Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/Python/marshal.c
Line
Count
Source (jump to first uncovered line)
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
249k
#define MAX_MARSHAL_STACK_DEPTH 2000
39
#endif
40
41
0
#define TYPE_NULL               '0'
42
7.66k
#define TYPE_NONE               'N'
43
1.04k
#define TYPE_FALSE              'F'
44
853
#define TYPE_TRUE               'T'
45
0
#define TYPE_STOPITER           'S'
46
0
#define TYPE_ELLIPSIS           '.'
47
2.26k
#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
28
#define TYPE_LONG               'l'
56
22.2k
#define TYPE_STRING             's'
57
0
#define TYPE_INTERNED           't'
58
118k
#define TYPE_REF                'r'
59
14
#define TYPE_TUPLE              '('
60
0
#define TYPE_LIST               '['
61
0
#define TYPE_DICT               '{'
62
11.0k
#define TYPE_CODE               'c'
63
15
#define TYPE_UNICODE            'u'
64
#define TYPE_UNKNOWN            '?'
65
63
#define TYPE_SET                '<'
66
21
#define TYPE_FROZENSET          '>'
67
498k
#define FLAG_REF                '\x80' /* with a type, add obj to index */
68
69
1.11k
#define TYPE_ASCII              'a'
70
0
#define TYPE_ASCII_INTERNED     'A'
71
26.3k
#define TYPE_SMALL_TUPLE        ')'
72
58.7k
#define TYPE_SHORT_ASCII        'z'
73
44.1k
#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
23.5k
#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
308
#define PyLong_MARSHAL_SHIFT 15
215
84
#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
140
#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
303k
{
651
303k
    Py_ssize_t read = -1;
652
653
303k
    if (p->ptr != NULL) {
654
        /* Fast path for loads() */
655
303k
        char *res = p->ptr;
656
303k
        Py_ssize_t left = p->end - p->ptr;
657
303k
        if (left < n) {
658
0
            PyErr_SetString(PyExc_EOFError,
659
0
                            "marshal data too short");
660
0
            return NULL;
661
0
        }
662
303k
        p->ptr += n;
663
303k
        return res;
664
303k
    }
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
334k
{
723
334k
    int c = EOF;
724
725
334k
    if (p->ptr != NULL) {
726
334k
        if (p->ptr < p->end)
727
334k
            c = (unsigned char) *p->ptr++;
728
334k
        return c;
729
334k
    }
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
334k
}
741
742
static int
743
r_short(RFILE *p)
744
84
{
745
84
    short x = -1;
746
84
    const unsigned char *buffer;
747
748
84
    buffer = (const unsigned char *) r_string(2, p);
749
84
    if (buffer != NULL) {
750
84
        x = buffer[0];
751
84
        x |= buffer[1] << 8;
752
        /* Sign-extension, in case short greater than 16 bits */
753
84
        x |= -(x & 0x8000);
754
84
    }
755
84
    return x;
756
84
}
757
758
static long
759
r_long(RFILE *p)
760
220k
{
761
220k
    long x = -1;
762
220k
    const unsigned char *buffer;
763
764
220k
    buffer = (const unsigned char *) r_string(4, p);
765
220k
    if (buffer != NULL) {
766
220k
        x = buffer[0];
767
220k
        x |= (long)buffer[1] << 8;
768
220k
        x |= (long)buffer[2] << 16;
769
220k
        x |= (long)buffer[3] << 24;
770
220k
#if SIZEOF_LONG > 4
771
        /* Sign extension for 64-bit machines */
772
220k
        x |= -(x & 0x80000000L);
773
220k
#endif
774
220k
    }
775
220k
    return x;
776
220k
}
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
28
{
794
28
    PyLongObject *ob;
795
28
    long n, size, i;
796
28
    int j, md, shorts_in_top_digit;
797
28
    digit d;
798
799
28
    n = r_long(p);
800
28
    if (PyErr_Occurred())
801
0
        return NULL;
802
28
    if (n == 0)
803
0
        return (PyObject *)_PyLong_New(0);
804
28
    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
28
    size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
811
28
    shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
812
28
    ob = _PyLong_New(size);
813
28
    if (ob == NULL)
814
0
        return NULL;
815
816
28
    Py_SIZE(ob) = n > 0 ? size : -size;
817
818
56
    for (i = 0; i < size-1; i++) {
819
28
        d = 0;
820
84
        for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
821
56
            md = r_short(p);
822
56
            if (PyErr_Occurred()) {
823
0
                Py_DECREF(ob);
824
0
                return NULL;
825
0
            }
826
56
            if (md < 0 || md > PyLong_MARSHAL_BASE)
827
0
                goto bad_digit;
828
56
            d += (digit)md << j*PyLong_MARSHAL_SHIFT;
829
56
        }
830
28
        ob->ob_digit[i] = d;
831
28
    }
832
833
28
    d = 0;
834
56
    for (j=0; j < shorts_in_top_digit; j++) {
835
28
        md = r_short(p);
836
28
        if (PyErr_Occurred()) {
837
0
            Py_DECREF(ob);
838
0
            return NULL;
839
0
        }
840
28
        if (md < 0 || md > PyLong_MARSHAL_BASE)
841
0
            goto bad_digit;
842
        /* topmost marshal digit should be nonzero */
843
28
        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
28
        d += (digit)md << j*PyLong_MARSHAL_SHIFT;
850
28
    }
851
28
    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
28
    ob->ob_digit[size-1] = d;
858
28
    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
28
}
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
11.0k
{
902
11.0k
    if (flag) { /* currently only FLAG_REF is defined */
903
235
        Py_ssize_t idx = PyList_GET_SIZE(p->refs);
904
235
        if (idx >= 0x7ffffffe) {
905
0
            PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
906
0
            return -1;
907
0
        }
908
235
        if (PyList_Append(p->refs, Py_None) < 0)
909
0
            return -1;
910
235
        return idx;
911
235
    } else
912
10.7k
        return 0;
913
11.0k
}
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
11.0k
{
926
11.0k
    if (o != NULL && flag) { /* currently only FLAG_REF is defined */
927
235
        PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
928
235
        Py_INCREF(o);
929
235
        PyList_SET_ITEM(p->refs, idx, o);
930
235
        Py_DECREF(tmp);
931
235
    }
932
11.0k
    return o;
933
11.0k
}
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
46.4k
{
942
46.4k
    assert(flag & FLAG_REF);
943
46.4k
    if (o == NULL)
944
0
        return NULL;
945
46.4k
    if (PyList_Append(p->refs, o) < 0) {
946
0
        Py_DECREF(o); /* release the new object */
947
0
        return NULL;
948
0
    }
949
46.4k
    return o;
950
46.4k
}
951
952
static PyObject *
953
r_object(RFILE *p)
954
249k
{
955
    /* NULL is a valid return value, it does not necessarily means that
956
       an exception is set. */
957
249k
    PyObject *v, *v2;
958
249k
    Py_ssize_t idx = 0;
959
249k
    long i, n;
960
249k
    int type, code = r_byte(p);
961
249k
    int flag, is_interned = 0;
962
249k
    PyObject *retval = NULL;
963
964
249k
    if (code == EOF) {
965
0
        PyErr_SetString(PyExc_EOFError,
966
0
                        "EOF read where object expected");
967
0
        return NULL;
968
0
    }
969
970
249k
    p->depth++;
971
972
249k
    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
249k
    flag = code & FLAG_REF;
979
249k
    type = code & ~FLAG_REF;
980
981
249k
#define R_REF(O) do{\
982
110k
    if (flag) \
983
110k
        O = r_ref(O, flag, p);\
984
110k
} while (0)
985
986
249k
    switch (type) {
987
988
0
    case TYPE_NULL:
989
0
        break;
990
991
7.66k
    case TYPE_NONE:
992
7.66k
        Py_INCREF(Py_None);
993
7.66k
        retval = Py_None;
994
7.66k
        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
1.04k
    case TYPE_FALSE:
1007
1.04k
        Py_INCREF(Py_False);
1008
1.04k
        retval = Py_False;
1009
1.04k
        break;
1010
1011
853
    case TYPE_TRUE:
1012
853
        Py_INCREF(Py_True);
1013
853
        retval = Py_True;
1014
853
        break;
1015
1016
2.26k
    case TYPE_INT:
1017
2.26k
        n = r_long(p);
1018
2.26k
        retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
1019
2.26k
        R_REF(retval);
1020
2.26k
        break;
1021
1022
0
    case TYPE_INT64:
1023
0
        retval = r_long64(p);
1024
0
        R_REF(retval);
1025
0
        break;
1026
1027
28
    case TYPE_LONG:
1028
28
        retval = r_PyLong(p);
1029
28
        R_REF(retval);
1030
28
        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
22.2k
    case TYPE_STRING:
1081
22.2k
        {
1082
22.2k
            const char *ptr;
1083
22.2k
            n = r_long(p);
1084
22.2k
            if (PyErr_Occurred())
1085
0
                break;
1086
22.2k
            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
22.2k
            v = PyBytes_FromStringAndSize((char *)NULL, n);
1091
22.2k
            if (v == NULL)
1092
0
                break;
1093
22.2k
            ptr = r_string(n, p);
1094
22.2k
            if (ptr == NULL) {
1095
0
                Py_DECREF(v);
1096
0
                break;
1097
0
            }
1098
22.2k
            memcpy(PyBytes_AS_STRING(v), ptr, n);
1099
22.2k
            retval = v;
1100
22.2k
            R_REF(retval);
1101
22.2k
            break;
1102
22.2k
        }
1103
1104
0
    case TYPE_ASCII_INTERNED:
1105
0
        is_interned = 1;
1106
        /* fall through */
1107
1.11k
    case TYPE_ASCII:
1108
1.11k
        n = r_long(p);
1109
1.11k
        if (PyErr_Occurred())
1110
0
            break;
1111
1.11k
        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.11k
        goto _read_ascii;
1116
1117
44.1k
    case TYPE_SHORT_ASCII_INTERNED:
1118
44.1k
        is_interned = 1;
1119
        /* fall through */
1120
58.7k
    case TYPE_SHORT_ASCII:
1121
58.7k
        n = r_byte(p);
1122
58.7k
        if (n == EOF) {
1123
0
            PyErr_SetString(PyExc_EOFError,
1124
0
                "EOF read where object expected");
1125
0
            break;
1126
0
        }
1127
59.8k
    _read_ascii:
1128
59.8k
        {
1129
59.8k
            const char *ptr;
1130
59.8k
            ptr = r_string(n, p);
1131
59.8k
            if (ptr == NULL)
1132
0
                break;
1133
59.8k
            v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
1134
59.8k
            if (v == NULL)
1135
0
                break;
1136
59.8k
            if (is_interned)
1137
44.1k
                PyUnicode_InternInPlace(&v);
1138
59.8k
            retval = v;
1139
59.8k
            R_REF(retval);
1140
59.8k
            break;
1141
59.8k
        }
1142
1143
0
    case TYPE_INTERNED:
1144
0
        is_interned = 1;
1145
        /* fall through */
1146
15
    case TYPE_UNICODE:
1147
15
        {
1148
15
        const char *buffer;
1149
1150
15
        n = r_long(p);
1151
15
        if (PyErr_Occurred())
1152
0
            break;
1153
15
        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
15
        if (n != 0) {
1158
15
            buffer = r_string(n, p);
1159
15
            if (buffer == NULL)
1160
0
                break;
1161
15
            v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
1162
15
        }
1163
0
        else {
1164
0
            v = PyUnicode_New(0, 0);
1165
0
        }
1166
15
        if (v == NULL)
1167
0
            break;
1168
15
        if (is_interned)
1169
0
            PyUnicode_InternInPlace(&v);
1170
15
        retval = v;
1171
15
        R_REF(retval);
1172
15
        break;
1173
15
        }
1174
1175
26.3k
    case TYPE_SMALL_TUPLE:
1176
26.3k
        n = (unsigned char) r_byte(p);
1177
26.3k
        if (PyErr_Occurred())
1178
0
            break;
1179
26.3k
        goto _read_tuple;
1180
26.3k
    case TYPE_TUPLE:
1181
14
        n = r_long(p);
1182
14
        if (PyErr_Occurred())
1183
0
            break;
1184
14
        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
26.3k
    _read_tuple:
1189
26.3k
        v = PyTuple_New(n);
1190
26.3k
        R_REF(v);
1191
26.3k
        if (v == NULL)
1192
0
            break;
1193
1194
176k
        for (i = 0; i < n; i++) {
1195
150k
            v2 = r_object(p);
1196
150k
            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
150k
            PyTuple_SET_ITEM(v, i, v2);
1205
150k
        }
1206
26.3k
        retval = v;
1207
26.3k
        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
21
    case TYPE_FROZENSET:
1268
21
        n = r_long(p);
1269
21
        if (PyErr_Occurred())
1270
0
            break;
1271
21
        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
21
        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
21
        else {
1285
21
            v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1286
21
            if (type == TYPE_SET) {
1287
0
                R_REF(v);
1288
21
            } else {
1289
                /* must use delayed registration of frozensets because they must
1290
                 * be init with a refcount of 1
1291
                 */
1292
21
                idx = r_ref_reserve(flag, p);
1293
21
                if (idx < 0)
1294
0
                    Py_CLEAR(v); /* signal error */
1295
21
            }
1296
21
            if (v == NULL)
1297
0
                break;
1298
1299
69
            for (i = 0; i < n; i++) {
1300
48
                v2 = r_object(p);
1301
48
                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
48
                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
48
                Py_DECREF(v2);
1316
48
            }
1317
21
            if (type != TYPE_SET)
1318
21
                v = r_ref_insert(v, idx, flag, p);
1319
21
            retval = v;
1320
21
        }
1321
21
        break;
1322
1323
11.0k
    case TYPE_CODE:
1324
11.0k
        {
1325
11.0k
            int argcount;
1326
11.0k
            int posonlyargcount;
1327
11.0k
            int kwonlyargcount;
1328
11.0k
            int nlocals;
1329
11.0k
            int stacksize;
1330
11.0k
            int flags;
1331
11.0k
            PyObject *code = NULL;
1332
11.0k
            PyObject *consts = NULL;
1333
11.0k
            PyObject *names = NULL;
1334
11.0k
            PyObject *varnames = NULL;
1335
11.0k
            PyObject *freevars = NULL;
1336
11.0k
            PyObject *cellvars = NULL;
1337
11.0k
            PyObject *filename = NULL;
1338
11.0k
            PyObject *name = NULL;
1339
11.0k
            int firstlineno;
1340
11.0k
            PyObject *lnotab = NULL;
1341
1342
11.0k
            idx = r_ref_reserve(flag, p);
1343
11.0k
            if (idx < 0)
1344
0
                break;
1345
1346
11.0k
            v = NULL;
1347
1348
            /* XXX ignore long->int overflows for now */
1349
11.0k
            argcount = (int)r_long(p);
1350
11.0k
            if (PyErr_Occurred())
1351
0
                goto code_error;
1352
11.0k
            posonlyargcount = (int)r_long(p);
1353
11.0k
            if (PyErr_Occurred()) {
1354
0
                goto code_error;
1355
0
            }
1356
11.0k
            kwonlyargcount = (int)r_long(p);
1357
11.0k
            if (PyErr_Occurred())
1358
0
                goto code_error;
1359
11.0k
            nlocals = (int)r_long(p);
1360
11.0k
            if (PyErr_Occurred())
1361
0
                goto code_error;
1362
11.0k
            stacksize = (int)r_long(p);
1363
11.0k
            if (PyErr_Occurred())
1364
0
                goto code_error;
1365
11.0k
            flags = (int)r_long(p);
1366
11.0k
            if (PyErr_Occurred())
1367
0
                goto code_error;
1368
11.0k
            code = r_object(p);
1369
11.0k
            if (code == NULL)
1370
0
                goto code_error;
1371
11.0k
            consts = r_object(p);
1372
11.0k
            if (consts == NULL)
1373
0
                goto code_error;
1374
11.0k
            names = r_object(p);
1375
11.0k
            if (names == NULL)
1376
0
                goto code_error;
1377
11.0k
            varnames = r_object(p);
1378
11.0k
            if (varnames == NULL)
1379
0
                goto code_error;
1380
11.0k
            freevars = r_object(p);
1381
11.0k
            if (freevars == NULL)
1382
0
                goto code_error;
1383
11.0k
            cellvars = r_object(p);
1384
11.0k
            if (cellvars == NULL)
1385
0
                goto code_error;
1386
11.0k
            filename = r_object(p);
1387
11.0k
            if (filename == NULL)
1388
0
                goto code_error;
1389
11.0k
            name = r_object(p);
1390
11.0k
            if (name == NULL)
1391
0
                goto code_error;
1392
11.0k
            firstlineno = (int)r_long(p);
1393
11.0k
            if (firstlineno == -1 && PyErr_Occurred())
1394
0
                break;
1395
11.0k
            lnotab = r_object(p);
1396
11.0k
            if (lnotab == NULL)
1397
0
                goto code_error;
1398
1399
11.0k
            v = (PyObject *) PyCode_NewWithPosOnlyArgs(
1400
11.0k
                            argcount, posonlyargcount, kwonlyargcount,
1401
11.0k
                            nlocals, stacksize, flags,
1402
11.0k
                            code, consts, names, varnames,
1403
11.0k
                            freevars, cellvars, filename, name,
1404
11.0k
                            firstlineno, lnotab);
1405
11.0k
            v = r_ref_insert(v, idx, flag, p);
1406
1407
11.0k
          code_error:
1408
11.0k
            Py_XDECREF(code);
1409
11.0k
            Py_XDECREF(consts);
1410
11.0k
            Py_XDECREF(names);
1411
11.0k
            Py_XDECREF(varnames);
1412
11.0k
            Py_XDECREF(freevars);
1413
11.0k
            Py_XDECREF(cellvars);
1414
11.0k
            Py_XDECREF(filename);
1415
11.0k
            Py_XDECREF(name);
1416
11.0k
            Py_XDECREF(lnotab);
1417
11.0k
        }
1418
0
        retval = v;
1419
11.0k
        break;
1420
1421
118k
    case TYPE_REF:
1422
118k
        n = r_long(p);
1423
118k
        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
118k
        v = PyList_GET_ITEM(p->refs, n);
1430
118k
        if (v == Py_None) {
1431
0
            PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
1432
0
            break;
1433
0
        }
1434
118k
        Py_INCREF(v);
1435
118k
        retval = v;
1436
118k
        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
249k
    }
1445
249k
    p->depth--;
1446
249k
    return retval;
1447
249k
}
1448
1449
static PyObject *
1450
read_object(RFILE *p)
1451
235
{
1452
235
    PyObject *v;
1453
235
    if (PyErr_Occurred()) {
1454
0
        fprintf(stderr, "XXX readobject called with exception set\n");
1455
0
        return NULL;
1456
0
    }
1457
235
    v = r_object(p);
1458
235
    if (v == NULL && !PyErr_Occurred())
1459
0
        PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1460
235
    return v;
1461
235
}
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
42
{
1563
42
    RFILE rf;
1564
42
    PyObject *result;
1565
42
    rf.fp = NULL;
1566
42
    rf.readable = NULL;
1567
42
    rf.ptr = (char *)str;
1568
42
    rf.end = (char *)str + len;
1569
42
    rf.buf = NULL;
1570
42
    rf.depth = 0;
1571
42
    rf.refs = PyList_New(0);
1572
42
    if (rf.refs == NULL)
1573
0
        return NULL;
1574
42
    result = r_object(&rf);
1575
42
    Py_DECREF(rf.refs);
1576
42
    if (rf.buf != NULL)
1577
0
        PyMem_FREE(rf.buf);
1578
42
    return result;
1579
42
}
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
235
{
1758
235
    RFILE rf;
1759
235
    char *s = bytes->buf;
1760
235
    Py_ssize_t n = bytes->len;
1761
235
    PyObject* result;
1762
235
    rf.fp = NULL;
1763
235
    rf.readable = NULL;
1764
235
    rf.ptr = s;
1765
235
    rf.end = s + n;
1766
235
    rf.depth = 0;
1767
235
    if ((rf.refs = PyList_New(0)) == NULL)
1768
0
        return NULL;
1769
235
    result = read_object(&rf);
1770
235
    Py_DECREF(rf.refs);
1771
235
    return result;
1772
235
}
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
14
{
1829
14
    PyObject *mod = PyModule_Create(&marshalmodule);
1830
14
    if (mod == NULL)
1831
0
        return NULL;
1832
14
    if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1833
0
        Py_DECREF(mod);
1834
0
        return NULL;
1835
0
    }
1836
14
    return mod;
1837
14
}