Branch data Line data Source code
1 : :
2 : : /* Write Python objects to files and read them back.
3 : : This is primarily intended for writing and reading compiled Python code,
4 : : even though dicts, lists, sets and frozensets, not commonly seen in
5 : : code objects, are supported.
6 : : Version 3 of this protocol properly supports circular links
7 : : and sharing. */
8 : :
9 : : #define PY_SSIZE_T_CLEAN
10 : :
11 : : #include "Python.h"
12 : : #include "pycore_call.h" // _PyObject_CallNoArgs()
13 : : #include "pycore_code.h" // _PyCode_New()
14 : : #include "pycore_hashtable.h" // _Py_hashtable_t
15 : : #include "marshal.h" // Py_MARSHAL_VERSION
16 : :
17 : : /*[clinic input]
18 : : module marshal
19 : : [clinic start generated code]*/
20 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/
21 : :
22 : : #include "clinic/marshal.c.h"
23 : :
24 : : /* High water mark to determine when the marshalled object is dangerously deep
25 : : * and risks coring the interpreter. When the object stack gets this deep,
26 : : * raise an exception instead of continuing.
27 : : * On Windows debug builds, reduce this value.
28 : : *
29 : : * BUG: https://bugs.python.org/issue33720
30 : : * On Windows PGO builds, the r_object function overallocates its stack and
31 : : * can cause a stack overflow. We reduce the maximum depth for all Windows
32 : : * releases to protect against this.
33 : : * #if defined(MS_WINDOWS) && defined(_DEBUG)
34 : : */
35 : : #if defined(MS_WINDOWS)
36 : : #define MAX_MARSHAL_STACK_DEPTH 1000
37 : : #elif defined(__wasi__)
38 : : #define MAX_MARSHAL_STACK_DEPTH 1500
39 : : #else
40 : : #define MAX_MARSHAL_STACK_DEPTH 2000
41 : : #endif
42 : :
43 : : #define TYPE_NULL '0'
44 : : #define TYPE_NONE 'N'
45 : : #define TYPE_FALSE 'F'
46 : : #define TYPE_TRUE 'T'
47 : : #define TYPE_STOPITER 'S'
48 : : #define TYPE_ELLIPSIS '.'
49 : : #define TYPE_INT 'i'
50 : : /* TYPE_INT64 is not generated anymore.
51 : : Supported for backward compatibility only. */
52 : : #define TYPE_INT64 'I'
53 : : #define TYPE_FLOAT 'f'
54 : : #define TYPE_BINARY_FLOAT 'g'
55 : : #define TYPE_COMPLEX 'x'
56 : : #define TYPE_BINARY_COMPLEX 'y'
57 : : #define TYPE_LONG 'l'
58 : : #define TYPE_STRING 's'
59 : : #define TYPE_INTERNED 't'
60 : : #define TYPE_REF 'r'
61 : : #define TYPE_TUPLE '('
62 : : #define TYPE_LIST '['
63 : : #define TYPE_DICT '{'
64 : : #define TYPE_CODE 'c'
65 : : #define TYPE_UNICODE 'u'
66 : : #define TYPE_UNKNOWN '?'
67 : : #define TYPE_SET '<'
68 : : #define TYPE_FROZENSET '>'
69 : : #define FLAG_REF '\x80' /* with a type, add obj to index */
70 : :
71 : : #define TYPE_ASCII 'a'
72 : : #define TYPE_ASCII_INTERNED 'A'
73 : : #define TYPE_SMALL_TUPLE ')'
74 : : #define TYPE_SHORT_ASCII 'z'
75 : : #define TYPE_SHORT_ASCII_INTERNED 'Z'
76 : :
77 : : #define WFERR_OK 0
78 : : #define WFERR_UNMARSHALLABLE 1
79 : : #define WFERR_NESTEDTOODEEP 2
80 : : #define WFERR_NOMEMORY 3
81 : :
82 : : typedef struct {
83 : : FILE *fp;
84 : : int error; /* see WFERR_* values */
85 : : int depth;
86 : : PyObject *str;
87 : : char *ptr;
88 : : const char *end;
89 : : char *buf;
90 : : _Py_hashtable_t *hashtable;
91 : : int version;
92 : : } WFILE;
93 : :
94 : : #define w_byte(c, p) do { \
95 : : if ((p)->ptr != (p)->end || w_reserve((p), 1)) \
96 : : *(p)->ptr++ = (c); \
97 : : } while(0)
98 : :
99 : : static void
100 : 0 : w_flush(WFILE *p)
101 : : {
102 : : assert(p->fp != NULL);
103 : 0 : fwrite(p->buf, 1, p->ptr - p->buf, p->fp);
104 : 0 : p->ptr = p->buf;
105 : 0 : }
106 : :
107 : : static int
108 : 737 : w_reserve(WFILE *p, Py_ssize_t needed)
109 : : {
110 : : Py_ssize_t pos, size, delta;
111 [ - + ]: 737 : if (p->ptr == NULL)
112 : 0 : return 0; /* An error already occurred */
113 [ - + ]: 737 : if (p->fp != NULL) {
114 : 0 : w_flush(p);
115 : 0 : return needed <= p->end - p->ptr;
116 : : }
117 : : assert(p->str != NULL);
118 : 737 : pos = p->ptr - p->buf;
119 : 737 : size = PyBytes_GET_SIZE(p->str);
120 [ - + ]: 737 : if (size > 16*1024*1024)
121 : 0 : delta = (size >> 3); /* 12.5% overallocation */
122 : : else
123 : 737 : delta = size + 1024;
124 : 737 : delta = Py_MAX(delta, needed);
125 [ - + ]: 737 : if (delta > PY_SSIZE_T_MAX - size) {
126 : 0 : p->error = WFERR_NOMEMORY;
127 : 0 : return 0;
128 : : }
129 : 737 : size += delta;
130 [ - + ]: 737 : if (_PyBytes_Resize(&p->str, size) != 0) {
131 : 0 : p->end = p->ptr = p->buf = NULL;
132 : 0 : return 0;
133 : : }
134 : : else {
135 : 737 : p->buf = PyBytes_AS_STRING(p->str);
136 : 737 : p->ptr = p->buf + pos;
137 : 737 : p->end = p->buf + size;
138 : 737 : return 1;
139 : : }
140 : : }
141 : :
142 : : static void
143 : 69409 : w_string(const void *s, Py_ssize_t n, WFILE *p)
144 : : {
145 : : Py_ssize_t m;
146 [ + + - + ]: 69409 : if (!n || p->ptr == NULL)
147 : 286 : return;
148 : 69123 : m = p->end - p->ptr;
149 [ - + ]: 69123 : if (p->fp != NULL) {
150 [ # # ]: 0 : if (n <= m) {
151 : 0 : memcpy(p->ptr, s, n);
152 : 0 : p->ptr += n;
153 : : }
154 : : else {
155 : 0 : w_flush(p);
156 : 0 : fwrite(s, 1, n, p->fp);
157 : : }
158 : : }
159 : : else {
160 [ + + + - ]: 69123 : if (n <= m || w_reserve(p, n - m)) {
161 : 69123 : memcpy(p->ptr, s, n);
162 : 69123 : p->ptr += n;
163 : : }
164 : : }
165 : : }
166 : :
167 : : static void
168 : 180 : w_short(int x, WFILE *p)
169 : : {
170 [ - + - - ]: 180 : w_byte((char)( x & 0xff), p);
171 [ - + - - ]: 180 : w_byte((char)((x>> 8) & 0xff), p);
172 : 180 : }
173 : :
174 : : static void
175 : 155909 : w_long(long x, WFILE *p)
176 : : {
177 [ + + + - ]: 155909 : w_byte((char)( x & 0xff), p);
178 [ + + + - ]: 155909 : w_byte((char)((x>> 8) & 0xff), p);
179 [ + + + - ]: 155909 : w_byte((char)((x>>16) & 0xff), p);
180 [ + + + - ]: 155909 : w_byte((char)((x>>24) & 0xff), p);
181 : 155909 : }
182 : :
183 : : #define SIZE32_MAX 0x7FFFFFFF
184 : :
185 : : #if SIZEOF_SIZE_T > 4
186 : : # define W_SIZE(n, p) do { \
187 : : if ((n) > SIZE32_MAX) { \
188 : : (p)->depth--; \
189 : : (p)->error = WFERR_UNMARSHALLABLE; \
190 : : return; \
191 : : } \
192 : : w_long((long)(n), p); \
193 : : } while(0)
194 : : #else
195 : : # define W_SIZE w_long
196 : : #endif
197 : :
198 : : static void
199 : 23942 : w_pstring(const void *s, Py_ssize_t n, WFILE *p)
200 : : {
201 [ - + ]: 23942 : W_SIZE(n, p);
202 : 23942 : w_string(s, n, p);
203 : : }
204 : :
205 : : static void
206 : 45213 : w_short_pstring(const void *s, Py_ssize_t n, WFILE *p)
207 : : {
208 [ + + + - ]: 45213 : w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p);
209 : 45213 : w_string(s, n, p);
210 : 45213 : }
211 : :
212 : : /* We assume that Python ints are stored internally in base some power of
213 : : 2**15; for the sake of portability we'll always read and write them in base
214 : : exactly 2**15. */
215 : :
216 : : #define PyLong_MARSHAL_SHIFT 15
217 : : #define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
218 : : #define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
219 : : #if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
220 : : #error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
221 : : #endif
222 : : #define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
223 : :
224 : : #define W_TYPE(t, p) do { \
225 : : w_byte((t) | flag, (p)); \
226 : : } while(0)
227 : :
228 : : static void
229 : 35 : w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
230 : : {
231 : : Py_ssize_t i, j, n, l;
232 : : digit d;
233 : :
234 [ - + - - ]: 35 : W_TYPE(TYPE_LONG, p);
235 [ - + ]: 35 : if (Py_SIZE(ob) == 0) {
236 : 0 : w_long((long)0, p);
237 : 0 : return;
238 : : }
239 : :
240 : : /* set l to number of base PyLong_MARSHAL_BASE digits */
241 [ + + ]: 35 : n = Py_ABS(Py_SIZE(ob));
242 : 35 : l = (n-1) * PyLong_MARSHAL_RATIO;
243 : 35 : d = ob->long_value.ob_digit[n-1];
244 : : assert(d != 0); /* a PyLong is always normalized */
245 : : do {
246 : 40 : d >>= PyLong_MARSHAL_SHIFT;
247 : 40 : l++;
248 [ + + ]: 40 : } while (d != 0);
249 [ - + ]: 35 : if (l > SIZE32_MAX) {
250 : 0 : p->depth--;
251 : 0 : p->error = WFERR_UNMARSHALLABLE;
252 : 0 : return;
253 : : }
254 [ + + ]: 35 : w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
255 : :
256 [ + + ]: 105 : for (i=0; i < n-1; i++) {
257 : 70 : d = ob->long_value.ob_digit[i];
258 [ + + ]: 210 : for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
259 : 140 : w_short(d & PyLong_MARSHAL_MASK, p);
260 : 140 : d >>= PyLong_MARSHAL_SHIFT;
261 : : }
262 : : assert (d == 0);
263 : : }
264 : 35 : d = ob->long_value.ob_digit[n-1];
265 : : do {
266 : 40 : w_short(d & PyLong_MARSHAL_MASK, p);
267 : 40 : d >>= PyLong_MARSHAL_SHIFT;
268 [ + + ]: 40 : } while (d != 0);
269 : : }
270 : :
271 : : static void
272 : 254 : w_float_bin(double v, WFILE *p)
273 : : {
274 : : char buf[8];
275 [ - + ]: 254 : if (PyFloat_Pack8(v, buf, 1) < 0) {
276 : 0 : p->error = WFERR_UNMARSHALLABLE;
277 : 0 : return;
278 : : }
279 : 254 : w_string(buf, 8, p);
280 : : }
281 : :
282 : : static void
283 : 0 : w_float_str(double v, WFILE *p)
284 : : {
285 : 0 : char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL);
286 [ # # ]: 0 : if (!buf) {
287 : 0 : p->error = WFERR_NOMEMORY;
288 : 0 : return;
289 : : }
290 : 0 : w_short_pstring(buf, strlen(buf), p);
291 : 0 : PyMem_Free(buf);
292 : : }
293 : :
294 : : static int
295 : 181773 : w_ref(PyObject *v, char *flag, WFILE *p)
296 : : {
297 : : _Py_hashtable_entry_t *entry;
298 : : int w;
299 : :
300 [ + - - + ]: 181773 : if (p->version < 3 || p->hashtable == NULL)
301 : 0 : return 0; /* not writing object references */
302 : :
303 : : /* If it has only one reference, it definitely isn't shared.
304 : : * But we use TYPE_REF always for interned string, to PYC file stable
305 : : * as possible.
306 : : */
307 [ + + + + ]: 240794 : if (Py_REFCNT(v) == 1 &&
308 [ + + ]: 78283 : !(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) {
309 : 52447 : return 0;
310 : : }
311 : :
312 : 129326 : entry = _Py_hashtable_get_entry(p->hashtable, v);
313 [ + + ]: 129326 : if (entry != NULL) {
314 : : /* write the reference index to the stream */
315 : 84251 : w = (int)(uintptr_t)entry->value;
316 : : /* we don't store "long" indices in the dict */
317 : : assert(0 <= w && w <= 0x7fffffff);
318 [ + + + - ]: 84251 : w_byte(TYPE_REF, p);
319 : 84251 : w_long(w, p);
320 : 84251 : return 1;
321 : : } else {
322 : 45075 : size_t s = p->hashtable->nentries;
323 : : /* we don't support long indices */
324 [ - + ]: 45075 : if (s >= 0x7fffffff) {
325 : 0 : PyErr_SetString(PyExc_ValueError, "too many objects");
326 : 0 : goto err;
327 : : }
328 : 45075 : w = (int)s;
329 [ - + ]: 45075 : if (_Py_hashtable_set(p->hashtable, Py_NewRef(v),
330 : 45075 : (void *)(uintptr_t)w) < 0) {
331 : 0 : Py_DECREF(v);
332 : 0 : goto err;
333 : : }
334 : 45075 : *flag |= FLAG_REF;
335 : 45075 : return 0;
336 : : }
337 : 0 : err:
338 : 0 : p->error = WFERR_UNMARSHALLABLE;
339 : 0 : return 1;
340 : : }
341 : :
342 : : static void
343 : : w_complex_object(PyObject *v, char flag, WFILE *p);
344 : :
345 : : static void
346 : 187604 : w_object(PyObject *v, WFILE *p)
347 : : {
348 : 187604 : char flag = '\0';
349 : :
350 : 187604 : p->depth++;
351 : :
352 [ - + ]: 187604 : if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
353 : 0 : p->error = WFERR_NESTEDTOODEEP;
354 : : }
355 [ - + ]: 187604 : else if (v == NULL) {
356 [ # # # # ]: 0 : w_byte(TYPE_NULL, p);
357 : : }
358 [ + + ]: 187604 : else if (v == Py_None) {
359 [ - + - - ]: 4561 : w_byte(TYPE_NONE, p);
360 : : }
361 [ - + ]: 183043 : else if (v == PyExc_StopIteration) {
362 [ # # # # ]: 0 : w_byte(TYPE_STOPITER, p);
363 : : }
364 [ + + ]: 183043 : else if (v == Py_Ellipsis) {
365 [ - + - - ]: 15 : w_byte(TYPE_ELLIPSIS, p);
366 : : }
367 [ + + ]: 183028 : else if (v == Py_False) {
368 [ - + - - ]: 639 : w_byte(TYPE_FALSE, p);
369 : : }
370 [ + + ]: 182389 : else if (v == Py_True) {
371 [ - + - - ]: 616 : w_byte(TYPE_TRUE, p);
372 : : }
373 [ + + ]: 181773 : else if (!w_ref(v, &flag, p))
374 : 97522 : w_complex_object(v, flag, p);
375 : :
376 : 187604 : p->depth--;
377 : 187604 : }
378 : :
379 : : static void
380 : 97522 : w_complex_object(PyObject *v, char flag, WFILE *p)
381 : : {
382 : : Py_ssize_t i, n;
383 : :
384 [ + + ]: 97522 : if (PyLong_CheckExact(v)) {
385 : : int overflow;
386 : 1801 : long x = PyLong_AsLongAndOverflow(v, &overflow);
387 [ + + ]: 1801 : if (overflow) {
388 : 15 : w_PyLong((PyLongObject *)v, flag, p);
389 : : }
390 : : else {
391 : : #if SIZEOF_LONG > 4
392 : 1786 : long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
393 [ + + + + ]: 1786 : if (y && y != -1) {
394 : : /* Too large for TYPE_INT */
395 : 20 : w_PyLong((PyLongObject*)v, flag, p);
396 : : }
397 : : else
398 : : #endif
399 : : {
400 [ + + + - ]: 1766 : W_TYPE(TYPE_INT, p);
401 : 1766 : w_long(x, p);
402 : : }
403 : : }
404 : : }
405 [ + + ]: 95721 : else if (PyFloat_CheckExact(v)) {
406 [ + - ]: 248 : if (p->version > 1) {
407 [ - + - - ]: 248 : W_TYPE(TYPE_BINARY_FLOAT, p);
408 : 248 : w_float_bin(PyFloat_AS_DOUBLE(v), p);
409 : : }
410 : : else {
411 [ # # # # ]: 0 : W_TYPE(TYPE_FLOAT, p);
412 : 0 : w_float_str(PyFloat_AS_DOUBLE(v), p);
413 : : }
414 : : }
415 [ + + ]: 95473 : else if (PyComplex_CheckExact(v)) {
416 [ + - ]: 3 : if (p->version > 1) {
417 [ - + - - ]: 3 : W_TYPE(TYPE_BINARY_COMPLEX, p);
418 : 3 : w_float_bin(PyComplex_RealAsDouble(v), p);
419 : 3 : w_float_bin(PyComplex_ImagAsDouble(v), p);
420 : : }
421 : : else {
422 [ # # # # ]: 0 : W_TYPE(TYPE_COMPLEX, p);
423 : 0 : w_float_str(PyComplex_RealAsDouble(v), p);
424 : 0 : w_float_str(PyComplex_ImagAsDouble(v), p);
425 : : }
426 : : }
427 [ + + ]: 95470 : else if (PyBytes_CheckExact(v)) {
428 [ + + + - ]: 23070 : W_TYPE(TYPE_STRING, p);
429 : 23070 : w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
430 : : }
431 [ + + ]: 72400 : else if (PyUnicode_CheckExact(v)) {
432 [ + - + + ]: 92146 : if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
433 : 46061 : int is_short = PyUnicode_GET_LENGTH(v) < 256;
434 [ + + ]: 46061 : if (is_short) {
435 [ + + ]: 45213 : if (PyUnicode_CHECK_INTERNED(v))
436 [ + + + - ]: 31805 : W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
437 : : else
438 [ + + + - ]: 13408 : W_TYPE(TYPE_SHORT_ASCII, p);
439 : 45213 : w_short_pstring(PyUnicode_1BYTE_DATA(v),
440 : : PyUnicode_GET_LENGTH(v), p);
441 : : }
442 : : else {
443 [ - + ]: 848 : if (PyUnicode_CHECK_INTERNED(v))
444 [ # # # # ]: 0 : W_TYPE(TYPE_ASCII_INTERNED, p);
445 : : else
446 [ - + - - ]: 848 : W_TYPE(TYPE_ASCII, p);
447 : 848 : w_pstring(PyUnicode_1BYTE_DATA(v),
448 : : PyUnicode_GET_LENGTH(v), p);
449 : : }
450 : : }
451 : : else {
452 : : PyObject *utf8;
453 : 24 : utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
454 [ - + ]: 24 : if (utf8 == NULL) {
455 : 0 : p->depth--;
456 : 0 : p->error = WFERR_UNMARSHALLABLE;
457 : 0 : return;
458 : : }
459 [ + - - + ]: 24 : if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
460 [ # # # # ]: 0 : W_TYPE(TYPE_INTERNED, p);
461 : : else
462 [ - + - - ]: 24 : W_TYPE(TYPE_UNICODE, p);
463 : 24 : w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
464 : 24 : Py_DECREF(utf8);
465 : : }
466 : : }
467 [ + + ]: 26315 : else if (PyTuple_CheckExact(v)) {
468 : 18634 : n = PyTuple_GET_SIZE(v);
469 [ + - + + ]: 18634 : if (p->version >= 4 && n < 256) {
470 [ + + + - ]: 18630 : W_TYPE(TYPE_SMALL_TUPLE, p);
471 [ + + + - ]: 18630 : w_byte((unsigned char)n, p);
472 : : }
473 : : else {
474 [ + - + - ]: 4 : W_TYPE(TYPE_TUPLE, p);
475 [ - + ]: 4 : W_SIZE(n, p);
476 : : }
477 [ + + ]: 129383 : for (i = 0; i < n; i++) {
478 : 110749 : w_object(PyTuple_GET_ITEM(v, i), p);
479 : : }
480 : : }
481 [ - + ]: 7681 : else if (PyList_CheckExact(v)) {
482 [ # # # # ]: 0 : W_TYPE(TYPE_LIST, p);
483 : 0 : n = PyList_GET_SIZE(v);
484 [ # # ]: 0 : W_SIZE(n, p);
485 [ # # ]: 0 : for (i = 0; i < n; i++) {
486 : 0 : w_object(PyList_GET_ITEM(v, i), p);
487 : : }
488 : : }
489 [ - + ]: 7681 : else if (PyDict_CheckExact(v)) {
490 : : Py_ssize_t pos;
491 : : PyObject *key, *value;
492 [ # # # # ]: 0 : W_TYPE(TYPE_DICT, p);
493 : : /* This one is NULL object terminated! */
494 : 0 : pos = 0;
495 [ # # ]: 0 : while (PyDict_Next(v, &pos, &key, &value)) {
496 : 0 : w_object(key, p);
497 : 0 : w_object(value, p);
498 : : }
499 : 0 : w_object((PyObject *)NULL, p);
500 : : }
501 [ + - + + ]: 7716 : else if (PyAnySet_CheckExact(v)) {
502 : : PyObject *value;
503 : 35 : Py_ssize_t pos = 0;
504 : : Py_hash_t hash;
505 : :
506 [ + - ]: 35 : if (PyFrozenSet_CheckExact(v))
507 [ - + - - ]: 35 : W_TYPE(TYPE_FROZENSET, p);
508 : : else
509 [ # # # # ]: 0 : W_TYPE(TYPE_SET, p);
510 : 35 : n = PySet_GET_SIZE(v);
511 [ - + ]: 35 : W_SIZE(n, p);
512 : : // bpo-37596: To support reproducible builds, sets and frozensets need
513 : : // to have their elements serialized in a consistent order (even when
514 : : // they have been scrambled by hash randomization). To ensure this, we
515 : : // use an order equivalent to sorted(v, key=marshal.dumps):
516 : 35 : PyObject *pairs = PyList_New(n);
517 [ - + ]: 35 : if (pairs == NULL) {
518 : 0 : p->error = WFERR_NOMEMORY;
519 : 0 : return;
520 : : }
521 : 35 : Py_ssize_t i = 0;
522 [ + + ]: 141 : while (_PySet_NextEntry(v, &pos, &value, &hash)) {
523 : 106 : PyObject *dump = PyMarshal_WriteObjectToString(value, p->version);
524 [ - + ]: 106 : if (dump == NULL) {
525 : 0 : p->error = WFERR_UNMARSHALLABLE;
526 : 0 : Py_DECREF(pairs);
527 : 0 : return;
528 : : }
529 : 106 : PyObject *pair = PyTuple_Pack(2, dump, value);
530 : 106 : Py_DECREF(dump);
531 [ - + ]: 106 : if (pair == NULL) {
532 : 0 : p->error = WFERR_NOMEMORY;
533 : 0 : Py_DECREF(pairs);
534 : 0 : return;
535 : : }
536 : 106 : PyList_SET_ITEM(pairs, i++, pair);
537 : : }
538 : : assert(i == n);
539 [ - + ]: 35 : if (PyList_Sort(pairs)) {
540 : 0 : p->error = WFERR_NOMEMORY;
541 : 0 : Py_DECREF(pairs);
542 : 0 : return;
543 : : }
544 [ + + ]: 141 : for (Py_ssize_t i = 0; i < n; i++) {
545 : 106 : PyObject *pair = PyList_GET_ITEM(pairs, i);
546 : 106 : value = PyTuple_GET_ITEM(pair, 1);
547 : 106 : w_object(value, p);
548 : : }
549 : 35 : Py_DECREF(pairs);
550 : : }
551 [ + - ]: 7646 : else if (PyCode_Check(v)) {
552 : 7646 : PyCodeObject *co = (PyCodeObject *)v;
553 : 7646 : PyObject *co_code = _PyCode_GetCode(co);
554 [ - + ]: 7646 : if (co_code == NULL) {
555 : 0 : p->error = WFERR_NOMEMORY;
556 : 0 : return;
557 : : }
558 [ + + + - ]: 7646 : W_TYPE(TYPE_CODE, p);
559 : 7646 : w_long(co->co_argcount, p);
560 : 7646 : w_long(co->co_posonlyargcount, p);
561 : 7646 : w_long(co->co_kwonlyargcount, p);
562 : 7646 : w_long(co->co_stacksize, p);
563 : 7646 : w_long(co->co_flags, p);
564 : 7646 : w_object(co_code, p);
565 : 7646 : w_object(co->co_consts, p);
566 : 7646 : w_object(co->co_names, p);
567 : 7646 : w_object(co->co_localsplusnames, p);
568 : 7646 : w_object(co->co_localspluskinds, p);
569 : 7646 : w_object(co->co_filename, p);
570 : 7646 : w_object(co->co_name, p);
571 : 7646 : w_object(co->co_qualname, p);
572 : 7646 : w_long(co->co_firstlineno, p);
573 : 7646 : w_object(co->co_linetable, p);
574 : 7646 : w_object(co->co_exceptiontable, p);
575 : 7646 : Py_DECREF(co_code);
576 : : }
577 [ # # ]: 0 : else if (PyObject_CheckBuffer(v)) {
578 : : /* Write unknown bytes-like objects as a bytes object */
579 : : Py_buffer view;
580 [ # # ]: 0 : if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
581 [ # # # # ]: 0 : w_byte(TYPE_UNKNOWN, p);
582 : 0 : p->depth--;
583 : 0 : p->error = WFERR_UNMARSHALLABLE;
584 : 0 : return;
585 : : }
586 [ # # # # ]: 0 : W_TYPE(TYPE_STRING, p);
587 : 0 : w_pstring(view.buf, view.len, p);
588 : 0 : PyBuffer_Release(&view);
589 : : }
590 : : else {
591 [ # # # # ]: 0 : W_TYPE(TYPE_UNKNOWN, p);
592 : 0 : p->error = WFERR_UNMARSHALLABLE;
593 : : }
594 : : }
595 : :
596 : : static void
597 : 45075 : w_decref_entry(void *key)
598 : : {
599 : 45075 : PyObject *entry_key = (PyObject *)key;
600 : 45075 : Py_XDECREF(entry_key);
601 : 45075 : }
602 : :
603 : : static int
604 : 289 : w_init_refs(WFILE *wf, int version)
605 : : {
606 [ + - ]: 289 : if (version >= 3) {
607 : 289 : wf->hashtable = _Py_hashtable_new_full(_Py_hashtable_hash_ptr,
608 : : _Py_hashtable_compare_direct,
609 : : w_decref_entry, NULL, NULL);
610 [ - + ]: 289 : if (wf->hashtable == NULL) {
611 : 0 : PyErr_NoMemory();
612 : 0 : return -1;
613 : : }
614 : : }
615 : 289 : return 0;
616 : : }
617 : :
618 : : static void
619 : 289 : w_clear_refs(WFILE *wf)
620 : : {
621 [ + - ]: 289 : if (wf->hashtable != NULL) {
622 : 289 : _Py_hashtable_destroy(wf->hashtable);
623 : : }
624 : 289 : }
625 : :
626 : : /* version currently has no effect for writing ints. */
627 : : void
628 : 0 : PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
629 : : {
630 : : char buf[4];
631 : : WFILE wf;
632 : 0 : memset(&wf, 0, sizeof(wf));
633 : 0 : wf.fp = fp;
634 : 0 : wf.ptr = wf.buf = buf;
635 : 0 : wf.end = wf.ptr + sizeof(buf);
636 : 0 : wf.error = WFERR_OK;
637 : 0 : wf.version = version;
638 : 0 : w_long(x, &wf);
639 : 0 : w_flush(&wf);
640 : 0 : }
641 : :
642 : : void
643 : 0 : PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
644 : : {
645 : : char buf[BUFSIZ];
646 : : WFILE wf;
647 [ # # ]: 0 : if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
648 : 0 : return; /* caller must check PyErr_Occurred() */
649 : : }
650 : 0 : memset(&wf, 0, sizeof(wf));
651 : 0 : wf.fp = fp;
652 : 0 : wf.ptr = wf.buf = buf;
653 : 0 : wf.end = wf.ptr + sizeof(buf);
654 : 0 : wf.error = WFERR_OK;
655 : 0 : wf.version = version;
656 [ # # ]: 0 : if (w_init_refs(&wf, version)) {
657 : 0 : return; /* caller must check PyErr_Occurred() */
658 : : }
659 : 0 : w_object(x, &wf);
660 : 0 : w_clear_refs(&wf);
661 : 0 : w_flush(&wf);
662 : : }
663 : :
664 : : typedef struct {
665 : : FILE *fp;
666 : : int depth;
667 : : PyObject *readable; /* Stream-like object being read from */
668 : : const char *ptr;
669 : : const char *end;
670 : : char *buf;
671 : : Py_ssize_t buf_size;
672 : : PyObject *refs; /* a list */
673 : : } RFILE;
674 : :
675 : : static const char *
676 : 606166 : r_string(Py_ssize_t n, RFILE *p)
677 : : {
678 : 606166 : Py_ssize_t read = -1;
679 : :
680 [ + - ]: 606166 : if (p->ptr != NULL) {
681 : : /* Fast path for loads() */
682 : 606166 : const char *res = p->ptr;
683 : 606166 : Py_ssize_t left = p->end - p->ptr;
684 [ - + ]: 606166 : if (left < n) {
685 : 0 : PyErr_SetString(PyExc_EOFError,
686 : : "marshal data too short");
687 : 0 : return NULL;
688 : : }
689 : 606166 : p->ptr += n;
690 : 606166 : return res;
691 : : }
692 [ # # ]: 0 : if (p->buf == NULL) {
693 : 0 : p->buf = PyMem_Malloc(n);
694 [ # # ]: 0 : if (p->buf == NULL) {
695 : 0 : PyErr_NoMemory();
696 : 0 : return NULL;
697 : : }
698 : 0 : p->buf_size = n;
699 : : }
700 [ # # ]: 0 : else if (p->buf_size < n) {
701 : 0 : char *tmp = PyMem_Realloc(p->buf, n);
702 [ # # ]: 0 : if (tmp == NULL) {
703 : 0 : PyErr_NoMemory();
704 : 0 : return NULL;
705 : : }
706 : 0 : p->buf = tmp;
707 : 0 : p->buf_size = n;
708 : : }
709 : :
710 [ # # ]: 0 : if (!p->readable) {
711 : : assert(p->fp != NULL);
712 : 0 : read = fread(p->buf, 1, n, p->fp);
713 : : }
714 : : else {
715 : : PyObject *res, *mview;
716 : : Py_buffer buf;
717 : :
718 [ # # ]: 0 : if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
719 : 0 : return NULL;
720 : 0 : mview = PyMemoryView_FromBuffer(&buf);
721 [ # # ]: 0 : if (mview == NULL)
722 : 0 : return NULL;
723 : :
724 : 0 : res = _PyObject_CallMethod(p->readable, &_Py_ID(readinto), "N", mview);
725 [ # # ]: 0 : if (res != NULL) {
726 : 0 : read = PyNumber_AsSsize_t(res, PyExc_ValueError);
727 : 0 : Py_DECREF(res);
728 : : }
729 : : }
730 [ # # ]: 0 : if (read != n) {
731 [ # # ]: 0 : if (!PyErr_Occurred()) {
732 [ # # ]: 0 : if (read > n)
733 : 0 : PyErr_Format(PyExc_ValueError,
734 : : "read() returned too much data: "
735 : : "%zd bytes requested, %zd returned",
736 : : n, read);
737 : : else
738 : 0 : PyErr_SetString(PyExc_EOFError,
739 : : "EOF read where not expected");
740 : : }
741 : 0 : return NULL;
742 : : }
743 : 0 : return p->buf;
744 : : }
745 : :
746 : : static int
747 : 669516 : r_byte(RFILE *p)
748 : : {
749 : 669516 : int c = EOF;
750 : :
751 [ + - ]: 669516 : if (p->ptr != NULL) {
752 [ + - ]: 669516 : if (p->ptr < p->end)
753 : 669516 : c = (unsigned char) *p->ptr++;
754 : 669516 : return c;
755 : : }
756 [ # # ]: 0 : if (!p->readable) {
757 : : assert(p->fp);
758 : 0 : c = getc(p->fp);
759 : : }
760 : : else {
761 : 0 : const char *ptr = r_string(1, p);
762 [ # # ]: 0 : if (ptr != NULL)
763 : 0 : c = *(const unsigned char *) ptr;
764 : : }
765 : 0 : return c;
766 : : }
767 : :
768 : : static int
769 : 156 : r_short(RFILE *p)
770 : : {
771 : 156 : short x = -1;
772 : : const unsigned char *buffer;
773 : :
774 : 156 : buffer = (const unsigned char *) r_string(2, p);
775 [ + - ]: 156 : if (buffer != NULL) {
776 : 156 : x = buffer[0];
777 : 156 : x |= buffer[1] << 8;
778 : : /* Sign-extension, in case short greater than 16 bits */
779 : 156 : x |= -(x & 0x8000);
780 : : }
781 : 156 : return x;
782 : : }
783 : :
784 : : static long
785 : 418669 : r_long(RFILE *p)
786 : : {
787 : 418669 : long x = -1;
788 : : const unsigned char *buffer;
789 : :
790 : 418669 : buffer = (const unsigned char *) r_string(4, p);
791 [ + - ]: 418669 : if (buffer != NULL) {
792 : 418669 : x = buffer[0];
793 : 418669 : x |= (long)buffer[1] << 8;
794 : 418669 : x |= (long)buffer[2] << 16;
795 : 418669 : x |= (long)buffer[3] << 24;
796 : : #if SIZEOF_LONG > 4
797 : : /* Sign extension for 64-bit machines */
798 : 418669 : x |= -(x & 0x80000000L);
799 : : #endif
800 : : }
801 : 418669 : return x;
802 : : }
803 : :
804 : : /* r_long64 deals with the TYPE_INT64 code. */
805 : : static PyObject *
806 : 0 : r_long64(RFILE *p)
807 : : {
808 : 0 : const unsigned char *buffer = (const unsigned char *) r_string(8, p);
809 [ # # ]: 0 : if (buffer == NULL) {
810 : 0 : return NULL;
811 : : }
812 : 0 : return _PyLong_FromByteArray(buffer, 8,
813 : : 1 /* little endian */,
814 : : 1 /* signed */);
815 : : }
816 : :
817 : : static PyObject *
818 : 50 : r_PyLong(RFILE *p)
819 : : {
820 : : PyLongObject *ob;
821 : : long n, size, i;
822 : : int j, md, shorts_in_top_digit;
823 : : digit d;
824 : :
825 : 50 : n = r_long(p);
826 [ - + ]: 50 : if (PyErr_Occurred())
827 : 0 : return NULL;
828 [ - + ]: 50 : if (n == 0)
829 : 0 : return (PyObject *)_PyLong_New(0);
830 [ + - - + ]: 50 : if (n < -SIZE32_MAX || n > SIZE32_MAX) {
831 : 0 : PyErr_SetString(PyExc_ValueError,
832 : : "bad marshal data (long size out of range)");
833 : 0 : return NULL;
834 : : }
835 : :
836 : 50 : size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
837 : 50 : shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
838 : 50 : ob = _PyLong_New(size);
839 [ - + ]: 50 : if (ob == NULL)
840 : 0 : return NULL;
841 : :
842 [ - + ]: 50 : Py_SET_SIZE(ob, n > 0 ? size : -size);
843 : :
844 [ + + ]: 103 : for (i = 0; i < size-1; i++) {
845 : 53 : d = 0;
846 [ + + ]: 159 : for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
847 : 106 : md = r_short(p);
848 [ - + ]: 106 : if (PyErr_Occurred()) {
849 : 0 : Py_DECREF(ob);
850 : 0 : return NULL;
851 : : }
852 [ + - - + ]: 106 : if (md < 0 || md > PyLong_MARSHAL_BASE)
853 : 0 : goto bad_digit;
854 : 106 : d += (digit)md << j*PyLong_MARSHAL_SHIFT;
855 : : }
856 : 53 : ob->long_value.ob_digit[i] = d;
857 : : }
858 : :
859 : 50 : d = 0;
860 [ + + ]: 100 : for (j=0; j < shorts_in_top_digit; j++) {
861 : 50 : md = r_short(p);
862 [ - + ]: 50 : if (PyErr_Occurred()) {
863 : 0 : Py_DECREF(ob);
864 : 0 : return NULL;
865 : : }
866 [ + - - + ]: 50 : if (md < 0 || md > PyLong_MARSHAL_BASE)
867 : 0 : goto bad_digit;
868 : : /* topmost marshal digit should be nonzero */
869 [ - + - - ]: 50 : if (md == 0 && j == shorts_in_top_digit - 1) {
870 : 0 : Py_DECREF(ob);
871 : 0 : PyErr_SetString(PyExc_ValueError,
872 : : "bad marshal data (unnormalized long data)");
873 : 0 : return NULL;
874 : : }
875 : 50 : d += (digit)md << j*PyLong_MARSHAL_SHIFT;
876 : : }
877 [ - + ]: 50 : if (PyErr_Occurred()) {
878 : 0 : Py_DECREF(ob);
879 : 0 : return NULL;
880 : : }
881 : : /* top digit should be nonzero, else the resulting PyLong won't be
882 : : normalized */
883 : 50 : ob->long_value.ob_digit[size-1] = d;
884 : 50 : return (PyObject *)ob;
885 : 0 : bad_digit:
886 : 0 : Py_DECREF(ob);
887 : 0 : PyErr_SetString(PyExc_ValueError,
888 : : "bad marshal data (digit out of range in long)");
889 : 0 : return NULL;
890 : : }
891 : :
892 : : static double
893 : 4 : r_float_bin(RFILE *p)
894 : : {
895 : 4 : const char *buf = r_string(8, p);
896 [ - + ]: 4 : if (buf == NULL)
897 : 0 : return -1;
898 : 4 : return PyFloat_Unpack8(buf, 1);
899 : : }
900 : :
901 : : /* Issue #33720: Disable inlining for reducing the C stack consumption
902 : : on PGO builds. */
903 : : Py_NO_INLINE static double
904 : 0 : r_float_str(RFILE *p)
905 : : {
906 : : int n;
907 : : char buf[256];
908 : : const char *ptr;
909 : 0 : n = r_byte(p);
910 [ # # ]: 0 : if (n == EOF) {
911 : 0 : PyErr_SetString(PyExc_EOFError,
912 : : "EOF read where object expected");
913 : 0 : return -1;
914 : : }
915 : 0 : ptr = r_string(n, p);
916 [ # # ]: 0 : if (ptr == NULL) {
917 : 0 : return -1;
918 : : }
919 : 0 : memcpy(buf, ptr, n);
920 : 0 : buf[n] = '\0';
921 : 0 : return PyOS_string_to_double(buf, NULL, NULL);
922 : : }
923 : :
924 : : /* allocate the reflist index for a new object. Return -1 on failure */
925 : : static Py_ssize_t
926 : 21176 : r_ref_reserve(int flag, RFILE *p)
927 : : {
928 [ + + ]: 21176 : if (flag) { /* currently only FLAG_REF is defined */
929 : 386 : Py_ssize_t idx = PyList_GET_SIZE(p->refs);
930 [ - + ]: 386 : if (idx >= 0x7ffffffe) {
931 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
932 : 0 : return -1;
933 : : }
934 [ - + ]: 386 : if (PyList_Append(p->refs, Py_None) < 0)
935 : 0 : return -1;
936 : 386 : return idx;
937 : : } else
938 : 20790 : return 0;
939 : : }
940 : :
941 : : /* insert the new object 'o' to the reflist at previously
942 : : * allocated index 'idx'.
943 : : * 'o' can be NULL, in which case nothing is done.
944 : : * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
945 : : * if 'o' was non-NULL, and the function fails, 'o' is released and
946 : : * NULL returned. This simplifies error checking at the call site since
947 : : * a single test for NULL for the function result is enough.
948 : : */
949 : : static PyObject *
950 : 21176 : r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
951 : : {
952 [ + - + + ]: 21176 : if (o != NULL && flag) { /* currently only FLAG_REF is defined */
953 : 386 : PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
954 : 386 : PyList_SET_ITEM(p->refs, idx, Py_NewRef(o));
955 : 386 : Py_DECREF(tmp);
956 : : }
957 : 21176 : return o;
958 : : }
959 : :
960 : : /* combination of both above, used when an object can be
961 : : * created whenever it is seen in the file, as opposed to
962 : : * after having loaded its sub-objects.
963 : : */
964 : : static PyObject *
965 : 124879 : r_ref(PyObject *o, int flag, RFILE *p)
966 : : {
967 : : assert(flag & FLAG_REF);
968 [ - + ]: 124879 : if (o == NULL)
969 : 0 : return NULL;
970 [ - + ]: 124879 : if (PyList_Append(p->refs, o) < 0) {
971 : 0 : Py_DECREF(o); /* release the new object */
972 : 0 : return NULL;
973 : : }
974 : 124879 : return o;
975 : : }
976 : :
977 : : static PyObject *
978 : 498821 : r_object(RFILE *p)
979 : : {
980 : : /* NULL is a valid return value, it does not necessarily means that
981 : : an exception is set. */
982 : : PyObject *v, *v2;
983 : 498821 : Py_ssize_t idx = 0;
984 : : long i, n;
985 : 498821 : int type, code = r_byte(p);
986 : 498821 : int flag, is_interned = 0;
987 : 498821 : PyObject *retval = NULL;
988 : :
989 [ - + ]: 498821 : if (code == EOF) {
990 : 0 : PyErr_SetString(PyExc_EOFError,
991 : : "EOF read where object expected");
992 : 0 : return NULL;
993 : : }
994 : :
995 : 498821 : p->depth++;
996 : :
997 [ - + ]: 498821 : if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
998 : 0 : p->depth--;
999 : 0 : PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
1000 : 0 : return NULL;
1001 : : }
1002 : :
1003 : 498821 : flag = code & FLAG_REF;
1004 : 498821 : type = code & ~FLAG_REF;
1005 : :
1006 : : #define R_REF(O) do{\
1007 : : if (flag) \
1008 : : O = r_ref(O, flag, p);\
1009 : : } while (0)
1010 : :
1011 [ - + - + : 498821 : switch (type) {
+ + + - +
- + - - +
- + + + -
+ + + - -
+ + + - ]
1012 : :
1013 : 0 : case TYPE_NULL:
1014 : 0 : break;
1015 : :
1016 : 11875 : case TYPE_NONE:
1017 : 11875 : retval = Py_NewRef(Py_None);
1018 : 11875 : break;
1019 : :
1020 : 0 : case TYPE_STOPITER:
1021 : 0 : retval = Py_NewRef(PyExc_StopIteration);
1022 : 0 : break;
1023 : :
1024 : 48 : case TYPE_ELLIPSIS:
1025 : 48 : retval = Py_NewRef(Py_Ellipsis);
1026 : 48 : break;
1027 : :
1028 : 1591 : case TYPE_FALSE:
1029 : 1591 : retval = Py_NewRef(Py_False);
1030 : 1591 : break;
1031 : :
1032 : 1414 : case TYPE_TRUE:
1033 : 1414 : retval = Py_NewRef(Py_True);
1034 : 1414 : break;
1035 : :
1036 : 4621 : case TYPE_INT:
1037 : 4621 : n = r_long(p);
1038 [ + - ]: 4621 : retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
1039 [ + + ]: 4621 : R_REF(retval);
1040 : 4621 : break;
1041 : :
1042 : 0 : case TYPE_INT64:
1043 : 0 : retval = r_long64(p);
1044 [ # # ]: 0 : R_REF(retval);
1045 : 0 : break;
1046 : :
1047 : 50 : case TYPE_LONG:
1048 : 50 : retval = r_PyLong(p);
1049 [ + + ]: 50 : R_REF(retval);
1050 : 50 : break;
1051 : :
1052 : 0 : case TYPE_FLOAT:
1053 : : {
1054 : 0 : double x = r_float_str(p);
1055 [ # # # # ]: 0 : if (x == -1.0 && PyErr_Occurred())
1056 : 0 : break;
1057 : 0 : retval = PyFloat_FromDouble(x);
1058 [ # # ]: 0 : R_REF(retval);
1059 : 0 : break;
1060 : : }
1061 : :
1062 : 4 : case TYPE_BINARY_FLOAT:
1063 : : {
1064 : 4 : double x = r_float_bin(p);
1065 [ - + - - ]: 4 : if (x == -1.0 && PyErr_Occurred())
1066 : 0 : break;
1067 : 4 : retval = PyFloat_FromDouble(x);
1068 [ - + ]: 4 : R_REF(retval);
1069 : 4 : break;
1070 : : }
1071 : :
1072 : 0 : case TYPE_COMPLEX:
1073 : : {
1074 : : Py_complex c;
1075 : 0 : c.real = r_float_str(p);
1076 [ # # # # ]: 0 : if (c.real == -1.0 && PyErr_Occurred())
1077 : 0 : break;
1078 : 0 : c.imag = r_float_str(p);
1079 [ # # # # ]: 0 : if (c.imag == -1.0 && PyErr_Occurred())
1080 : 0 : break;
1081 : 0 : retval = PyComplex_FromCComplex(c);
1082 [ # # ]: 0 : R_REF(retval);
1083 : 0 : break;
1084 : : }
1085 : :
1086 : 0 : case TYPE_BINARY_COMPLEX:
1087 : : {
1088 : : Py_complex c;
1089 : 0 : c.real = r_float_bin(p);
1090 [ # # # # ]: 0 : if (c.real == -1.0 && PyErr_Occurred())
1091 : 0 : break;
1092 : 0 : c.imag = r_float_bin(p);
1093 [ # # # # ]: 0 : if (c.imag == -1.0 && PyErr_Occurred())
1094 : 0 : break;
1095 : 0 : retval = PyComplex_FromCComplex(c);
1096 [ # # ]: 0 : R_REF(retval);
1097 : 0 : break;
1098 : : }
1099 : :
1100 : 63221 : case TYPE_STRING:
1101 : : {
1102 : : const char *ptr;
1103 : 63221 : n = r_long(p);
1104 [ - + ]: 63221 : if (PyErr_Occurred())
1105 : 0 : break;
1106 [ + - - + ]: 63221 : if (n < 0 || n > SIZE32_MAX) {
1107 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
1108 : 0 : break;
1109 : : }
1110 : 63221 : v = PyBytes_FromStringAndSize((char *)NULL, n);
1111 [ - + ]: 63221 : if (v == NULL)
1112 : 0 : break;
1113 : 63221 : ptr = r_string(n, p);
1114 [ - + ]: 63221 : if (ptr == NULL) {
1115 : 0 : Py_DECREF(v);
1116 : 0 : break;
1117 : : }
1118 : 63221 : memcpy(PyBytes_AS_STRING(v), ptr, n);
1119 : 63221 : retval = v;
1120 [ + + ]: 63221 : R_REF(retval);
1121 : 63221 : break;
1122 : : }
1123 : :
1124 : 0 : case TYPE_ASCII_INTERNED:
1125 : 0 : is_interned = 1;
1126 : : /* fall through */
1127 : 2176 : case TYPE_ASCII:
1128 : 2176 : n = r_long(p);
1129 [ - + ]: 2176 : if (PyErr_Occurred())
1130 : 0 : break;
1131 [ + - - + ]: 2176 : if (n < 0 || n > SIZE32_MAX) {
1132 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
1133 : 0 : break;
1134 : : }
1135 : 2176 : goto _read_ascii;
1136 : :
1137 : 88749 : case TYPE_SHORT_ASCII_INTERNED:
1138 : 88749 : is_interned = 1;
1139 : : /* fall through */
1140 : 121914 : case TYPE_SHORT_ASCII:
1141 : 121914 : n = r_byte(p);
1142 [ - + ]: 121914 : if (n == EOF) {
1143 : 0 : PyErr_SetString(PyExc_EOFError,
1144 : : "EOF read where object expected");
1145 : 0 : break;
1146 : : }
1147 : 121914 : _read_ascii:
1148 : : {
1149 : : const char *ptr;
1150 : 124090 : ptr = r_string(n, p);
1151 [ - + ]: 124090 : if (ptr == NULL)
1152 : 0 : break;
1153 : 124090 : v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
1154 [ - + ]: 124090 : if (v == NULL)
1155 : 0 : break;
1156 [ + + ]: 124090 : if (is_interned)
1157 : 88749 : PyUnicode_InternInPlace(&v);
1158 : 124090 : retval = v;
1159 [ + + ]: 124090 : R_REF(retval);
1160 : 124090 : break;
1161 : : }
1162 : :
1163 : 0 : case TYPE_INTERNED:
1164 : 0 : is_interned = 1;
1165 : : /* fall through */
1166 : 26 : case TYPE_UNICODE:
1167 : : {
1168 : : const char *buffer;
1169 : :
1170 : 26 : n = r_long(p);
1171 [ - + ]: 26 : if (PyErr_Occurred())
1172 : 0 : break;
1173 [ + - - + ]: 26 : if (n < 0 || n > SIZE32_MAX) {
1174 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
1175 : 0 : break;
1176 : : }
1177 [ + - ]: 26 : if (n != 0) {
1178 : 26 : buffer = r_string(n, p);
1179 [ - + ]: 26 : if (buffer == NULL)
1180 : 0 : break;
1181 : 26 : v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
1182 : : }
1183 : : else {
1184 : 0 : v = PyUnicode_New(0, 0);
1185 : : }
1186 [ - + ]: 26 : if (v == NULL)
1187 : 0 : break;
1188 [ - + ]: 26 : if (is_interned)
1189 : 0 : PyUnicode_InternInPlace(&v);
1190 : 26 : retval = v;
1191 [ - + ]: 26 : R_REF(retval);
1192 : 26 : break;
1193 : : }
1194 : :
1195 : 48781 : case TYPE_SMALL_TUPLE:
1196 : 48781 : n = (unsigned char) r_byte(p);
1197 [ - + ]: 48781 : if (PyErr_Occurred())
1198 : 0 : break;
1199 : 48781 : goto _read_tuple;
1200 : 29 : case TYPE_TUPLE:
1201 : 29 : n = r_long(p);
1202 [ - + ]: 29 : if (PyErr_Occurred())
1203 : 0 : break;
1204 [ + - - + ]: 29 : if (n < 0 || n > SIZE32_MAX) {
1205 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
1206 : 0 : break;
1207 : : }
1208 : 29 : _read_tuple:
1209 : 48810 : v = PyTuple_New(n);
1210 [ + + ]: 48810 : R_REF(v);
1211 [ - + ]: 48810 : if (v == NULL)
1212 : 0 : break;
1213 : :
1214 [ + + ]: 335994 : for (i = 0; i < n; i++) {
1215 : 287184 : v2 = r_object(p);
1216 [ - + ]: 287184 : if ( v2 == NULL ) {
1217 [ # # ]: 0 : if (!PyErr_Occurred())
1218 : 0 : PyErr_SetString(PyExc_TypeError,
1219 : : "NULL object in marshal data for tuple");
1220 : 0 : Py_SETREF(v, NULL);
1221 : 0 : break;
1222 : : }
1223 : 287184 : PyTuple_SET_ITEM(v, i, v2);
1224 : : }
1225 : 48810 : retval = v;
1226 : 48810 : break;
1227 : :
1228 : 0 : case TYPE_LIST:
1229 : 0 : n = r_long(p);
1230 [ # # ]: 0 : if (PyErr_Occurred())
1231 : 0 : break;
1232 [ # # # # ]: 0 : if (n < 0 || n > SIZE32_MAX) {
1233 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
1234 : 0 : break;
1235 : : }
1236 : 0 : v = PyList_New(n);
1237 [ # # ]: 0 : R_REF(v);
1238 [ # # ]: 0 : if (v == NULL)
1239 : 0 : break;
1240 [ # # ]: 0 : for (i = 0; i < n; i++) {
1241 : 0 : v2 = r_object(p);
1242 [ # # ]: 0 : if ( v2 == NULL ) {
1243 [ # # ]: 0 : if (!PyErr_Occurred())
1244 : 0 : PyErr_SetString(PyExc_TypeError,
1245 : : "NULL object in marshal data for list");
1246 : 0 : Py_SETREF(v, NULL);
1247 : 0 : break;
1248 : : }
1249 : 0 : PyList_SET_ITEM(v, i, v2);
1250 : : }
1251 : 0 : retval = v;
1252 : 0 : break;
1253 : :
1254 : 0 : case TYPE_DICT:
1255 : 0 : v = PyDict_New();
1256 [ # # ]: 0 : R_REF(v);
1257 [ # # ]: 0 : if (v == NULL)
1258 : 0 : break;
1259 : 0 : for (;;) {
1260 : : PyObject *key, *val;
1261 : 0 : key = r_object(p);
1262 [ # # ]: 0 : if (key == NULL)
1263 : 0 : break;
1264 : 0 : val = r_object(p);
1265 [ # # ]: 0 : if (val == NULL) {
1266 : 0 : Py_DECREF(key);
1267 : 0 : break;
1268 : : }
1269 [ # # ]: 0 : if (PyDict_SetItem(v, key, val) < 0) {
1270 : 0 : Py_DECREF(key);
1271 : 0 : Py_DECREF(val);
1272 : 0 : break;
1273 : : }
1274 : 0 : Py_DECREF(key);
1275 : 0 : Py_DECREF(val);
1276 : : }
1277 [ # # ]: 0 : if (PyErr_Occurred()) {
1278 : 0 : Py_SETREF(v, NULL);
1279 : : }
1280 : 0 : retval = v;
1281 : 0 : break;
1282 : :
1283 : 81 : case TYPE_SET:
1284 : : case TYPE_FROZENSET:
1285 : 81 : n = r_long(p);
1286 [ - + ]: 81 : if (PyErr_Occurred())
1287 : 0 : break;
1288 [ + - - + ]: 81 : if (n < 0 || n > SIZE32_MAX) {
1289 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
1290 : 0 : break;
1291 : : }
1292 : :
1293 [ - + - - ]: 81 : if (n == 0 && type == TYPE_FROZENSET) {
1294 : : /* call frozenset() to get the empty frozenset singleton */
1295 : 0 : v = _PyObject_CallNoArgs((PyObject*)&PyFrozenSet_Type);
1296 [ # # ]: 0 : if (v == NULL)
1297 : 0 : break;
1298 [ # # ]: 0 : R_REF(v);
1299 : 0 : retval = v;
1300 : : }
1301 : : else {
1302 [ - + ]: 81 : v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1303 [ - + ]: 81 : if (type == TYPE_SET) {
1304 [ # # ]: 0 : R_REF(v);
1305 : : } else {
1306 : : /* must use delayed registration of frozensets because they must
1307 : : * be init with a refcount of 1
1308 : : */
1309 : 81 : idx = r_ref_reserve(flag, p);
1310 [ - + ]: 81 : if (idx < 0)
1311 [ # # ]: 0 : Py_CLEAR(v); /* signal error */
1312 : : }
1313 [ - + ]: 81 : if (v == NULL)
1314 : 0 : break;
1315 : :
1316 [ + + ]: 294 : for (i = 0; i < n; i++) {
1317 : 213 : v2 = r_object(p);
1318 [ - + ]: 213 : if ( v2 == NULL ) {
1319 [ # # ]: 0 : if (!PyErr_Occurred())
1320 : 0 : PyErr_SetString(PyExc_TypeError,
1321 : : "NULL object in marshal data for set");
1322 : 0 : Py_SETREF(v, NULL);
1323 : 0 : break;
1324 : : }
1325 [ - + ]: 213 : if (PySet_Add(v, v2) == -1) {
1326 : 0 : Py_DECREF(v);
1327 : 0 : Py_DECREF(v2);
1328 : 0 : v = NULL;
1329 : 0 : break;
1330 : : }
1331 : 213 : Py_DECREF(v2);
1332 : : }
1333 [ + - ]: 81 : if (type != TYPE_SET)
1334 : 81 : v = r_ref_insert(v, idx, flag, p);
1335 : 81 : retval = v;
1336 : : }
1337 : 81 : break;
1338 : :
1339 : 21095 : case TYPE_CODE:
1340 : : {
1341 : : int argcount;
1342 : : int posonlyargcount;
1343 : : int kwonlyargcount;
1344 : : int stacksize;
1345 : : int flags;
1346 : 21095 : PyObject *code = NULL;
1347 : 21095 : PyObject *consts = NULL;
1348 : 21095 : PyObject *names = NULL;
1349 : 21095 : PyObject *localsplusnames = NULL;
1350 : 21095 : PyObject *localspluskinds = NULL;
1351 : 21095 : PyObject *filename = NULL;
1352 : 21095 : PyObject *name = NULL;
1353 : 21095 : PyObject *qualname = NULL;
1354 : : int firstlineno;
1355 : 21095 : PyObject* linetable = NULL;
1356 : 21095 : PyObject *exceptiontable = NULL;
1357 : :
1358 : 21095 : idx = r_ref_reserve(flag, p);
1359 [ - + ]: 21095 : if (idx < 0)
1360 : 0 : break;
1361 : :
1362 : 21095 : v = NULL;
1363 : :
1364 : : /* XXX ignore long->int overflows for now */
1365 : 21095 : argcount = (int)r_long(p);
1366 [ - + ]: 21095 : if (PyErr_Occurred())
1367 : 0 : goto code_error;
1368 : 21095 : posonlyargcount = (int)r_long(p);
1369 [ - + ]: 21095 : if (PyErr_Occurred()) {
1370 : 0 : goto code_error;
1371 : : }
1372 : 21095 : kwonlyargcount = (int)r_long(p);
1373 [ - + ]: 21095 : if (PyErr_Occurred())
1374 : 0 : goto code_error;
1375 : 21095 : stacksize = (int)r_long(p);
1376 [ - + ]: 21095 : if (PyErr_Occurred())
1377 : 0 : goto code_error;
1378 : 21095 : flags = (int)r_long(p);
1379 [ - + ]: 21095 : if (PyErr_Occurred())
1380 : 0 : goto code_error;
1381 : 21095 : code = r_object(p);
1382 [ - + ]: 21095 : if (code == NULL)
1383 : 0 : goto code_error;
1384 : 21095 : consts = r_object(p);
1385 [ - + ]: 21095 : if (consts == NULL)
1386 : 0 : goto code_error;
1387 : 21095 : names = r_object(p);
1388 [ - + ]: 21095 : if (names == NULL)
1389 : 0 : goto code_error;
1390 : 21095 : localsplusnames = r_object(p);
1391 [ - + ]: 21095 : if (localsplusnames == NULL)
1392 : 0 : goto code_error;
1393 : 21095 : localspluskinds = r_object(p);
1394 [ - + ]: 21095 : if (localspluskinds == NULL)
1395 : 0 : goto code_error;
1396 : 21095 : filename = r_object(p);
1397 [ - + ]: 21095 : if (filename == NULL)
1398 : 0 : goto code_error;
1399 : 21095 : name = r_object(p);
1400 [ - + ]: 21095 : if (name == NULL)
1401 : 0 : goto code_error;
1402 : 21095 : qualname = r_object(p);
1403 [ - + ]: 21095 : if (qualname == NULL)
1404 : 0 : goto code_error;
1405 : 21095 : firstlineno = (int)r_long(p);
1406 [ - + - - ]: 21095 : if (firstlineno == -1 && PyErr_Occurred())
1407 : 0 : break;
1408 : 21095 : linetable = r_object(p);
1409 [ - + ]: 21095 : if (linetable == NULL)
1410 : 0 : goto code_error;
1411 : 21095 : exceptiontable = r_object(p);
1412 [ - + ]: 21095 : if (exceptiontable == NULL)
1413 : 0 : goto code_error;
1414 : :
1415 : 21095 : struct _PyCodeConstructor con = {
1416 : : .filename = filename,
1417 : : .name = name,
1418 : : .qualname = qualname,
1419 : : .flags = flags,
1420 : :
1421 : : .code = code,
1422 : : .firstlineno = firstlineno,
1423 : : .linetable = linetable,
1424 : :
1425 : : .consts = consts,
1426 : : .names = names,
1427 : :
1428 : : .localsplusnames = localsplusnames,
1429 : : .localspluskinds = localspluskinds,
1430 : :
1431 : : .argcount = argcount,
1432 : : .posonlyargcount = posonlyargcount,
1433 : : .kwonlyargcount = kwonlyargcount,
1434 : :
1435 : : .stacksize = stacksize,
1436 : :
1437 : : .exceptiontable = exceptiontable,
1438 : : };
1439 : :
1440 [ - + ]: 21095 : if (_PyCode_Validate(&con) < 0) {
1441 : 0 : goto code_error;
1442 : : }
1443 : :
1444 : 21095 : v = (PyObject *)_PyCode_New(&con);
1445 [ - + ]: 21095 : if (v == NULL) {
1446 : 0 : goto code_error;
1447 : : }
1448 : :
1449 : 21095 : v = r_ref_insert(v, idx, flag, p);
1450 : :
1451 : 21095 : code_error:
1452 : 21095 : Py_XDECREF(code);
1453 : 21095 : Py_XDECREF(consts);
1454 : 21095 : Py_XDECREF(names);
1455 : 21095 : Py_XDECREF(localsplusnames);
1456 : 21095 : Py_XDECREF(localspluskinds);
1457 : 21095 : Py_XDECREF(filename);
1458 : 21095 : Py_XDECREF(name);
1459 : 21095 : Py_XDECREF(qualname);
1460 : 21095 : Py_XDECREF(linetable);
1461 : 21095 : Py_XDECREF(exceptiontable);
1462 : : }
1463 : 21095 : retval = v;
1464 : 21095 : break;
1465 : :
1466 : 221895 : case TYPE_REF:
1467 : 221895 : n = r_long(p);
1468 [ + - - + ]: 221895 : if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
1469 [ # # # # ]: 0 : if (n == -1 && PyErr_Occurred())
1470 : 0 : break;
1471 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
1472 : 0 : break;
1473 : : }
1474 : 221895 : v = PyList_GET_ITEM(p->refs, n);
1475 [ - + ]: 221895 : if (v == Py_None) {
1476 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
1477 : 0 : break;
1478 : : }
1479 : 221895 : retval = Py_NewRef(v);
1480 : 221895 : break;
1481 : :
1482 : 0 : default:
1483 : : /* Bogus data got written, which isn't ideal.
1484 : : This will let you keep working and recover. */
1485 : 0 : PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
1486 : 0 : break;
1487 : :
1488 : : }
1489 : 498821 : p->depth--;
1490 : 498821 : return retval;
1491 : : }
1492 : :
1493 : : static PyObject *
1494 : 474 : read_object(RFILE *p)
1495 : : {
1496 : : PyObject *v;
1497 [ - + ]: 474 : if (PyErr_Occurred()) {
1498 : 0 : fprintf(stderr, "XXX readobject called with exception set\n");
1499 : 0 : return NULL;
1500 : : }
1501 [ + - + - ]: 474 : if (p->ptr && p->end) {
1502 [ - + ]: 474 : if (PySys_Audit("marshal.loads", "y#", p->ptr, (Py_ssize_t)(p->end - p->ptr)) < 0) {
1503 : 0 : return NULL;
1504 : : }
1505 [ # # # # ]: 0 : } else if (p->fp || p->readable) {
1506 [ # # ]: 0 : if (PySys_Audit("marshal.load", NULL) < 0) {
1507 : 0 : return NULL;
1508 : : }
1509 : : }
1510 : 474 : v = r_object(p);
1511 [ - + - - ]: 474 : if (v == NULL && !PyErr_Occurred())
1512 : 0 : PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1513 : 474 : return v;
1514 : : }
1515 : :
1516 : : int
1517 : 0 : PyMarshal_ReadShortFromFile(FILE *fp)
1518 : : {
1519 : : RFILE rf;
1520 : : int res;
1521 : : assert(fp);
1522 : 0 : rf.readable = NULL;
1523 : 0 : rf.fp = fp;
1524 : 0 : rf.end = rf.ptr = NULL;
1525 : 0 : rf.buf = NULL;
1526 : 0 : res = r_short(&rf);
1527 [ # # ]: 0 : if (rf.buf != NULL)
1528 : 0 : PyMem_Free(rf.buf);
1529 : 0 : return res;
1530 : : }
1531 : :
1532 : : long
1533 : 0 : PyMarshal_ReadLongFromFile(FILE *fp)
1534 : : {
1535 : : RFILE rf;
1536 : : long res;
1537 : 0 : rf.fp = fp;
1538 : 0 : rf.readable = NULL;
1539 : 0 : rf.ptr = rf.end = NULL;
1540 : 0 : rf.buf = NULL;
1541 : 0 : res = r_long(&rf);
1542 [ # # ]: 0 : if (rf.buf != NULL)
1543 : 0 : PyMem_Free(rf.buf);
1544 : 0 : return res;
1545 : : }
1546 : :
1547 : : /* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
1548 : : static off_t
1549 : 0 : getfilesize(FILE *fp)
1550 : : {
1551 : : struct _Py_stat_struct st;
1552 [ # # ]: 0 : if (_Py_fstat_noraise(fileno(fp), &st) != 0)
1553 : 0 : return -1;
1554 : : #if SIZEOF_OFF_T == 4
1555 : : else if (st.st_size >= INT_MAX)
1556 : : return (off_t)INT_MAX;
1557 : : #endif
1558 : : else
1559 : 0 : return (off_t)st.st_size;
1560 : : }
1561 : :
1562 : : /* If we can get the size of the file up-front, and it's reasonably small,
1563 : : * read it in one gulp and delegate to ...FromString() instead. Much quicker
1564 : : * than reading a byte at a time from file; speeds .pyc imports.
1565 : : * CAUTION: since this may read the entire remainder of the file, don't
1566 : : * call it unless you know you're done with the file.
1567 : : */
1568 : : PyObject *
1569 : 0 : PyMarshal_ReadLastObjectFromFile(FILE *fp)
1570 : : {
1571 : : /* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
1572 : : #define REASONABLE_FILE_LIMIT (1L << 18)
1573 : : off_t filesize;
1574 : 0 : filesize = getfilesize(fp);
1575 [ # # # # ]: 0 : if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1576 : 0 : char* pBuf = (char *)PyMem_Malloc(filesize);
1577 [ # # ]: 0 : if (pBuf != NULL) {
1578 : 0 : size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1579 : 0 : PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
1580 : 0 : PyMem_Free(pBuf);
1581 : 0 : return v;
1582 : : }
1583 : :
1584 : : }
1585 : : /* We don't have fstat, or we do but the file is larger than
1586 : : * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1587 : : */
1588 : 0 : return PyMarshal_ReadObjectFromFile(fp);
1589 : :
1590 : : #undef REASONABLE_FILE_LIMIT
1591 : : }
1592 : :
1593 : : PyObject *
1594 : 0 : PyMarshal_ReadObjectFromFile(FILE *fp)
1595 : : {
1596 : : RFILE rf;
1597 : : PyObject *result;
1598 : 0 : rf.fp = fp;
1599 : 0 : rf.readable = NULL;
1600 : 0 : rf.depth = 0;
1601 : 0 : rf.ptr = rf.end = NULL;
1602 : 0 : rf.buf = NULL;
1603 : 0 : rf.refs = PyList_New(0);
1604 [ # # ]: 0 : if (rf.refs == NULL)
1605 : 0 : return NULL;
1606 : 0 : result = read_object(&rf);
1607 : 0 : Py_DECREF(rf.refs);
1608 [ # # ]: 0 : if (rf.buf != NULL)
1609 : 0 : PyMem_Free(rf.buf);
1610 : 0 : return result;
1611 : : }
1612 : :
1613 : : PyObject *
1614 : 88 : PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
1615 : : {
1616 : : RFILE rf;
1617 : : PyObject *result;
1618 : 88 : rf.fp = NULL;
1619 : 88 : rf.readable = NULL;
1620 : 88 : rf.ptr = str;
1621 : 88 : rf.end = str + len;
1622 : 88 : rf.buf = NULL;
1623 : 88 : rf.depth = 0;
1624 : 88 : rf.refs = PyList_New(0);
1625 [ - + ]: 88 : if (rf.refs == NULL)
1626 : 0 : return NULL;
1627 : 88 : result = read_object(&rf);
1628 : 88 : Py_DECREF(rf.refs);
1629 [ - + ]: 88 : if (rf.buf != NULL)
1630 : 0 : PyMem_Free(rf.buf);
1631 : 88 : return result;
1632 : : }
1633 : :
1634 : : PyObject *
1635 : 289 : PyMarshal_WriteObjectToString(PyObject *x, int version)
1636 : : {
1637 : : WFILE wf;
1638 : :
1639 [ - + ]: 289 : if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
1640 : 0 : return NULL;
1641 : : }
1642 : 289 : memset(&wf, 0, sizeof(wf));
1643 : 289 : wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1644 [ - + ]: 289 : if (wf.str == NULL)
1645 : 0 : return NULL;
1646 : 289 : wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
1647 : 289 : wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
1648 : 289 : wf.error = WFERR_OK;
1649 : 289 : wf.version = version;
1650 [ - + ]: 289 : if (w_init_refs(&wf, version)) {
1651 : 0 : Py_DECREF(wf.str);
1652 : 0 : return NULL;
1653 : : }
1654 : 289 : w_object(x, &wf);
1655 : 289 : w_clear_refs(&wf);
1656 [ + - ]: 289 : if (wf.str != NULL) {
1657 : 289 : const char *base = PyBytes_AS_STRING(wf.str);
1658 [ - + ]: 289 : if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1659 : 0 : return NULL;
1660 : : }
1661 [ - + ]: 289 : if (wf.error != WFERR_OK) {
1662 : 0 : Py_XDECREF(wf.str);
1663 [ # # ]: 0 : if (wf.error == WFERR_NOMEMORY)
1664 : 0 : PyErr_NoMemory();
1665 : : else
1666 : 0 : PyErr_SetString(PyExc_ValueError,
1667 [ # # ]: 0 : (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1668 : : :"object too deeply nested to marshal");
1669 : 0 : return NULL;
1670 : : }
1671 : 289 : return wf.str;
1672 : : }
1673 : :
1674 : : /* And an interface for Python programs... */
1675 : : /*[clinic input]
1676 : : marshal.dump
1677 : :
1678 : : value: object
1679 : : Must be a supported type.
1680 : : file: object
1681 : : Must be a writeable binary file.
1682 : : version: int(c_default="Py_MARSHAL_VERSION") = version
1683 : : Indicates the data format that dump should use.
1684 : : /
1685 : :
1686 : : Write the value on the open file.
1687 : :
1688 : : If the value has (or contains an object that has) an unsupported type, a
1689 : : ValueError exception is raised - but garbage data will also be written
1690 : : to the file. The object will not be properly read back by load().
1691 : : [clinic start generated code]*/
1692 : :
1693 : : static PyObject *
1694 : 0 : marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
1695 : : int version)
1696 : : /*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
1697 : : {
1698 : : /* XXX Quick hack -- need to do this differently */
1699 : : PyObject *s;
1700 : : PyObject *res;
1701 : :
1702 : 0 : s = PyMarshal_WriteObjectToString(value, version);
1703 [ # # ]: 0 : if (s == NULL)
1704 : 0 : return NULL;
1705 : 0 : res = _PyObject_CallMethodOneArg(file, &_Py_ID(write), s);
1706 : 0 : Py_DECREF(s);
1707 : 0 : return res;
1708 : : }
1709 : :
1710 : : /*[clinic input]
1711 : : marshal.load
1712 : :
1713 : : file: object
1714 : : Must be readable binary file.
1715 : : /
1716 : :
1717 : : Read one value from the open file and return it.
1718 : :
1719 : : If no valid value is read (e.g. because the data has a different Python
1720 : : version's incompatible marshal format), raise EOFError, ValueError or
1721 : : TypeError.
1722 : :
1723 : : Note: If an object containing an unsupported type was marshalled with
1724 : : dump(), load() will substitute None for the unmarshallable type.
1725 : : [clinic start generated code]*/
1726 : :
1727 : : static PyObject *
1728 : 0 : marshal_load(PyObject *module, PyObject *file)
1729 : : /*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
1730 : : {
1731 : : PyObject *data, *result;
1732 : : RFILE rf;
1733 : :
1734 : : /*
1735 : : * Make a call to the read method, but read zero bytes.
1736 : : * This is to ensure that the object passed in at least
1737 : : * has a read method which returns bytes.
1738 : : * This can be removed if we guarantee good error handling
1739 : : * for r_string()
1740 : : */
1741 : 0 : data = _PyObject_CallMethod(file, &_Py_ID(read), "i", 0);
1742 [ # # ]: 0 : if (data == NULL)
1743 : 0 : return NULL;
1744 [ # # ]: 0 : if (!PyBytes_Check(data)) {
1745 : 0 : PyErr_Format(PyExc_TypeError,
1746 : : "file.read() returned not bytes but %.100s",
1747 : 0 : Py_TYPE(data)->tp_name);
1748 : 0 : result = NULL;
1749 : : }
1750 : : else {
1751 : 0 : rf.depth = 0;
1752 : 0 : rf.fp = NULL;
1753 : 0 : rf.readable = file;
1754 : 0 : rf.ptr = rf.end = NULL;
1755 : 0 : rf.buf = NULL;
1756 [ # # ]: 0 : if ((rf.refs = PyList_New(0)) != NULL) {
1757 : 0 : result = read_object(&rf);
1758 : 0 : Py_DECREF(rf.refs);
1759 [ # # ]: 0 : if (rf.buf != NULL)
1760 : 0 : PyMem_Free(rf.buf);
1761 : : } else
1762 : 0 : result = NULL;
1763 : : }
1764 : 0 : Py_DECREF(data);
1765 : 0 : return result;
1766 : : }
1767 : :
1768 : : /*[clinic input]
1769 : : marshal.dumps
1770 : :
1771 : : value: object
1772 : : Must be a supported type.
1773 : : version: int(c_default="Py_MARSHAL_VERSION") = version
1774 : : Indicates the data format that dumps should use.
1775 : : /
1776 : :
1777 : : Return the bytes object that would be written to a file by dump(value, file).
1778 : :
1779 : : Raise a ValueError exception if value has (or contains an object that has) an
1780 : : unsupported type.
1781 : : [clinic start generated code]*/
1782 : :
1783 : : static PyObject *
1784 : 179 : marshal_dumps_impl(PyObject *module, PyObject *value, int version)
1785 : : /*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
1786 : : {
1787 : 179 : return PyMarshal_WriteObjectToString(value, version);
1788 : : }
1789 : :
1790 : : /*[clinic input]
1791 : : marshal.loads
1792 : :
1793 : : bytes: Py_buffer
1794 : : /
1795 : :
1796 : : Convert the bytes-like object to a value.
1797 : :
1798 : : If no valid value is found, raise EOFError, ValueError or TypeError. Extra
1799 : : bytes in the input are ignored.
1800 : : [clinic start generated code]*/
1801 : :
1802 : : static PyObject *
1803 : 386 : marshal_loads_impl(PyObject *module, Py_buffer *bytes)
1804 : : /*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
1805 : : {
1806 : : RFILE rf;
1807 : 386 : char *s = bytes->buf;
1808 : 386 : Py_ssize_t n = bytes->len;
1809 : : PyObject* result;
1810 : 386 : rf.fp = NULL;
1811 : 386 : rf.readable = NULL;
1812 : 386 : rf.ptr = s;
1813 : 386 : rf.end = s + n;
1814 : 386 : rf.depth = 0;
1815 [ - + ]: 386 : if ((rf.refs = PyList_New(0)) == NULL)
1816 : 0 : return NULL;
1817 : 386 : result = read_object(&rf);
1818 : 386 : Py_DECREF(rf.refs);
1819 : 386 : return result;
1820 : : }
1821 : :
1822 : : static PyMethodDef marshal_methods[] = {
1823 : : MARSHAL_DUMP_METHODDEF
1824 : : MARSHAL_LOAD_METHODDEF
1825 : : MARSHAL_DUMPS_METHODDEF
1826 : : MARSHAL_LOADS_METHODDEF
1827 : : {NULL, NULL} /* sentinel */
1828 : : };
1829 : :
1830 : :
1831 : : PyDoc_STRVAR(module_doc,
1832 : : "This module contains functions that can read and write Python values in\n\
1833 : : a binary format. The format is specific to Python, but independent of\n\
1834 : : machine architecture issues.\n\
1835 : : \n\
1836 : : Not all Python object types are supported; in general, only objects\n\
1837 : : whose value is independent from a particular invocation of Python can be\n\
1838 : : written and read by this module. The following types are supported:\n\
1839 : : None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1840 : : tuples, lists, sets, dictionaries, and code objects, where it\n\
1841 : : should be understood that tuples, lists and dictionaries are only\n\
1842 : : supported as long as the values contained therein are themselves\n\
1843 : : supported; and recursive lists and dictionaries should not be written\n\
1844 : : (they will cause infinite loops).\n\
1845 : : \n\
1846 : : Variables:\n\
1847 : : \n\
1848 : : version -- indicates the format that the module uses. Version 0 is the\n\
1849 : : historical format, version 1 shares interned strings and version 2\n\
1850 : : uses a binary format for floating point numbers.\n\
1851 : : Version 3 shares common object references (New in version 3.4).\n\
1852 : : \n\
1853 : : Functions:\n\
1854 : : \n\
1855 : : dump() -- write value to a file\n\
1856 : : load() -- read value from a file\n\
1857 : : dumps() -- marshal value as a bytes object\n\
1858 : : loads() -- read value from a bytes-like object");
1859 : :
1860 : :
1861 : : static int
1862 : 26 : marshal_module_exec(PyObject *mod)
1863 : : {
1864 [ - + ]: 26 : if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1865 : 0 : return -1;
1866 : : }
1867 : 26 : return 0;
1868 : : }
1869 : :
1870 : : static PyModuleDef_Slot marshalmodule_slots[] = {
1871 : : {Py_mod_exec, marshal_module_exec},
1872 : : {0, NULL}
1873 : : };
1874 : :
1875 : : static struct PyModuleDef marshalmodule = {
1876 : : PyModuleDef_HEAD_INIT,
1877 : : .m_name = "marshal",
1878 : : .m_doc = module_doc,
1879 : : .m_methods = marshal_methods,
1880 : : .m_slots = marshalmodule_slots,
1881 : : };
1882 : :
1883 : : PyMODINIT_FUNC
1884 : 26 : PyMarshal_Init(void)
1885 : : {
1886 : 26 : return PyModuleDef_Init(&marshalmodule);
1887 : : }
|