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