this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "marshal.h"
3
4#include <cmath>
5#include <cstdint>
6
7#include "gtest/gtest.h"
8
9#include "globals.h"
10#include "runtime.h"
11#include "test-utils.h"
12
13namespace py {
14namespace testing {
15
16using MarshalReaderDeathTest = RuntimeFixture;
17using MarshalReaderTest = RuntimeFixture;
18
19TEST_F(MarshalReaderTest, ReadBytes) {
20 HandleScope scope(thread_);
21 const byte bytes[] = "hello, world";
22 Marshal::Reader reader(&scope, thread_, bytes);
23
24 const byte* s1 = reader.readBytes(1);
25 ASSERT_NE(s1, nullptr);
26 EXPECT_EQ(*s1, 'h');
27
28 const byte* s2 = reader.readBytes(2);
29 ASSERT_NE(s2, nullptr);
30 EXPECT_EQ(s2[0], 'e');
31 EXPECT_EQ(s2[1], 'l');
32}
33
34TEST_F(MarshalReaderTest, ReadPycHeaderReturnsNone) {
35 HandleScope scope(thread_);
36 byte bytes[] =
37 "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
38 bytes[0] = static_cast<byte>(kPycMagic >> 0);
39 bytes[1] = static_cast<byte>(kPycMagic >> 8);
40 bytes[2] = static_cast<byte>(kPycMagic >> 16);
41 bytes[3] = static_cast<byte>(kPycMagic >> 24);
42 Marshal::Reader reader(&scope, thread_, bytes);
43 Str filename(&scope, runtime_->newStrFromCStr(""));
44 EXPECT_TRUE(reader.readPycHeader(filename).isNoneType());
45}
46
47TEST_F(MarshalReaderTest, ReadPycHeaderRaisesEOFError) {
48 HandleScope scope(thread_);
49 byte bytes[] = "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00";
50 bytes[0] = static_cast<byte>(kPycMagic >> 0);
51 bytes[1] = static_cast<byte>(kPycMagic >> 8);
52 bytes[2] = static_cast<byte>(kPycMagic >> 16);
53 bytes[3] = static_cast<byte>(kPycMagic >> 24);
54 Marshal::Reader reader(&scope, thread_, bytes);
55 Str filename(&scope, runtime_->newStrFromCStr(""));
56 EXPECT_TRUE(raised(reader.readPycHeader(filename), LayoutId::kEOFError));
57}
58
59TEST_F(MarshalReaderTest, ReadPycHeaderWithZeroSizedFileRaisesEOFError) {
60 HandleScope scope(thread_);
61 View<byte> bytes(nullptr, 0);
62 Marshal::Reader reader(&scope, thread_, bytes);
63 Str filename(&scope, runtime_->newStrFromCStr(""));
64 EXPECT_TRUE(raised(reader.readPycHeader(filename), LayoutId::kEOFError));
65}
66
67TEST_F(MarshalReaderTest, ReadPycHeaderRaisesImportError) {
68 HandleScope scope(thread_);
69 byte bytes[] = "1234 ";
70 Marshal::Reader reader(&scope, thread_, bytes);
71 Str filename(&scope, runtime_->newStrFromCStr("<test input>"));
72 EXPECT_TRUE(raisedWithStr(reader.readPycHeader(filename),
73 LayoutId::kImportError,
74 "unsupported magic number in '<test input>'"));
75}
76
77TEST_F(MarshalReaderTest, ReadTypeAsciiNonRef) {
78 HandleScope scope(thread_);
79 const byte bytes[] = "\x61\x0a\x00\x00\x00testing123";
80 Marshal::Reader reader(&scope, thread_, bytes);
81 Object result(&scope, reader.readObject());
82 EXPECT_EQ(reader.numRefs(), 0);
83 EXPECT_TRUE(isStrEqualsCStr(*result, "testing123"));
84
85 // Shouldn't have interned the string during unmarshaling, so interning it
86 // now should return the same string
87 Str str(&scope, runtime_->newStrFromCStr("testing123"));
88 EXPECT_EQ(Runtime::internStr(thread_, str), *str);
89}
90
91TEST_F(MarshalReaderTest, ReadTypeAsciiRef) {
92 HandleScope scope(thread_);
93 const byte bytes[] = "\xe1\x0a\x00\x00\x00testing321";
94 Marshal::Reader reader(&scope, thread_, bytes);
95 Object result(&scope, reader.readObject());
96 EXPECT_EQ(reader.numRefs(), 1);
97 EXPECT_TRUE(isStrEqualsCStr(*result, "testing321"));
98
99 // Shouldn't have interned the string during unmarshaling, so interning it
100 // now should return the same string
101 Str str(&scope, runtime_->newStrFromCStr("testing321"));
102 EXPECT_EQ(Runtime::internStr(thread_, str), *str);
103}
104
105TEST_F(MarshalReaderTest, ReadTypeAsciiWithNegativeLengthReturnsError) {
106 HandleScope scope(thread_);
107 const byte bytes[] = "\x61\xf6\xff\xff\xfftesting123";
108 Marshal::Reader reader(&scope, thread_, bytes);
109 EXPECT_TRUE(reader.readObject().isError());
110}
111
112TEST_F(MarshalReaderTest, ReadTypeAsciiInternedNonRef) {
113 HandleScope scope(thread_);
114 const byte bytes[] = "\x41\x0a\x00\x00\x00testing123";
115 Marshal::Reader reader(&scope, thread_, bytes);
116 Object result(&scope, reader.readObject());
117 EXPECT_EQ(reader.numRefs(), 0);
118 EXPECT_TRUE(isStrEqualsCStr(*result, "testing123"));
119
120 // Should have interned the string during unmarshaling, so interning it
121 // now should return the canonical value.
122 Str str(&scope, runtime_->newStrFromCStr("testing123"));
123 EXPECT_NE(Runtime::internStr(thread_, str), *str);
124}
125
126TEST_F(MarshalReaderTest, ReadTypeAsciiInternedRef) {
127 HandleScope scope(thread_);
128 const byte bytes[] = "\xc1\x0a\x00\x00\x00testing321";
129 Marshal::Reader reader(&scope, thread_, bytes);
130 Object result(&scope, reader.readObject());
131 EXPECT_EQ(reader.numRefs(), 1);
132 EXPECT_TRUE(isStrEqualsCStr(*result, "testing321"));
133
134 // Should have interned the string during unmarshaling, so interning it
135 // now should return the canonical value.
136 Str str(&scope, runtime_->newStrFromCStr("testing321"));
137 EXPECT_NE(Runtime::internStr(thread_, str), *str);
138}
139
140TEST_F(MarshalReaderTest, ReadTypeAsciiInternedWithNegativeLengthReturnsError) {
141 HandleScope scope(thread_);
142 const byte bytes[] = "\x41\xf6\xff\xff\xfftesting123";
143 Marshal::Reader reader(&scope, thread_, bytes);
144 EXPECT_TRUE(reader.readObject().isError());
145}
146
147TEST_F(MarshalReaderTest, ReadTypeUnicodeNonRef) {
148 HandleScope scope(thread_);
149 const byte bytes[] = "\x75\x0a\x00\x00\x00testing123";
150 Marshal::Reader reader(&scope, thread_, bytes);
151 Object result(&scope, reader.readObject());
152 EXPECT_EQ(reader.numRefs(), 0);
153 EXPECT_TRUE(isStrEqualsCStr(*result, "testing123"));
154
155 // Shouldn't have interned the string during unmarshaling, so interning it
156 // now should return the same string
157 Str str(&scope, runtime_->newStrFromCStr("testing123"));
158 EXPECT_EQ(Runtime::internStr(thread_, str), *str);
159}
160
161TEST_F(MarshalReaderTest, ReadTypeUnicodeRef) {
162 HandleScope scope(thread_);
163 const byte bytes[] = "\xf5\x0a\x00\x00\x00testing321";
164 Marshal::Reader reader(&scope, thread_, bytes);
165 Object result(&scope, reader.readObject());
166 EXPECT_EQ(reader.numRefs(), 1);
167 EXPECT_TRUE(isStrEqualsCStr(*result, "testing321"));
168
169 // Shouldn't have interned the string during unmarshaling, so interning it
170 // now should return the same string
171 Str str(&scope, runtime_->newStrFromCStr("testing321"));
172 EXPECT_EQ(Runtime::internStr(thread_, str), *str);
173}
174
175TEST_F(MarshalReaderTest, ReadTypeUnicodeWithNegativeLengthReturnsError) {
176 HandleScope scope(thread_);
177 const byte bytes[] = "\x75\xf6\xff\xff\xfftesting123";
178 Marshal::Reader reader(&scope, thread_, bytes);
179 EXPECT_TRUE(reader.readObject().isError());
180}
181
182TEST_F(MarshalReaderTest, ReadTypeInternedNonRef) {
183 HandleScope scope(thread_);
184 const byte bytes[] = "\x74\x0a\x00\x00\x00testing123";
185 Marshal::Reader reader(&scope, thread_, bytes);
186 Object result(&scope, reader.readObject());
187 EXPECT_EQ(reader.numRefs(), 0);
188 EXPECT_TRUE(isStrEqualsCStr(*result, "testing123"));
189
190 // Should have interned the string during unmarshaling, so interning it
191 // now should return the canonical value.
192 Str str(&scope, runtime_->newStrFromCStr("testing123"));
193 EXPECT_NE(Runtime::internStr(thread_, str), *str);
194}
195
196TEST_F(MarshalReaderTest, ReadTypeInternedRef) {
197 HandleScope scope(thread_);
198 const byte bytes[] = "\xf4\x0a\x00\x00\x00testing321";
199 Marshal::Reader reader(&scope, thread_, bytes);
200 Object ref_result(&scope, reader.readObject());
201 EXPECT_EQ(reader.numRefs(), 1);
202 EXPECT_TRUE(isStrEqualsCStr(*ref_result, "testing321"));
203
204 // Should have interned the string during unmarshaling, so interning it
205 // now should return the canonical value.
206 Str str(&scope, runtime_->newStrFromCStr("testing321"));
207 EXPECT_NE(Runtime::internStr(thread_, str), *str);
208}
209
210TEST_F(MarshalReaderTest, ReadTypeWithInternedWithNegativeLengthReturnsError) {
211 HandleScope scope(thread_);
212 const byte bytes[] = "\x74\xf6\xff\xff\xfftesting123";
213 Marshal::Reader reader(&scope, thread_, bytes);
214 EXPECT_TRUE(reader.readObject().isError());
215}
216
217TEST_F(MarshalReaderTest, ReadTypeShortAsciiInternedNonRef) {
218 HandleScope scope(thread_);
219 const byte bytes[] = "\x5a\x0atesting123";
220 Marshal::Reader reader(&scope, thread_, bytes);
221 Object result(&scope, reader.readObject());
222 EXPECT_EQ(reader.numRefs(), 0);
223 EXPECT_TRUE(isStrEqualsCStr(*result, "testing123"));
224
225 // Should have interned the string during unmarshaling, so interning it
226 // now should return the canonical value.
227 Str str(&scope, runtime_->newStrFromCStr("testing123"));
228 EXPECT_NE(Runtime::internStr(thread_, str), *str);
229}
230
231TEST_F(MarshalReaderTest, ReadTypeShortAsciiInternedRef) {
232 HandleScope scope(thread_);
233 const byte bytes[] = "\xda\x0atesting321";
234 Marshal::Reader reader(&scope, thread_, bytes);
235 Object result(&scope, reader.readObject());
236 EXPECT_EQ(reader.numRefs(), 1);
237 EXPECT_TRUE(isStrEqualsCStr(*result, "testing321"));
238
239 // Should have interned the string during unmarshaling, so interning it
240 // now should return the canonical value.
241 Str str(&scope, runtime_->newStrFromCStr("testing321"));
242 EXPECT_NE(Runtime::internStr(thread_, str), *str);
243}
244
245TEST_F(MarshalReaderTest, ReadLong) {
246 HandleScope scope(thread_);
247
248 const byte bytes_a[] = "\x01\x00\x00\x00";
249 int32_t a = Marshal::Reader(&scope, thread_, bytes_a).readLong();
250 EXPECT_EQ(a, 1);
251
252 const byte bytes_b[] = "\x01\x02\x00\x00";
253 int32_t b = Marshal::Reader(&scope, thread_, bytes_b).readLong();
254 ASSERT_EQ(b, 0x0201);
255
256 const byte bytes_c[] = "\x01\x02\x03\x00";
257 int32_t c = Marshal::Reader(&scope, thread_, bytes_c).readLong();
258 ASSERT_EQ(c, 0x030201);
259
260 const byte bytes_d[] = "\x01\x02\x03\x04";
261 int32_t d = Marshal::Reader(&scope, thread_, bytes_d).readLong();
262 ASSERT_EQ(d, 0x04030201);
263
264 const byte bytes_e[] = "\x00\x00\x00\x80";
265 int32_t e = Marshal::Reader(&scope, thread_, bytes_e).readLong();
266 ASSERT_EQ(e, -2147483648); // INT32_MIN
267}
268
269TEST_F(MarshalReaderTest, ReadTypeIntMin) {
270 HandleScope scope(thread_);
271
272 // marshal.dumps(INT32_MIN)
273 const byte bytes[] = "\xe9\x00\x00\x00\x80";
274 Marshal::Reader reader(&scope, thread_, bytes);
275 RawObject result = reader.readObject();
276 EXPECT_TRUE(isIntEqualsWord(result, INT32_MIN));
277 ASSERT_EQ(reader.numRefs(), 1);
278 EXPECT_EQ(reader.getRef(0), result);
279
280 // marshal.dumps(INT32_MIN)
281 const byte bytes_norefs[] = "\x69\x00\x00\x00\x80";
282 Marshal::Reader reader_norefs(&scope, thread_, bytes_norefs);
283 result = reader_norefs.readObject();
284 EXPECT_TRUE(isIntEqualsWord(result, INT32_MIN));
285 EXPECT_EQ(reader_norefs.numRefs(), 0);
286}
287
288TEST_F(MarshalReaderTest, ReadTypeIntMax) {
289 HandleScope scope(thread_);
290
291 // marshal.dumps(INT32_MAX)
292 const byte bytes[] = "\xe9\xff\xff\xff\x7f";
293 Marshal::Reader reader(&scope, thread_, bytes);
294 RawObject result = reader.readObject();
295 EXPECT_TRUE(isIntEqualsWord(result, INT32_MAX));
296 ASSERT_EQ(reader.numRefs(), 1);
297 EXPECT_EQ(reader.getRef(0), result);
298
299 // marshal.dumps(INT32_MAX)
300 const byte bytes_norefs[] = "\x69\xff\xff\xff\x7f";
301 Marshal::Reader reader_norefs(&scope, thread_, bytes_norefs);
302 result = reader_norefs.readObject();
303 EXPECT_TRUE(isIntEqualsWord(result, INT32_MAX));
304 EXPECT_EQ(reader_norefs.numRefs(), 0);
305}
306
307TEST_F(MarshalReaderTest, ReadBinaryFloat) {
308 HandleScope scope(thread_);
309
310 const byte bytes_a[] = "\x00\x00\x00\x00\x00\x00\x00\x00";
311 double a = Marshal::Reader(&scope, thread_, bytes_a).readBinaryFloat();
312 ASSERT_EQ(a, 0.0);
313
314 const byte bytes_b[] = "\x00\x00\x00\x00\x00\x00\xf0?";
315 double b = Marshal::Reader(&scope, thread_, bytes_b).readBinaryFloat();
316 ASSERT_EQ(b, 1.0);
317
318 const byte bytes_c[] = "\x00\x00\x00\x00\x00\x00\xf0\x7f";
319 double c = Marshal::Reader(&scope, thread_, bytes_c).readBinaryFloat();
320 ASSERT_TRUE(std::isinf(c));
321
322 const byte bytes_d[] = "\x00\x00\x00\x00\x00\x00\xf8\x7f";
323 double d = Marshal::Reader(&scope, thread_, bytes_d).readBinaryFloat();
324 ASSERT_TRUE(std::isnan(d));
325}
326
327TEST_F(MarshalReaderTest, ReadNegativeTypeLong) {
328 HandleScope scope(thread_);
329
330 // marshal.dumps(kMinInt64) + 1
331 const byte bytes[] =
332 "\xec\xfb\xff\xff\xff\xff\x7f\xff\x7f\xff\x7f\xff\x7f\x07\x00";
333 RawObject integer = Marshal::Reader(&scope, thread_, bytes).readObject();
334 EXPECT_TRUE(isIntEqualsWord(integer, kMinInt64 + 1));
335
336 // marshal.dumps(SmallInt::kMinValue)
337 const byte bytes_min[] =
338 "\xec\xfb\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00";
339 integer = Marshal::Reader(&scope, thread_, bytes_min).readObject();
340 EXPECT_TRUE(isIntEqualsWord(integer, SmallInt::kMinValue));
341}
342
343TEST_F(MarshalReaderTest, ReadPositiveTypeLong) {
344 HandleScope scope(thread_);
345
346 // marshal.dumps(kMaxInt64)
347 const byte bytes[] =
348 "\xec\x05\x00\x00\x00\xff\x7f\xff\x7f\xff\x7f\xff\x7f\x07\x00";
349 RawObject integer = Marshal::Reader(&scope, thread_, bytes).readObject();
350 EXPECT_TRUE(isIntEqualsWord(integer, kMaxInt64));
351
352 // marshal.dumps(SmallInt::kMaxValue)
353 const byte bytes_max[] =
354 "\xec\x05\x00\x00\x00\xff\x7f\xff\x7f\xff\x7f\xff\x7f\x03\x00";
355 integer = Marshal::Reader(&scope, thread_, bytes_max).readObject();
356 EXPECT_TRUE(isIntEqualsWord(integer, SmallInt::kMaxValue));
357}
358
359TEST_F(MarshalReaderTest, ReadPositiveMultiDigitTypeLong) {
360 HandleScope scope(thread_);
361
362 // marshal.dumps(kMaxUint64)
363 const byte bytes[] =
364 "\xec\x05\x00\x00\x00\xff\x7f\xff\x7f\xff\x7f\xff\x7f\x0f\x00";
365
366 RawObject obj = Marshal::Reader(&scope, thread_, bytes).readObject();
367 ASSERT_TRUE(obj.isLargeInt());
368 RawLargeInt integer = LargeInt::cast(obj);
369 EXPECT_EQ(integer.numDigits(), 2);
370 EXPECT_TRUE(integer.isPositive());
371 EXPECT_EQ(integer.digitAt(0), kMaxUint64);
372
373 // marshal.dumps(kMaxUint64 << 1)
374 const byte bytes1[] =
375 "\xec\x05\x00\x00\x00\xfe\x7f\xff\x7f\xff\x7f\xff\x7f\x1f\x00";
376
377 obj = Marshal::Reader(&scope, thread_, bytes1).readObject();
378 ASSERT_TRUE(obj.isLargeInt());
379 integer = LargeInt::cast(obj);
380 EXPECT_EQ(integer.numDigits(), 2);
381 EXPECT_TRUE(integer.isPositive());
382 EXPECT_EQ(integer.digitAt(0), uword{kMaxUint64 - 0x1});
383 EXPECT_EQ(integer.digitAt(1), uword{1});
384
385 // marshal.dumps(kMaxUint64 << 4)
386 const byte bytes2[] =
387 "\xec\x05\x00\x00\x00\xf0\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x00";
388
389 obj = Marshal::Reader(&scope, thread_, bytes2).readObject();
390 ASSERT_TRUE(obj.isLargeInt());
391 integer = LargeInt::cast(obj);
392 EXPECT_EQ(integer.numDigits(), 2);
393 EXPECT_TRUE(integer.isPositive());
394 EXPECT_EQ(integer.digitAt(0), uword{kMaxUint64 - 0xF});
395 EXPECT_EQ(integer.digitAt(1), uword{15});
396
397 // marshal.dumps(1 << 63)
398 const byte bytes3[] =
399 "\xec\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00";
400
401 obj = Marshal::Reader(&scope, thread_, bytes3).readObject();
402 ASSERT_TRUE(obj.isLargeInt());
403 integer = LargeInt::cast(obj);
404 ASSERT_EQ(integer.numDigits(), 2);
405 EXPECT_EQ(integer.digitAt(0), uword{1} << (kBitsPerWord - 1));
406 EXPECT_EQ(integer.digitAt(1), uword{0});
407}
408
409TEST_F(MarshalReaderTest, ReadNegativeMultiDigitTypeLong) {
410 HandleScope scope(thread_);
411
412 // marshal.dumps(-kMaxUint64)
413 const byte bytes[] =
414 "\xec\xfb\xff\xff\xff\xff\x7f\xff\x7f\xff\x7f\xff\x7f\x0f\x00";
415 RawObject obj = Marshal::Reader(&scope, thread_, bytes).readObject();
416 ASSERT_TRUE(obj.isLargeInt());
417 RawLargeInt integer = LargeInt::cast(obj);
418 EXPECT_EQ(integer.numDigits(), 2);
419 EXPECT_TRUE(integer.isNegative());
420 EXPECT_EQ(integer.digitAt(0), uword{1});
421 EXPECT_EQ(integer.digitAt(1), uword{kMaxUint64});
422
423 // marshal.dumps(-(kMaxUint64 << 1))
424 const byte bytes1[] =
425 "\xec\xfb\xff\xff\xff\xfe\x7f\xff\x7f\xff\x7f\xff\x7f\x1f\x00";
426 RawObject obj1 = Marshal::Reader(&scope, thread_, bytes1).readObject();
427 ASSERT_TRUE(obj1.isLargeInt());
428 RawLargeInt integer1 = LargeInt::cast(obj1);
429 EXPECT_EQ(integer1.numDigits(), 2);
430 EXPECT_TRUE(integer1.isNegative());
431 EXPECT_EQ(integer1.digitAt(0), uword{2}); // ~(kMaxUint64 << 1) + 1
432 EXPECT_EQ(integer1.digitAt(1), uword{kMaxUint64 ^ 1}); // sign_extend(~1)
433
434 // marshal.dumps(-(kMaxUint64 << 4))
435 const byte bytes2[] =
436 "\xec\xfb\xff\xff\xff\xf0\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x00";
437 RawObject obj2 = Marshal::Reader(&scope, thread_, bytes2).readObject();
438 ASSERT_TRUE(obj2.isLargeInt());
439 RawLargeInt integer2 = LargeInt::cast(obj2);
440 EXPECT_EQ(integer2.numDigits(), 2);
441 EXPECT_TRUE(integer2.isNegative());
442 EXPECT_EQ(integer2.digitAt(0), uword{16}); // ~(kMaxUint64 << 4) + 1
443 EXPECT_EQ(integer2.digitAt(1), ~uword{16} + 1);
444
445 // marshal.dumps(-(1 << 63))
446 const byte bytes3[] =
447 "\xec\xfb\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00";
448 RawObject obj3 = Marshal::Reader(&scope, thread_, bytes3).readObject();
449 ASSERT_TRUE(obj3.isLargeInt());
450 RawLargeInt integer3 = LargeInt::cast(obj3);
451 ASSERT_EQ(integer3.numDigits(), 1);
452 EXPECT_EQ(integer3.digitAt(0), uword{1} << (kBitsPerWord - 1));
453}
454
455TEST_F(MarshalReaderDeathTest, ReadUnknownTypeCode) {
456 HandleScope scope(thread_);
457 const byte bytes[] = "\xff";
458 EXPECT_DEATH(Marshal::Reader(&scope, thread_, bytes).readObject(),
459 "unreachable: unknown type");
460}
461
462TEST_F(MarshalReaderTest, ReadShort) {
463 HandleScope scope(thread_);
464
465 const byte bytes_a[] = "\x01\x00";
466 int16_t a = Marshal::Reader(&scope, thread_, bytes_a).readShort();
467 EXPECT_EQ(a, 1);
468
469 const byte bytes_b[] = "\x01\x02";
470 int16_t b = Marshal::Reader(&scope, thread_, bytes_b).readShort();
471 ASSERT_EQ(b, 0x0201);
472
473 const byte bytes_c[] = "\x00\x80";
474 int16_t c = Marshal::Reader(&scope, thread_, bytes_c).readShort();
475 ASSERT_EQ(c, kMinInt16);
476}
477
478TEST_F(MarshalReaderTest, ReadObjectNull) {
479 HandleScope scope(thread_);
480 const byte bytes[] = "0";
481 RawObject a = Marshal::Reader(&scope, thread_, bytes).readObject();
482 ASSERT_EQ(a, RawObject{0});
483}
484
485TEST_F(MarshalReaderTest, ReadObjectCode) {
486 HandleScope scope(thread_);
487 const byte bytes[] =
488 "\x33\x0D\x0D\x0A\x3B\x5B\xB8\x59\x05\x00\x00\x00\xE3\x00\x00\x00\x00\x00"
489 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x40\x00\x00"
490 "\x00\x73\x04\x00\x00\x00\x64\x00\x53\x00\x29\x01\x4E\xA9\x00\x72\x01\x00"
491 "\x00\x00\x72\x01\x00\x00\x00\x72\x01\x00\x00\x00\xFA\x07\x70\x61\x73\x73"
492 "\x2E\x70\x79\xDA\x08\x3C\x6D\x6F\x64\x75\x6C\x65\x3E\x01\x00\x00\x00\x73"
493 "\x00\x00\x00\x00";
494 Marshal::Reader reader(&scope, thread_, bytes);
495
496 int32_t magic = reader.readLong();
497 EXPECT_EQ(magic, 0x0A0D0D33);
498 int32_t mtime = reader.readLong();
499 EXPECT_EQ(mtime, 0x59B85B3B);
500 int32_t size = reader.readLong();
501 EXPECT_EQ(size, 0x05);
502
503 RawObject raw_object = reader.readObject();
504 ASSERT_TRUE(raw_object.isCode());
505
506 RawCode code = Code::cast(raw_object);
507 EXPECT_EQ(code.argcount(), 0);
508 EXPECT_EQ(code.posonlyargcount(), 0);
509 EXPECT_EQ(code.kwonlyargcount(), 0);
510 EXPECT_EQ(code.nlocals(), 0);
511 EXPECT_EQ(code.stacksize(), 1);
512 EXPECT_TRUE(code.cell2arg().isNoneType());
513 EXPECT_EQ(code.flags(), Code::Flags::kNofree);
514
515 ASSERT_TRUE(code.code().isBytes());
516 EXPECT_NE(Bytes::cast(code.code()).length(), 0);
517
518 ASSERT_TRUE(code.varnames().isTuple());
519 EXPECT_EQ(Tuple::cast(code.varnames()).length(), 0);
520
521 ASSERT_TRUE(code.cellvars().isTuple());
522 EXPECT_EQ(Tuple::cast(code.cellvars()).length(), 0);
523
524 ASSERT_TRUE(code.consts().isTuple());
525 ASSERT_EQ(Tuple::cast(code.consts()).length(), 1);
526 EXPECT_EQ(Tuple::cast(code.consts()).at(0), NoneType::object());
527
528 ASSERT_TRUE(code.freevars().isTuple());
529 EXPECT_EQ(Tuple::cast(code.freevars()).length(), 0);
530
531 ASSERT_TRUE(code.filename().isStr());
532 EXPECT_TRUE(Str::cast(code.filename()).equalsCStr("pass.py"));
533
534 ASSERT_TRUE(code.name().isStr());
535 EXPECT_TRUE(Str::cast(code.name()).equalsCStr("<module>"));
536
537 ASSERT_TRUE(code.names().isTuple());
538 EXPECT_EQ(Tuple::cast(code.names()).length(), 0);
539
540 EXPECT_EQ(code.firstlineno(), 1);
541
542 ASSERT_TRUE(code.lnotab().isBytes());
543 EXPECT_EQ(Bytes::cast(code.lnotab()).length(), 0);
544}
545
546TEST_F(MarshalReaderTest, ReadObjectSetOnEmptySetReturnsEmptySet) {
547 HandleScope scope(thread_);
548 // marshal.dumps(set())
549 const byte bytes[] = "\xbc\x00\x00\x00\x00";
550 Marshal::Reader reader(&scope, thread_, bytes);
551 Object obj(&scope, reader.readObject());
552 ASSERT_TRUE(obj.isSet());
553 EXPECT_EQ(Set::cast(*obj).numItems(), 0);
554}
555
556TEST_F(MarshalReaderTest, ReadObjectSetOnNonEmptySetReturnsCorrectNonEmptySet) {
557 HandleScope scope(thread_);
558 // marshal.dumps(set([1,2,3]))
559 const byte bytes[] =
560 "\xbc\x03\x00\x00\x00\xe9\x01\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x03\x00"
561 "\x00\x00";
562 Marshal::Reader reader(&scope, thread_, bytes);
563 Object obj(&scope, reader.readObject());
564 ASSERT_TRUE(obj.isSet());
565 Set set(&scope, *obj);
566 EXPECT_EQ(set.numItems(), 3);
567 Int one(&scope, SmallInt::fromWord(1));
568 EXPECT_TRUE(setIncludes(thread_, set, one));
569 Int two(&scope, SmallInt::fromWord(2));
570 EXPECT_TRUE(setIncludes(thread_, set, two));
571 Int three(&scope, SmallInt::fromWord(3));
572 EXPECT_TRUE(setIncludes(thread_, set, three));
573}
574
575TEST_F(MarshalReaderTest, ReadObjectFrozenSetOnEmptySetReturnsEmptyFrozenSet) {
576 HandleScope scope(thread_);
577 // marshal.dumps(frozenset())
578 const byte bytes[] = "\xbe\x00\x00\x00\x00";
579 Marshal::Reader reader(&scope, thread_, bytes);
580 Object obj(&scope, reader.readObject());
581 ASSERT_TRUE(obj.isFrozenSet());
582 EXPECT_EQ(FrozenSet::cast(*obj).numItems(), 0);
583}
584
585TEST_F(MarshalReaderTest,
586 ReadObjectFrozenSetOnEmptySetReturnsEmptyFrozenSetSingleton) {
587 HandleScope scope(thread_);
588 // marshal.dumps(frozenset())
589 const byte bytes[] = "\xbe\x00\x00\x00\x00";
590 Marshal::Reader reader(&scope, thread_, bytes);
591 Object obj(&scope, reader.readObject());
592 ASSERT_EQ(*obj, runtime_->emptyFrozenSet());
593}
594
595TEST_F(MarshalReaderTest,
596 ReadObjectFrozenSetOnNonEmptySetReturnsCorrectNonEmptyFrozenSet) {
597 HandleScope scope(thread_);
598 // marshal.dumps(frozenset([1,2,3]))
599 const byte bytes[] =
600 "\xbe\x03\x00\x00\x00\xe9\x01\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x03\x00"
601 "\x00\x00";
602 Marshal::Reader reader(&scope, thread_, bytes);
603 Object obj(&scope, reader.readObject());
604 ASSERT_TRUE(obj.isFrozenSet());
605 FrozenSet set(&scope, *obj);
606 EXPECT_EQ(set.numItems(), 3);
607 Int one(&scope, SmallInt::fromWord(1));
608 EXPECT_TRUE(setIncludes(thread_, set, one));
609 Int two(&scope, SmallInt::fromWord(2));
610 EXPECT_TRUE(setIncludes(thread_, set, two));
611 Int three(&scope, SmallInt::fromWord(3));
612 EXPECT_TRUE(setIncludes(thread_, set, three));
613}
614
615TEST_F(MarshalReaderTest,
616 ReadObjectLongReturnsNegativeLargeIntWithSignExtension) {
617 HandleScope scope(thread_);
618 // This is: -0x8000000000000000_0000000000000001
619 const byte bytes[] =
620 "l"
621 "\xf7\xff\xff\xff"
622 "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
623 "\x00\x00\x00\x80\x00";
624 Marshal::Reader reader(&scope, thread_, bytes);
625 Object result(&scope, reader.readObject());
626 const uword digits[] = {kMaxUword, static_cast<uword>(kMaxWord), kMaxUword};
627 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
628}
629
630TEST_F(MarshalReaderTest,
631 ReadObjectLongReturnsNegativeLargeIntWithoutSignExtension) {
632 HandleScope scope(thread_);
633 // This is: -0x8000000000000000
634 const byte bytes[] =
635 "l"
636 "\xfb\xff\xff\xff"
637 "\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00";
638 Marshal::Reader reader(&scope, thread_, bytes);
639 Object result(&scope, reader.readObject());
640 EXPECT_TRUE(isIntEqualsWord(*result, -0x8000000000000000));
641}
642
643} // namespace testing
644} // namespace py