this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "gtest/gtest.h"
3
4#include "builtins.h"
5#include "bytearray-builtins.h"
6#include "runtime.h"
7#include "test-utils.h"
8
9namespace py {
10namespace testing {
11
12using CodecsModuleTest = RuntimeFixture;
13
14TEST_F(CodecsModuleTest, DecodeASCIIWithWellFormedASCIIReturnsString) {
15 HandleScope scope(thread_);
16 byte encoded[] = {'h', 'e', 'l', 'l', 'o'};
17 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
18 Object errors(&scope, runtime_->newStrFromCStr("strict"));
19 Object index(&scope, runtime_->newInt(0));
20 Object strarray(&scope, runtime_->newStrArray());
21 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_decode), bytes,
22 errors, index, strarray));
23 ASSERT_TRUE(result_obj.isTuple());
24
25 Tuple result(&scope, *result_obj);
26 Str str(&scope, result.at(0));
27 EXPECT_EQ(str.length(), 5);
28 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
29 EXPECT_TRUE(str.equalsCStr("hello"));
30}
31
32TEST_F(CodecsModuleTest, DecodeASCIIWithIgnoreErrorHandlerReturnsStr) {
33 HandleScope scope(thread_);
34 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
35 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
36 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
37 Object index(&scope, runtime_->newInt(0));
38 Object strarray(&scope, runtime_->newStrArray());
39 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_decode), bytes,
40 errors, index, strarray));
41 ASSERT_TRUE(result_obj.isTuple());
42
43 Tuple result(&scope, *result_obj);
44 Str str(&scope, result.at(0));
45 EXPECT_EQ(str.length(), 5);
46 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
47 EXPECT_TRUE(str.equalsCStr("hello"));
48}
49
50TEST_F(CodecsModuleTest, DecodeASCIIWithReplaceErrorHandlerReturnsStr) {
51 HandleScope scope(thread_);
52 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
53 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
54 Object errors(&scope, runtime_->newStrFromCStr("replace"));
55 Object index(&scope, runtime_->newInt(0));
56 Object strarray(&scope, runtime_->newStrArray());
57 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_decode), bytes,
58 errors, index, strarray));
59 ASSERT_TRUE(result_obj.isTuple());
60
61 Tuple result(&scope, *result_obj);
62 Str str(&scope, result.at(0));
63 EXPECT_EQ(str.length(), 8);
64 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
65 word placeholder;
66 EXPECT_EQ(str.codePointAt(4, &placeholder), 0xfffd);
67}
68
69TEST_F(CodecsModuleTest,
70 DecodeASCIIWithSurroogateescapeErrorHandlerReturnsStr) {
71 HandleScope scope(thread_);
72 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
73 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
74 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
75 Object index(&scope, runtime_->newInt(0));
76 Object strarray(&scope, runtime_->newStrArray());
77 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_decode), bytes,
78 errors, index, strarray));
79 ASSERT_TRUE(result_obj.isTuple());
80
81 Tuple result(&scope, *result_obj);
82 Str str(&scope, result.at(0));
83 EXPECT_EQ(str.length(), 8);
84 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
85 word placeholder;
86 EXPECT_EQ(str.codePointAt(4, &placeholder), 0xdc80);
87}
88
89TEST_F(CodecsModuleTest, DecodeASCIIWithBytesSubclassReturnsStr) {
90 HandleScope scope(thread_);
91 ASSERT_FALSE(runFromCStr(runtime_, R"(
92class Foo(bytes): pass
93encoded = Foo(b"hello")
94)")
95 .isError());
96 Object bytes(&scope, mainModuleAt(runtime_, "encoded"));
97 Object errors(&scope, runtime_->newStrFromCStr("strict"));
98 Object index(&scope, runtime_->newInt(0));
99 Object strarray(&scope, runtime_->newStrArray());
100 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_decode), bytes,
101 errors, index, strarray));
102 ASSERT_TRUE(result_obj.isTuple());
103
104 Tuple result(&scope, *result_obj);
105 Str str(&scope, result.at(0));
106 EXPECT_EQ(str.length(), 5);
107 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
108 EXPECT_TRUE(str.equalsCStr("hello"));
109}
110
111TEST_F(CodecsModuleTest, DecodeUTF8WithWellFormedUTF8ReturnsString) {
112 HandleScope scope(thread_);
113 byte encoded[] = {'h', 0xC3, 0xA9, 0xF0, 0x9D, 0x87, 0xB0,
114 'l', 'l', 'o', 0xE2, 0xB3, 0x80};
115 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
116 Object errors(&scope, runtime_->newStrFromCStr("strict"));
117 Object index(&scope, runtime_->newInt(0));
118 Object strarray(&scope, runtime_->newStrArray());
119 Object is_final(&scope, Bool::trueObj());
120 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
121 errors, index, strarray, is_final));
122 ASSERT_TRUE(result_obj.isTuple());
123
124 Tuple result(&scope, *result_obj);
125 EXPECT_TRUE(isStrEqualsCStr(result.at(0),
126 "h\xC3\xA9\xF0\x9D\x87\xB0llo\xE2\xB3\x80"));
127 EXPECT_TRUE(isIntEqualsWord(result.at(1), 13));
128 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
129}
130
131TEST_F(CodecsModuleTest, DecodeUTF8WithIgnoreErrorHandlerReturnsStr) {
132 HandleScope scope(thread_);
133 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
134 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
135 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
136 Object index(&scope, runtime_->newInt(0));
137 Object strarray(&scope, runtime_->newStrArray());
138 Object is_final(&scope, Bool::trueObj());
139 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
140 errors, index, strarray, is_final));
141 ASSERT_TRUE(result_obj.isTuple());
142
143 Tuple result(&scope, *result_obj);
144 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
145 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
146 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
147}
148
149TEST_F(CodecsModuleTest, DecodeUTF8WithReplaceErrorHandlerReturnsStr) {
150 HandleScope scope(thread_);
151 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
152 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
153 Object errors(&scope, runtime_->newStrFromCStr("replace"));
154 Object index(&scope, runtime_->newInt(0));
155 Object strarray(&scope, runtime_->newStrArray());
156 Object is_final(&scope, Bool::trueObj());
157 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
158 errors, index, strarray, is_final));
159 ASSERT_TRUE(result_obj.isTuple());
160
161 Tuple result(&scope, *result_obj);
162 Str str(&scope, result.at(0));
163 EXPECT_EQ(str.length(), 8);
164 word placeholder;
165 EXPECT_EQ(str.codePointAt(4, &placeholder), 0xfffd);
166 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
167 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
168}
169
170TEST_F(CodecsModuleTest, DecodeUTF8WithSurroogateescapeErrorHandlerReturnsStr) {
171 HandleScope scope(thread_);
172 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
173 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
174 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
175 Object index(&scope, runtime_->newInt(0));
176 Object strarray(&scope, runtime_->newStrArray());
177 Object is_final(&scope, Bool::trueObj());
178 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
179 errors, index, strarray, is_final));
180 ASSERT_TRUE(result_obj.isTuple());
181
182 Tuple result(&scope, *result_obj);
183 Str str(&scope, result.at(0));
184 EXPECT_EQ(str.length(), 8);
185 word placeholder;
186 EXPECT_EQ(str.codePointAt(4, &placeholder), 0xdc80);
187 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
188 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
189}
190
191TEST_F(CodecsModuleTest, DecodeUTF8WithInvalidStartByteReturnsIndices) {
192 HandleScope scope(thread_);
193 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
194 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
195 Object errors(&scope, runtime_->newStrFromCStr("strict"));
196 Object index(&scope, runtime_->newInt(0));
197 Object strarray(&scope, runtime_->newStrArray());
198 Object is_final(&scope, Bool::trueObj());
199 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
200 errors, index, strarray, is_final));
201 ASSERT_TRUE(result_obj.isTuple());
202
203 Tuple result(&scope, *result_obj);
204 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
205 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
206 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "invalid start byte"));
207}
208
209TEST_F(CodecsModuleTest, DecodeUTF8StatefulWithInvalidStartByteReturnsIndices) {
210 HandleScope scope(thread_);
211 byte encoded[] = {'h', 'e', 'l', 'l', 0x80, 'o'};
212 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
213 Object errors(&scope, runtime_->newStrFromCStr("strict"));
214 Object index(&scope, runtime_->newInt(0));
215 Object strarray(&scope, runtime_->newStrArray());
216 Object is_final(&scope, Bool::falseObj());
217 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
218 errors, index, strarray, is_final));
219 ASSERT_TRUE(result_obj.isTuple());
220
221 Tuple result(&scope, *result_obj);
222 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
223 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
224 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "invalid start byte"));
225}
226
227TEST_F(CodecsModuleTest, DecodeUTF8WithUnexpectedEndReturnsIndices) {
228 HandleScope scope(thread_);
229 byte encoded[] = {'h', 'e', 'l', 'l', 0xC3};
230 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
231 Object errors(&scope, runtime_->newStrFromCStr("strict"));
232 Object index(&scope, runtime_->newInt(0));
233 Object strarray(&scope, runtime_->newStrArray());
234 Object is_final(&scope, Bool::trueObj());
235 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
236 errors, index, strarray, is_final));
237 ASSERT_TRUE(result_obj.isTuple());
238
239 Tuple result(&scope, *result_obj);
240 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
241 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
242 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "unexpected end of data"));
243}
244
245TEST_F(CodecsModuleTest, DecodeUTF8StatefulWithUnexpectedEndReturnsStr) {
246 HandleScope scope(thread_);
247 byte encoded[] = {'h', 'e', 'l', 'l', 0xC3};
248 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
249 Object errors(&scope, runtime_->newStrFromCStr("strict"));
250 Object index(&scope, runtime_->newInt(0));
251 Object strarray(&scope, runtime_->newStrArray());
252 Object is_final(&scope, Bool::falseObj());
253 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
254 errors, index, strarray, is_final));
255 ASSERT_TRUE(result_obj.isTuple());
256
257 Tuple result(&scope, *result_obj);
258 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hell"));
259 EXPECT_TRUE(isIntEqualsWord(result.at(1), 4));
260 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
261}
262
263TEST_F(CodecsModuleTest, DecodeUTF8WithInvalidFirstContReturnsIndices) {
264 HandleScope scope(thread_);
265 byte encoded[] = {'h', 'e', 'l', 'l', 0xE2, 0xC3, 'o'};
266 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
267 Object errors(&scope, runtime_->newStrFromCStr("strict"));
268 Object index(&scope, runtime_->newInt(0));
269 Object strarray(&scope, runtime_->newStrArray());
270 Object is_final(&scope, Bool::trueObj());
271 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
272 errors, index, strarray, is_final));
273 ASSERT_TRUE(result_obj.isTuple());
274
275 Tuple result(&scope, *result_obj);
276 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
277 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
278 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "invalid continuation byte"));
279}
280
281TEST_F(CodecsModuleTest, DecodeUTF8StatefulWithInvalidFirstContReturnsStr) {
282 HandleScope scope(thread_);
283 byte encoded[] = {'h', 'e', 'l', 'l', 0xE2, 0xC3, 'o'};
284 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
285 Object errors(&scope, runtime_->newStrFromCStr("strict"));
286 Object index(&scope, runtime_->newInt(0));
287 Object strarray(&scope, runtime_->newStrArray());
288 Object is_final(&scope, Bool::falseObj());
289 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
290 errors, index, strarray, is_final));
291 ASSERT_TRUE(result_obj.isTuple());
292
293 Tuple result(&scope, *result_obj);
294 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hell"));
295 EXPECT_TRUE(isIntEqualsWord(result.at(1), 4));
296 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
297}
298
299TEST_F(CodecsModuleTest, DecodeUTF8WithInvalidSecondContReturnsIndices) {
300 HandleScope scope(thread_);
301 byte encoded[] = {'h', 'e', 'l', 'l', 0xF0, 0x9D, 'o', 'o'};
302 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
303 Object errors(&scope, runtime_->newStrFromCStr("strict"));
304 Object index(&scope, runtime_->newInt(0));
305 Object strarray(&scope, runtime_->newStrArray());
306 Object is_final(&scope, Bool::trueObj());
307 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
308 errors, index, strarray, is_final));
309 ASSERT_TRUE(result_obj.isTuple());
310
311 Tuple result(&scope, *result_obj);
312 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
313 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
314 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "invalid continuation byte"));
315}
316
317TEST_F(CodecsModuleTest, DecodeUTF8StatefulWithInvalidSecondContReturnsStr) {
318 HandleScope scope(thread_);
319 byte encoded[] = {'h', 'e', 'l', 'l', 0xF0, 0x9D, 'o', 'o'};
320 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
321 Object errors(&scope, runtime_->newStrFromCStr("strict"));
322 Object index(&scope, runtime_->newInt(0));
323 Object strarray(&scope, runtime_->newStrArray());
324 Object is_final(&scope, Bool::falseObj());
325 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
326 errors, index, strarray, is_final));
327 ASSERT_TRUE(result_obj.isTuple());
328
329 Tuple result(&scope, *result_obj);
330 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hell"));
331 EXPECT_TRUE(isIntEqualsWord(result.at(1), 4));
332 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
333}
334
335TEST_F(CodecsModuleTest, DecodeUTF8WithInvalidThirdContReturnsIndices) {
336 HandleScope scope(thread_);
337 byte encoded[] = {'h', 'e', 'l', 'l', 0xF0, 0x9D, 0x87, 'o'};
338 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
339 Object errors(&scope, runtime_->newStrFromCStr("strict"));
340 Object index(&scope, runtime_->newInt(0));
341 Object strarray(&scope, runtime_->newStrArray());
342 Object is_final(&scope, Bool::trueObj());
343 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
344 errors, index, strarray, is_final));
345 ASSERT_TRUE(result_obj.isTuple());
346
347 Tuple result(&scope, *result_obj);
348 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
349 EXPECT_TRUE(isIntEqualsWord(result.at(1), 7));
350 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "invalid continuation byte"));
351}
352
353TEST_F(CodecsModuleTest, DecodeUTF8StatefulWithInvalidThirdContReturnsStr) {
354 HandleScope scope(thread_);
355 byte encoded[] = {'h', 'e', 'l', 'l', 0xF0, 0x9D, 0x87, 'o'};
356 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
357 Object errors(&scope, runtime_->newStrFromCStr("strict"));
358 Object index(&scope, runtime_->newInt(0));
359 Object strarray(&scope, runtime_->newStrArray());
360 Object is_final(&scope, Bool::falseObj());
361 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
362 errors, index, strarray, is_final));
363 ASSERT_TRUE(result_obj.isTuple());
364
365 Tuple result(&scope, *result_obj);
366 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hell"));
367 EXPECT_TRUE(isIntEqualsWord(result.at(1), 4));
368 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
369}
370
371TEST_F(CodecsModuleTest, DecodeUTF8WithBytesSubclassReturnsStr) {
372 HandleScope scope(thread_);
373 ASSERT_FALSE(runFromCStr(runtime_, R"(
374class Foo(bytes): pass
375encoded = Foo(b"hello")
376)")
377 .isError());
378 Object bytes(&scope, mainModuleAt(runtime_, "encoded"));
379 Object errors(&scope, runtime_->newStrFromCStr("strict"));
380 Object index(&scope, runtime_->newInt(0));
381 Object strarray(&scope, runtime_->newStrArray());
382 Object is_final(&scope, Bool::trueObj());
383 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_decode), bytes,
384 errors, index, strarray, is_final));
385 ASSERT_TRUE(result_obj.isTuple());
386
387 Tuple result(&scope, *result_obj);
388 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
389 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
390 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
391}
392
393TEST_F(CodecsModuleTest, DecodeEscapeWithWellFormedLatin1ReturnsString) {
394 HandleScope scope(thread_);
395 byte encoded[] = {'h', 'e', 'l', 'l', 0xE9, 'o'};
396 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
397 Object errors(&scope, runtime_->newStrFromCStr("strict"));
398 Object encoding(&scope, runtime_->newStrFromCStr(""));
399 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
400 errors, encoding));
401 ASSERT_TRUE(result_obj.isTuple());
402
403 Tuple result(&scope, *result_obj);
404 Object decoded(&scope, result.at(0));
405 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hell\xC3\xA9o"));
406 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
407 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
408}
409
410TEST_F(CodecsModuleTest, DecodeEscapeWithIgnoreAndTrailingSlashReturnsStr) {
411 HandleScope scope(thread_);
412 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\'};
413 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
414 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
415 Object encoding(&scope, runtime_->newStrFromCStr(""));
416 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
417 errors, encoding));
418 ASSERT_TRUE(result_obj.isStr());
419 EXPECT_TRUE(isStrEqualsCStr(*result_obj, "Trailing \\ in string"));
420}
421
422TEST_F(CodecsModuleTest, DecodeEscapeWithIgnoreAndTruncatedHexIterates) {
423 HandleScope scope(thread_);
424 byte encoded[] = {'h', 'e', 'l', 'l', '\\', 'x', '1', 'o'};
425 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
426 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
427 Object encoding(&scope, runtime_->newStrFromCStr(""));
428 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
429 errors, encoding));
430 ASSERT_TRUE(result_obj.isTuple());
431
432 Tuple result(&scope, *result_obj);
433 Object decoded(&scope, result.at(0));
434 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello"));
435 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
436 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
437}
438
439TEST_F(CodecsModuleTest, DecodeEscapeWithReplaceAndTruncatedHexIterates) {
440 HandleScope scope(thread_);
441 byte encoded[] = {'h', 'e', 'l', 'l', '\\', 'x', 'o'};
442 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
443 Object errors(&scope, runtime_->newStrFromCStr("replace"));
444 Object encoding(&scope, runtime_->newStrFromCStr(""));
445 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
446 errors, encoding));
447 ASSERT_TRUE(result_obj.isTuple());
448
449 Tuple result(&scope, *result_obj);
450 Object decoded(&scope, result.at(0));
451 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hell?o"));
452 EXPECT_TRUE(isIntEqualsWord(result.at(1), 7));
453 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
454}
455
456TEST_F(CodecsModuleTest, DecodeEscapeWithStrictAndTruncatedHexReturnsMessage) {
457 HandleScope scope(thread_);
458 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'x', '1'};
459 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
460 Object errors(&scope, runtime_->newStrFromCStr("strict"));
461 Object encoding(&scope, runtime_->newStrFromCStr(""));
462 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
463 errors, encoding));
464 ASSERT_TRUE(result_obj.isStr());
465 EXPECT_TRUE(isStrEqualsCStr(*result_obj, "invalid \\x escape at position 5"));
466}
467
468TEST_F(CodecsModuleTest,
469 DecodeEscapeWithUnknownHandlerAndTruncatedHexReturnsMessage) {
470 HandleScope scope(thread_);
471 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'x', '1'};
472 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
473 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
474 Object encoding(&scope, runtime_->newStrFromCStr(""));
475 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
476 errors, encoding));
477 ASSERT_TRUE(result_obj.isStr());
478 EXPECT_TRUE(isStrEqualsCStr(
479 *result_obj,
480 "decoding error; unknown error handling code: surrogateescape"));
481}
482
483TEST_F(CodecsModuleTest, DecodeEscapeEscapesSingleOctals) {
484 HandleScope scope(thread_);
485 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '0', 'w'};
486 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
487 Object errors(&scope, runtime_->newStrFromCStr("strict"));
488 Object encoding(&scope, runtime_->newStrFromCStr(""));
489 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
490 errors, encoding));
491
492 Tuple result(&scope, *result_obj);
493 Object decoded(&scope, result.at(0));
494 byte escaped[] = {'h', 'e', 'l', 'l', 'o', 0x00, 'w'};
495 EXPECT_TRUE(isBytesEqualsBytes(decoded, View<byte>{escaped}));
496 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
497 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
498}
499
500TEST_F(CodecsModuleTest, DecodeEscapeEscapesMidStringDoubleOctals) {
501 HandleScope scope(thread_);
502 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '4', '0', 'w'};
503 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
504 Object errors(&scope, runtime_->newStrFromCStr("strict"));
505 Object encoding(&scope, runtime_->newStrFromCStr(""));
506 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
507 errors, encoding));
508
509 Tuple result(&scope, *result_obj);
510 Object decoded(&scope, result.at(0));
511 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello w"));
512 EXPECT_TRUE(isIntEqualsWord(result.at(1), 9));
513 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
514}
515
516TEST_F(CodecsModuleTest, DecodeEscapeEscapesEndStringDoubleOctals) {
517 HandleScope scope(thread_);
518 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '4', '0'};
519 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
520 Object errors(&scope, runtime_->newStrFromCStr("strict"));
521 Object encoding(&scope, runtime_->newStrFromCStr(""));
522 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
523 errors, encoding));
524
525 Tuple result(&scope, *result_obj);
526 Object decoded(&scope, result.at(0));
527 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello "));
528 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
529 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
530}
531
532TEST_F(CodecsModuleTest, DecodeEscapeEscapesTripleOctals) {
533 HandleScope scope(thread_);
534 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '7', '7', '7', 'w'};
535 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
536 Object errors(&scope, runtime_->newStrFromCStr("strict"));
537 Object encoding(&scope, runtime_->newStrFromCStr(""));
538 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
539 errors, encoding));
540
541 Tuple result(&scope, *result_obj);
542 Object decoded(&scope, result.at(0));
543 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello\xFFw"));
544 EXPECT_TRUE(isIntEqualsWord(result.at(1), 10));
545 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
546}
547
548TEST_F(CodecsModuleTest, DecodeEscapeEscapesHex) {
549 HandleScope scope(thread_);
550 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'x', 'e', 'E', 'w'};
551 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
552 Object errors(&scope, runtime_->newStrFromCStr("strict"));
553 Object encoding(&scope, runtime_->newStrFromCStr(""));
554 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
555 errors, encoding));
556
557 Tuple result(&scope, *result_obj);
558 Object decoded(&scope, result.at(0));
559 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello\xEEw"));
560 EXPECT_TRUE(isIntEqualsWord(result.at(1), 10));
561 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
562}
563
564TEST_F(CodecsModuleTest, DecodeEscapeSetsFirstInvalidEscape) {
565 HandleScope scope(thread_);
566 byte encoded[] = {'h', 'e', 'l', 'l', '\\', 'y', 'o'};
567 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
568 Object errors(&scope, runtime_->newStrFromCStr("strict"));
569 Object encoding(&scope, runtime_->newStrFromCStr(""));
570 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
571 errors, encoding));
572 ASSERT_TRUE(result_obj.isTuple());
573
574 Tuple result(&scope, *result_obj);
575 Object decoded(&scope, result.at(0));
576 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hell\\yo"));
577 EXPECT_TRUE(isIntEqualsWord(result.at(1), 7));
578 EXPECT_TRUE(isIntEqualsWord(result.at(2), 5));
579}
580
581TEST_F(CodecsModuleTest, DecodeEscapeWithBytesSubclassReturnsStr) {
582 HandleScope scope(thread_);
583 ASSERT_FALSE(runFromCStr(runtime_, R"(
584class Foo(bytes): pass
585encoded = Foo(b"hello")
586)")
587 .isError());
588 Object bytes(&scope, mainModuleAt(runtime_, "encoded"));
589 Object errors(&scope, runtime_->newStrFromCStr("strict"));
590 Object encoding(&scope, runtime_->newStrFromCStr(""));
591 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _escape_decode), bytes,
592 errors, encoding));
593 ASSERT_TRUE(result_obj.isTuple());
594
595 Tuple result(&scope, *result_obj);
596 Object decoded(&scope, result.at(0));
597 EXPECT_TRUE(isBytesEqualsCStr(decoded, "hello"));
598 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
599 EXPECT_TRUE(isIntEqualsWord(result.at(2), -1));
600}
601
602TEST_F(CodecsModuleTest, DecodeUnicodeEscapeWithWellFormedLatin1ReturnsString) {
603 HandleScope scope(thread_);
604 byte encoded[] = {'h', 'e', 'l', 'l', 0xE9, 'o'};
605 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
606 Object errors(&scope, runtime_->newStrFromCStr("strict"));
607 Object index(&scope, runtime_->newInt(0));
608 Object strarray(&scope, runtime_->newStrArray());
609 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
610 bytes, errors, index, strarray));
611 ASSERT_TRUE(result_obj.isTuple());
612
613 Tuple result(&scope, *result_obj);
614 Str str(&scope, result.at(0));
615 EXPECT_EQ(str.length(), 7);
616 EXPECT_TRUE(str.equalsCStr("hell\xC3\xA9o"));
617 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
618 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
619 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
620}
621
622TEST_F(CodecsModuleTest, DecodeUnicodeEscapeWithIgnoreErrorHandlerReturnsStr) {
623 HandleScope scope(thread_);
624 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\'};
625 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
626 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
627 Object index(&scope, runtime_->newInt(0));
628 Object strarray(&scope, runtime_->newStrArray());
629 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
630 bytes, errors, index, strarray));
631 ASSERT_TRUE(result_obj.isTuple());
632
633 Tuple result(&scope, *result_obj);
634 Str str(&scope, result.at(0));
635 EXPECT_EQ(str.length(), 5);
636 EXPECT_TRUE(str.equalsCStr("hello"));
637 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
638 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
639 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
640}
641
642TEST_F(CodecsModuleTest, DecodeUnicodeEscapeWithReplaceErrorHandlerReturnsStr) {
643 HandleScope scope(thread_);
644 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\'};
645 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
646 Object errors(&scope, runtime_->newStrFromCStr("replace"));
647 Object index(&scope, runtime_->newInt(0));
648 Object strarray(&scope, runtime_->newStrArray());
649 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
650 bytes, errors, index, strarray));
651 ASSERT_TRUE(result_obj.isTuple());
652
653 Tuple result(&scope, *result_obj);
654 Str str(&scope, result.at(0));
655 EXPECT_EQ(str.length(), 8);
656 word placeholder;
657 EXPECT_EQ(str.codePointAt(5, &placeholder), 0xfffd);
658 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
659 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
660 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
661}
662
663TEST_F(CodecsModuleTest,
664 DecodeUnicodeEscapeReturnsMessageWhenEscapeAtEndOfString) {
665 HandleScope scope(thread_);
666 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\'};
667 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
668 Object errors(&scope, runtime_->newStrFromCStr("not-a-handler"));
669 Object index(&scope, runtime_->newInt(0));
670 Object strarray(&scope, runtime_->newStrArray());
671 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
672 bytes, errors, index, strarray));
673 ASSERT_TRUE(result_obj.isTuple());
674
675 Tuple result(&scope, *result_obj);
676 EXPECT_TRUE(isIntEqualsWord(result.at(0), 5));
677 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
678 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "\\ at end of string"));
679 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
680}
681
682TEST_F(CodecsModuleTest, DecodeUnicodeEscapeReturnsMessageOnTruncatedHex) {
683 HandleScope scope(thread_);
684 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'x', '1'};
685 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
686 Object errors(&scope, runtime_->newStrFromCStr("not-a-handler"));
687 Object index(&scope, runtime_->newInt(0));
688 Object strarray(&scope, runtime_->newStrArray());
689 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
690 bytes, errors, index, strarray));
691 ASSERT_TRUE(result_obj.isTuple());
692
693 Tuple result(&scope, *result_obj);
694 EXPECT_TRUE(isIntEqualsWord(result.at(0), 5));
695 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
696 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "truncated \\xXX escape"));
697 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
698}
699
700TEST_F(CodecsModuleTest,
701 DecodeUnicodeEscapeReturnsMessageOnTruncatedSmallUnicode) {
702 HandleScope scope(thread_);
703 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'u', '0'};
704 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
705 Object errors(&scope, runtime_->newStrFromCStr("not-a-handler"));
706 Object index(&scope, runtime_->newInt(0));
707 Object strarray(&scope, runtime_->newStrArray());
708 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
709 bytes, errors, index, strarray));
710 ASSERT_TRUE(result_obj.isTuple());
711
712 Tuple result(&scope, *result_obj);
713 EXPECT_TRUE(isIntEqualsWord(result.at(0), 5));
714 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
715 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "truncated \\uXXXX escape"));
716 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
717}
718
719TEST_F(CodecsModuleTest,
720 DecodeUnicodeEscapeReturnsMessageOnTruncatedLargeUnicode) {
721 HandleScope scope(thread_);
722 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'U', '0'};
723 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
724 Object errors(&scope, runtime_->newStrFromCStr("not-a-handler"));
725 Object index(&scope, runtime_->newInt(0));
726 Object strarray(&scope, runtime_->newStrArray());
727 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
728 bytes, errors, index, strarray));
729 ASSERT_TRUE(result_obj.isTuple());
730
731 Tuple result(&scope, *result_obj);
732 EXPECT_TRUE(isIntEqualsWord(result.at(0), 5));
733 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
734 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "truncated \\uXXXXXXXX escape"));
735 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
736}
737
738TEST_F(CodecsModuleTest, DecodeUnicodeEscapeReturnsMessageOnOversizedUnicode) {
739 HandleScope scope(thread_);
740 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', 'U', '0',
741 '1', '1', '0', '0', '0', '0', '0'};
742 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
743 Object errors(&scope, runtime_->newStrFromCStr("not-a-handler"));
744 Object index(&scope, runtime_->newInt(0));
745 Object strarray(&scope, runtime_->newStrArray());
746 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
747 bytes, errors, index, strarray));
748 ASSERT_TRUE(result_obj.isTuple());
749
750 Tuple result(&scope, *result_obj);
751 EXPECT_TRUE(isIntEqualsWord(result.at(0), 5));
752 EXPECT_TRUE(isIntEqualsWord(result.at(1), 15));
753 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "illegal Unicode character"));
754 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
755}
756
757TEST_F(CodecsModuleTest, DecodeUnicodeEscapeWithTruncatedHexProperlyIterates) {
758 HandleScope scope(thread_);
759 byte encoded[] = {'h', 'e', 'l', 'l', '\\', 'U', '1',
760 '1', '0', '0', '0', '0', 'o'};
761 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
762 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
763 Object index(&scope, runtime_->newInt(0));
764 Object strarray(&scope, runtime_->newStrArray());
765 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
766 bytes, errors, index, strarray));
767 ASSERT_TRUE(result_obj.isTuple());
768
769 Tuple result(&scope, *result_obj);
770 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
771 EXPECT_TRUE(isIntEqualsWord(result.at(1), 13));
772 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
773 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
774}
775
776TEST_F(CodecsModuleTest, DecodeUnicodeEscapeProperlyEscapesSingleOctals) {
777 HandleScope scope(thread_);
778 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '0', 'w'};
779 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
780 Object errors(&scope, runtime_->newStrFromCStr("strict"));
781 Object index(&scope, runtime_->newInt(0));
782 Object strarray(&scope, runtime_->newStrArray());
783 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
784 bytes, errors, index, strarray));
785
786 Tuple result(&scope, *result_obj);
787 byte escaped[] = {'h', 'e', 'l', 'l', 'o', 0x00, 'w'};
788 Str expected(&scope, runtime_->newStrWithAll(View<byte>{escaped}));
789 Object decoded(&scope, result.at(0));
790 EXPECT_TRUE(isStrEquals(decoded, expected));
791 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
792 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
793 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
794}
795
796TEST_F(CodecsModuleTest,
797 DecodeUnicodeEscapeProperlyEscapesMidStringDoubleOctals) {
798 HandleScope scope(thread_);
799 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '4', '0', 'w'};
800 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
801 Object errors(&scope, runtime_->newStrFromCStr("strict"));
802 Object index(&scope, runtime_->newInt(0));
803 Object strarray(&scope, runtime_->newStrArray());
804 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
805 bytes, errors, index, strarray));
806
807 Tuple result(&scope, *result_obj);
808 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello w"));
809 EXPECT_TRUE(isIntEqualsWord(result.at(1), 9));
810 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
811 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
812}
813
814TEST_F(CodecsModuleTest,
815 DecodeUnicodeEscapeProperlyEscapesEndStringDoubleOctals) {
816 HandleScope scope(thread_);
817 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '4', '0'};
818 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
819 Object errors(&scope, runtime_->newStrFromCStr("strict"));
820 Object index(&scope, runtime_->newInt(0));
821 Object strarray(&scope, runtime_->newStrArray());
822 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
823 bytes, errors, index, strarray));
824
825 Tuple result(&scope, *result_obj);
826 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello "));
827 EXPECT_TRUE(isIntEqualsWord(result.at(1), 8));
828 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
829 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
830}
831
832TEST_F(CodecsModuleTest, DecodeUnicodeEscapeProperlyEscapesTripleOctals) {
833 HandleScope scope(thread_);
834 byte encoded[] = {'h', 'e', 'l', 'l', 'o', '\\', '7', '7', '7', 'w'};
835 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
836 Object errors(&scope, runtime_->newStrFromCStr("strict"));
837 Object index(&scope, runtime_->newInt(0));
838 Object strarray(&scope, runtime_->newStrArray());
839 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
840 bytes, errors, index, strarray));
841
842 Tuple result(&scope, *result_obj);
843 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello\xC7\xBFw"));
844 EXPECT_TRUE(isIntEqualsWord(result.at(1), 10));
845 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
846 EXPECT_TRUE(isIntEqualsWord(result.at(3), -1));
847}
848
849TEST_F(CodecsModuleTest, DecodeUnicodeEscapeSetsFirstInvalidEscape) {
850 HandleScope scope(thread_);
851 byte encoded[] = {'h', 'e', 'l', 'l', '\\', 'y', 'o'};
852 Object bytes(&scope, runtime_->newBytesWithAll(encoded));
853 Object errors(&scope, runtime_->newStrFromCStr("strict"));
854 Object index(&scope, runtime_->newInt(0));
855 Object strarray(&scope, runtime_->newStrArray());
856 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
857 bytes, errors, index, strarray));
858 ASSERT_TRUE(result_obj.isTuple());
859
860 Tuple result(&scope, *result_obj);
861 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hell\\yo"));
862 EXPECT_TRUE(isIntEqualsWord(result.at(1), 7));
863 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
864 EXPECT_TRUE(isIntEqualsWord(result.at(3), 5));
865}
866
867TEST_F(CodecsModuleTest, DecodeUnicodeEscapeWithBytesSubclassReturnsStr) {
868 HandleScope scope(thread_);
869 ASSERT_FALSE(runFromCStr(runtime_, R"(
870class Foo(bytes): pass
871encoded = Foo(b"hello")
872)")
873 .isError());
874 Object bytes(&scope, mainModuleAt(runtime_, "encoded"));
875 Object errors(&scope, runtime_->newStrFromCStr("strict"));
876 Object index(&scope, runtime_->newInt(0));
877 Object strarray(&scope, runtime_->newStrArray());
878 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _unicode_escape_decode),
879 bytes, errors, index, strarray));
880 ASSERT_TRUE(result_obj.isTuple());
881
882 Tuple result(&scope, *result_obj);
883 Str str(&scope, result.at(0));
884 EXPECT_EQ(str.length(), 5);
885 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
886 EXPECT_TRUE(str.equalsCStr("hello"));
887}
888
889TEST_F(CodecsModuleTest, EncodeASCIIWithWellFormedASCIIReturnsString) {
890 HandleScope scope(thread_);
891 Object str(&scope, runtime_->newStrFromCStr("hello"));
892 Object errors(&scope, runtime_->newStrFromCStr("strict"));
893 Object index(&scope, runtime_->newInt(0));
894 Object bytearray(&scope, runtime_->newBytearray());
895 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_encode), str,
896 errors, index, bytearray));
897 ASSERT_TRUE(result_obj.isTuple());
898
899 Tuple result(&scope, *result_obj);
900 Bytes bytes(&scope, result.at(0));
901 EXPECT_EQ(bytes.length(), 5);
902 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
903 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hello"));
904}
905
906TEST_F(CodecsModuleTest, EncodeASCIIWithIgnoreErrorHandlerReturnsString) {
907 HandleScope scope(thread_);
908 Object str(&scope, runtime_->newStrFromCStr("hell\uac80o"));
909 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
910 Object index(&scope, runtime_->newInt(0));
911 Object bytearray(&scope, runtime_->newBytearray());
912 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_encode), str,
913 errors, index, bytearray));
914 ASSERT_TRUE(result_obj.isTuple());
915
916 Tuple result(&scope, *result_obj);
917 Bytes bytes(&scope, result.at(0));
918 EXPECT_EQ(bytes.length(), 5);
919 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
920 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hello"));
921}
922
923TEST_F(CodecsModuleTest, EncodeASCIIWithReplaceErrorHandlerReturnsString) {
924 HandleScope scope(thread_);
925 Object str(&scope, runtime_->newStrFromCStr("hell\u0080o"));
926 Object errors(&scope, runtime_->newStrFromCStr("replace"));
927 Object index(&scope, runtime_->newInt(0));
928 Object bytearray(&scope, runtime_->newBytearray());
929 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_encode), str,
930 errors, index, bytearray));
931 ASSERT_TRUE(result_obj.isTuple());
932
933 Tuple result(&scope, *result_obj);
934 Bytes bytes(&scope, result.at(0));
935 EXPECT_EQ(bytes.length(), 6);
936 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
937 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell?o"));
938}
939
940TEST_F(CodecsModuleTest,
941 EncodeASCIIWithSurrogateescapeErrorHandlerReturnsString) {
942 HandleScope scope(thread_);
943 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80o"));
944 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
945 Object index(&scope, runtime_->newInt(0));
946 Object bytearray(&scope, runtime_->newBytearray());
947 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _ascii_encode), str,
948 errors, index, bytearray));
949 ASSERT_TRUE(result_obj.isTuple());
950
951 Tuple result(&scope, *result_obj);
952 Bytes bytes(&scope, result.at(0));
953 EXPECT_EQ(bytes.length(), 6);
954 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
955 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell\x80o"));
956}
957
958TEST_F(CodecsModuleTest, EncodeLatin1WithWellFormedLatin1ReturnsString) {
959 HandleScope scope(thread_);
960 Object str(&scope, runtime_->newStrFromCStr("hell\u00e5"));
961 Object errors(&scope, runtime_->newStrFromCStr("strict"));
962 Object index(&scope, runtime_->newInt(0));
963 Object bytearray(&scope, runtime_->newBytearray());
964 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _latin_1_encode), str,
965 errors, index, bytearray));
966 ASSERT_TRUE(result_obj.isTuple());
967
968 Tuple result(&scope, *result_obj);
969 Bytes bytes(&scope, result.at(0));
970 EXPECT_EQ(bytes.length(), 5);
971 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
972 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell\xe5"));
973}
974
975TEST_F(CodecsModuleTest, EncodeLatin1WithIgnoreErrorHandlerReturnsString) {
976 HandleScope scope(thread_);
977 Object str(&scope, runtime_->newStrFromCStr("hell\u1c80o"));
978 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
979 Object index(&scope, runtime_->newInt(0));
980 Object bytearray(&scope, runtime_->newBytearray());
981 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _latin_1_encode), str,
982 errors, index, bytearray));
983 ASSERT_TRUE(result_obj.isTuple());
984
985 Tuple result(&scope, *result_obj);
986 Bytes bytes(&scope, result.at(0));
987 EXPECT_EQ(bytes.length(), 5);
988 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
989 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hello"));
990}
991
992TEST_F(CodecsModuleTest, EncodeLatin1WithReplaceErrorHandlerReturnsString) {
993 HandleScope scope(thread_);
994 Object str(&scope, runtime_->newStrFromCStr("hell\u0180o"));
995 Object errors(&scope, runtime_->newStrFromCStr("replace"));
996 Object index(&scope, runtime_->newInt(0));
997 Object bytearray(&scope, runtime_->newBytearray());
998 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _latin_1_encode), str,
999 errors, index, bytearray));
1000 ASSERT_TRUE(result_obj.isTuple());
1001
1002 Tuple result(&scope, *result_obj);
1003 Bytes bytes(&scope, result.at(0));
1004 EXPECT_EQ(bytes.length(), 6);
1005 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1006 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell?o"));
1007}
1008
1009TEST_F(CodecsModuleTest,
1010 EncodeLatin1WithSurrogateescapeErrorHandlerReturnsString) {
1011 HandleScope scope(thread_);
1012 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80o"));
1013 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
1014 Object index(&scope, runtime_->newInt(0));
1015 Object bytearray(&scope, runtime_->newBytearray());
1016 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _latin_1_encode), str,
1017 errors, index, bytearray));
1018 ASSERT_TRUE(result_obj.isTuple());
1019
1020 Tuple result(&scope, *result_obj);
1021 Bytes bytes(&scope, result.at(0));
1022 EXPECT_EQ(bytes.length(), 6);
1023 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1024 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell\x80o"));
1025}
1026
1027TEST_F(CodecsModuleTest, EncodeUTF8WithWellFormedASCIIReturnsString) {
1028 HandleScope scope(thread_);
1029 Object str(&scope, runtime_->newStrFromCStr("hello"));
1030 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1031 Object index(&scope, runtime_->newInt(0));
1032 Object bytearray(&scope, runtime_->newBytearray());
1033 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_encode), str,
1034 errors, index, bytearray));
1035 ASSERT_TRUE(result_obj.isTuple());
1036
1037 Tuple result(&scope, *result_obj);
1038 Bytes bytes(&scope, result.at(0));
1039 EXPECT_EQ(bytes.length(), 5);
1040 EXPECT_TRUE(isIntEqualsWord(result.at(1), 5));
1041 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hello"));
1042}
1043
1044TEST_F(CodecsModuleTest, EncodeUTF8WithIgnoreErrorHandlerReturnsStr) {
1045 HandleScope scope(thread_);
1046 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80o"));
1047 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
1048 Object index(&scope, runtime_->newInt(0));
1049 Object bytearray(&scope, runtime_->newBytearray());
1050 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_encode), str,
1051 errors, index, bytearray));
1052 ASSERT_TRUE(result_obj.isTuple());
1053
1054 Tuple result(&scope, *result_obj);
1055 Bytes bytes(&scope, result.at(0));
1056 EXPECT_EQ(bytes.length(), 5);
1057 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1058 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hello"));
1059}
1060
1061TEST_F(CodecsModuleTest, EncodeUTF8WithReplaceErrorHandlerReturnsStr) {
1062 HandleScope scope(thread_);
1063 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80o"));
1064 Object errors(&scope, runtime_->newStrFromCStr("replace"));
1065 Object index(&scope, runtime_->newInt(0));
1066 Object bytearray(&scope, runtime_->newBytearray());
1067 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_encode), str,
1068 errors, index, bytearray));
1069 ASSERT_TRUE(result_obj.isTuple());
1070
1071 Tuple result(&scope, *result_obj);
1072 Bytes bytes(&scope, result.at(0));
1073 EXPECT_EQ(bytes.length(), 6);
1074 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1075 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell?o"));
1076}
1077
1078TEST_F(CodecsModuleTest, EncodeUTF8WithSurroogateescapeErrorHandlerReturnsStr) {
1079 HandleScope scope(thread_);
1080 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80o"));
1081 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
1082 Object index(&scope, runtime_->newInt(0));
1083 Object bytearray(&scope, runtime_->newBytearray());
1084 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_encode), str,
1085 errors, index, bytearray));
1086 ASSERT_TRUE(result_obj.isTuple());
1087
1088 Tuple result(&scope, *result_obj);
1089 Bytes bytes(&scope, result.at(0));
1090 EXPECT_EQ(bytes.length(), 6);
1091 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1092 EXPECT_TRUE(isBytesEqualsCStr(bytes, "hell\x80o"));
1093}
1094
1095TEST_F(CodecsModuleTest,
1096 EncodeUTF8WithUnknownErrorHandlerReturnsSurrogateRange) {
1097 HandleScope scope(thread_);
1098 Object str(&scope, runtime_->newStrFromCStr("hell\xed\xb2\x80\xed\xb2\x80o"));
1099 Object errors(&scope, runtime_->newStrFromCStr("unknown"));
1100 Object index(&scope, runtime_->newInt(0));
1101 Object bytearray(&scope, runtime_->newBytearray());
1102 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_8_encode), str,
1103 errors, index, bytearray));
1104 ASSERT_TRUE(result_obj.isTuple());
1105
1106 Tuple result(&scope, *result_obj);
1107 EXPECT_TRUE(isIntEqualsWord(result.at(0), 4));
1108 EXPECT_TRUE(isIntEqualsWord(result.at(1), 6));
1109}
1110
1111TEST_F(CodecsModuleTest, EncodeUTF16WithWellFormedASCIIReturnsBytes) {
1112 HandleScope scope(thread_);
1113 Object str(&scope, runtime_->newStrFromCStr("hi"));
1114 Object errors(&scope, runtime_->newStrFromCStr("unknown"));
1115 Object index(&scope, runtime_->newInt(0));
1116 Object bytearray(&scope, runtime_->newBytearray());
1117 Object byteorder(&scope, runtime_->newInt(0));
1118 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1119 errors, index, bytearray, byteorder));
1120 ASSERT_TRUE(result_obj.isTuple());
1121
1122 Tuple result(&scope, *result_obj);
1123 Bytes bytes(&scope, result.at(0));
1124 EXPECT_EQ(bytes.length(), 4);
1125 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2));
1126 byte expected[] = {'h', 0x00, 'i', 0x00};
1127 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1128}
1129
1130TEST_F(CodecsModuleTest, EncodeUTF16WithLargeIntByteorderRaisesOverflowError) {
1131 HandleScope scope(thread_);
1132 Object str(&scope, runtime_->newStrFromCStr("hi"));
1133 Object errors(&scope, runtime_->newStrFromCStr("unknown"));
1134 Object index(&scope, runtime_->newInt(0));
1135 Object bytearray(&scope, runtime_->newBytearray());
1136 Object byteorder(&scope, runtime_->newInt(kMaxWord));
1137 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1138 errors, index, bytearray, byteorder),
1139 LayoutId::kOverflowError,
1140 "Python int too large to convert to C int"));
1141}
1142
1143TEST_F(CodecsModuleTest, EncodeUTF16WithIgnoreErrorHandlerReturnsStr) {
1144 HandleScope scope(thread_);
1145 Object str(&scope, runtime_->newStrFromCStr("h\xed\xb2\x80i"));
1146 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
1147 Object index(&scope, runtime_->newInt(0));
1148 Object bytearray(&scope, runtime_->newBytearray());
1149 Object byteorder(&scope, runtime_->newInt(0));
1150 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1151 errors, index, bytearray, byteorder));
1152 ASSERT_TRUE(result_obj.isTuple());
1153
1154 Tuple result(&scope, *result_obj);
1155 Bytes bytes(&scope, result.at(0));
1156 EXPECT_EQ(bytes.length(), 4);
1157 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1158 byte expected[] = {'h', 0x00, 'i', 0x00};
1159 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1160}
1161
1162TEST_F(CodecsModuleTest, EncodeUTF16WithReplaceErrorHandlerReturnsStr) {
1163 HandleScope scope(thread_);
1164 Object str(&scope, runtime_->newStrFromCStr("hi\xed\xb2\x80"));
1165 Object errors(&scope, runtime_->newStrFromCStr("replace"));
1166 Object index(&scope, runtime_->newInt(0));
1167 Object bytearray(&scope, runtime_->newBytearray());
1168 Object byteorder(&scope, runtime_->newInt(0));
1169 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1170 errors, index, bytearray, byteorder));
1171 ASSERT_TRUE(result_obj.isTuple());
1172
1173 Tuple result(&scope, *result_obj);
1174 Bytes bytes(&scope, result.at(0));
1175 EXPECT_EQ(bytes.length(), 6);
1176 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1177 byte expected[] = {'h', 0x00, 'i', 0x00, '?', 0x00};
1178 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1179}
1180
1181TEST_F(CodecsModuleTest,
1182 EncodeUTF16WithSurroogateescapeErrorHandlerReturnsStr) {
1183 HandleScope scope(thread_);
1184 Object str(&scope, runtime_->newStrFromCStr("h\xed\xb2\x80i"));
1185 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
1186 Object index(&scope, runtime_->newInt(0));
1187 Object bytearray(&scope, runtime_->newBytearray());
1188 Object byteorder(&scope, runtime_->newInt(0));
1189 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1190 errors, index, bytearray, byteorder));
1191 ASSERT_TRUE(result_obj.isTuple());
1192
1193 Tuple result(&scope, *result_obj);
1194 Bytes bytes(&scope, result.at(0));
1195 EXPECT_EQ(bytes.length(), 6);
1196 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1197 byte expected[] = {'h', 0x00, 0x80, 0x00, 'i', 0x00};
1198 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1199}
1200
1201TEST_F(CodecsModuleTest, EncodeUTF16WithSupplementaryStringReturnsUTF16Bytes) {
1202 HandleScope scope(thread_);
1203 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1204 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1205 Object index(&scope, runtime_->newInt(0));
1206 Object bytearray(&scope, runtime_->newBytearray());
1207 Object byteorder(&scope, runtime_->newInt(0));
1208 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1209 errors, index, bytearray, byteorder));
1210 ASSERT_TRUE(result_obj.isTuple());
1211
1212 Tuple result(&scope, *result_obj);
1213 Bytes bytes(&scope, result.at(0));
1214 EXPECT_EQ(bytes.length(), 8);
1215 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1216 byte expected[] = {'h', 0x00, '4', 0xd8, 0xf0, 0xdd, 'i', 0x00};
1217 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1218}
1219
1220TEST_F(CodecsModuleTest,
1221 EncodeUTF16LeWithSupplementaryStringReturnsUTF16Bytes) {
1222 HandleScope scope(thread_);
1223 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1224 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1225 Object index(&scope, runtime_->newInt(0));
1226 Object bytearray(&scope, runtime_->newBytearray());
1227 Object byteorder(&scope, runtime_->newInt(-1));
1228 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1229 errors, index, bytearray, byteorder));
1230 ASSERT_TRUE(result_obj.isTuple());
1231
1232 Tuple result(&scope, *result_obj);
1233 Bytes bytes(&scope, result.at(0));
1234 EXPECT_EQ(bytes.length(), 8);
1235 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1236 byte expected[] = {'h', 0x00, '4', 0xd8, 0xf0, 0xdd, 'i', 0x00};
1237 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1238}
1239
1240TEST_F(CodecsModuleTest,
1241 EncodeUTF16BeWithSupplementaryStringReturnsUTF16Bytes) {
1242 HandleScope scope(thread_);
1243 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1244 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1245 Object index(&scope, runtime_->newInt(0));
1246 Object bytearray(&scope, runtime_->newBytearray());
1247 Object byteorder(&scope, runtime_->newInt(1));
1248 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_16_encode), str,
1249 errors, index, bytearray, byteorder));
1250 ASSERT_TRUE(result_obj.isTuple());
1251
1252 Tuple result(&scope, *result_obj);
1253 Bytes bytes(&scope, result.at(0));
1254 EXPECT_EQ(bytes.length(), 8);
1255 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1256 byte expected[] = {0x00, 'h', 0xd8, '4', 0xdd, 0xf0, 0x00, 'i'};
1257 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1258}
1259
1260TEST_F(CodecsModuleTest, EncodeUTF32WithWellFormedASCIIReturnsBytes) {
1261 HandleScope scope(thread_);
1262 Object str(&scope, runtime_->newStrFromCStr("hi"));
1263 Object errors(&scope, runtime_->newStrFromCStr("unknown"));
1264 Object index(&scope, runtime_->newInt(0));
1265 Object bytearray(&scope, runtime_->newBytearray());
1266 Object byteorder(&scope, runtime_->newInt(0));
1267 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1268 errors, index, bytearray, byteorder));
1269 ASSERT_TRUE(result_obj.isTuple());
1270
1271 Tuple result(&scope, *result_obj);
1272 Bytes bytes(&scope, result.at(0));
1273 EXPECT_EQ(bytes.length(), 8);
1274 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2));
1275 byte expected[] = {'h', 0x00, 0x00, 0x00, 'i', 0x00, 0x00, 0x00};
1276 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1277}
1278
1279TEST_F(CodecsModuleTest, EncodeUTF32WithLargeIntByteorderRaisesOverflowError) {
1280 HandleScope scope(thread_);
1281 Object str(&scope, runtime_->newStrFromCStr("hi"));
1282 Object errors(&scope, runtime_->newStrFromCStr("unknown"));
1283 Object index(&scope, runtime_->newInt(0));
1284 Object bytearray(&scope, runtime_->newBytearray());
1285 Object byteorder(&scope, runtime_->newInt(kMaxWord));
1286 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1287 errors, index, bytearray, byteorder),
1288 LayoutId::kOverflowError,
1289 "Python int too large to convert to C int"));
1290}
1291
1292TEST_F(CodecsModuleTest, EncodeUTF32WithIgnoreErrorHandlerReturnsStr) {
1293 HandleScope scope(thread_);
1294 Object str(&scope, runtime_->newStrFromCStr("h\xed\xb2\x80i"));
1295 Object errors(&scope, runtime_->newStrFromCStr("ignore"));
1296 Object index(&scope, runtime_->newInt(0));
1297 Object bytearray(&scope, runtime_->newBytearray());
1298 Object byteorder(&scope, runtime_->newInt(0));
1299 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1300 errors, index, bytearray, byteorder));
1301 ASSERT_TRUE(result_obj.isTuple());
1302
1303 Tuple result(&scope, *result_obj);
1304 Bytes bytes(&scope, result.at(0));
1305 EXPECT_EQ(bytes.length(), 8);
1306 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1307 byte expected[] = {'h', 0x00, 0x00, 0x00, 'i', 0x00, 0x00, 0x00};
1308 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1309}
1310
1311TEST_F(CodecsModuleTest, EncodeUTF32WithReplaceErrorHandlerReturnsStr) {
1312 HandleScope scope(thread_);
1313 Object str(&scope, runtime_->newStrFromCStr("hi\xed\xb2\x80"));
1314 Object errors(&scope, runtime_->newStrFromCStr("replace"));
1315 Object index(&scope, runtime_->newInt(0));
1316 Object bytearray(&scope, runtime_->newBytearray());
1317 Object byteorder(&scope, runtime_->newInt(0));
1318 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1319 errors, index, bytearray, byteorder));
1320 ASSERT_TRUE(result_obj.isTuple());
1321
1322 Tuple result(&scope, *result_obj);
1323 Bytes bytes(&scope, result.at(0));
1324 EXPECT_EQ(bytes.length(), 12);
1325 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1326 byte expected[] = {'h', 0x00, 0x00, 0x00, 'i', 0x00,
1327 0x00, 0x00, '?', 0x00, 0x00, 0x00};
1328 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1329}
1330
1331TEST_F(CodecsModuleTest,
1332 EncodeUTF32WithSurroogateescapeErrorHandlerReturnsStr) {
1333 HandleScope scope(thread_);
1334 Object str(&scope, runtime_->newStrFromCStr("h\xed\xb2\x80i"));
1335 Object errors(&scope, runtime_->newStrFromCStr("surrogateescape"));
1336 Object index(&scope, runtime_->newInt(0));
1337 Object bytearray(&scope, runtime_->newBytearray());
1338 Object byteorder(&scope, runtime_->newInt(0));
1339 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1340 errors, index, bytearray, byteorder));
1341 ASSERT_TRUE(result_obj.isTuple());
1342
1343 Tuple result(&scope, *result_obj);
1344 Bytes bytes(&scope, result.at(0));
1345 EXPECT_EQ(bytes.length(), 12);
1346 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1347 byte expected[] = {'h', 0x00, 0x00, 0x00, 0x80, 0x00,
1348 0x00, 0x00, 'i', 0x00, 0x00, 0x00};
1349 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1350}
1351
1352TEST_F(CodecsModuleTest, EncodeUTF32WithSupplementaryStringReturnsUTF32Bytes) {
1353 HandleScope scope(thread_);
1354 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1355 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1356 Object index(&scope, runtime_->newInt(0));
1357 Object bytearray(&scope, runtime_->newBytearray());
1358 Object byteorder(&scope, runtime_->newInt(0));
1359 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1360 errors, index, bytearray, byteorder));
1361 ASSERT_TRUE(result_obj.isTuple());
1362
1363 Tuple result(&scope, *result_obj);
1364 Bytes bytes(&scope, result.at(0));
1365 EXPECT_EQ(bytes.length(), 12);
1366 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1367 byte expected[] = {'h', 0x00, 0x00, 0x00, 0xf0, 0xd1,
1368 0x01, 0x00, 'i', 0x00, 0x00, 0x00};
1369 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1370}
1371
1372TEST_F(CodecsModuleTest,
1373 EncodeUTF32LeWithSupplementaryStringReturnsUTF32Bytes) {
1374 HandleScope scope(thread_);
1375 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1376 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1377 Object index(&scope, runtime_->newInt(0));
1378 Object bytearray(&scope, runtime_->newBytearray());
1379 Object byteorder(&scope, runtime_->newInt(-1));
1380 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1381 errors, index, bytearray, byteorder));
1382 ASSERT_TRUE(result_obj.isTuple());
1383
1384 Tuple result(&scope, *result_obj);
1385 Bytes bytes(&scope, result.at(0));
1386 EXPECT_EQ(bytes.length(), 12);
1387 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1388 byte expected[] = {'h', 0x00, 0x00, 0x00, 0xf0, 0xd1,
1389 0x01, 0x00, 'i', 0x00, 0x00, 0x00};
1390 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1391}
1392
1393TEST_F(CodecsModuleTest,
1394 EncodeUTF32BeWithSupplementaryStringReturnsUTF32Bytes) {
1395 HandleScope scope(thread_);
1396 Object str(&scope, runtime_->newStrFromCStr("h\U0001d1f0i"));
1397 Object errors(&scope, runtime_->newStrFromCStr("strict"));
1398 Object index(&scope, runtime_->newInt(0));
1399 Object bytearray(&scope, runtime_->newBytearray());
1400 Object byteorder(&scope, runtime_->newInt(1));
1401 Object result_obj(&scope, runBuiltin(FUNC(_codecs, _utf_32_encode), str,
1402 errors, index, bytearray, byteorder));
1403 ASSERT_TRUE(result_obj.isTuple());
1404
1405 Tuple result(&scope, *result_obj);
1406 Bytes bytes(&scope, result.at(0));
1407 EXPECT_EQ(bytes.length(), 12);
1408 EXPECT_TRUE(isIntEqualsWord(result.at(1), 3));
1409 byte expected[] = {0x00, 0x00, 0x00, 'h', 0x00, 0x01,
1410 0xd1, 0xf0, 0x00, 0x00, 0x00, 'i'};
1411 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected));
1412}
1413
1414TEST_F(CodecsModuleTest, LookupRareCodecReturnsCodecInfo) {
1415 ASSERT_FALSE(runFromCStr(runtime_, R"(
1416import _codecs
1417codec = _codecs.lookup("iso_ir_6")
1418)")
1419 .isError());
1420 HandleScope scope(thread_);
1421 Object codec(&scope, mainModuleAt(runtime_, "codec"));
1422 EXPECT_TRUE(codec.isHeapObject());
1423}
1424
1425} // namespace testing
1426} // namespace py