Coverage Report

Created: 2026-06-14 06:25

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