LCOV - code coverage report
Current view: | top level - Python - marshal.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 536 | 994 | 53.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 31 | 44 | 70.5 %
|  |  | Branches: | 310 | 734 | 42.2 %

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

Generated by: LCOV version 1.14