LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Python - marshal.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 211 731 28.9 %
Date: 2012-12-17 Functions: 10 28 35.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /* Write Python objects to files and read them back.
       3             :    This is intended for writing and reading compiled Python code only;
       4             :    a true persistent storage facility would be much harder, since
       5             :    it would have to take circular links and sharing into account. */
       6             : 
       7             : #define PY_SSIZE_T_CLEAN
       8             : 
       9             : #include "Python.h"
      10             : #include "longintrepr.h"
      11             : #include "code.h"
      12             : #include "marshal.h"
      13             : 
      14             : #define ABS(x) ((x) < 0 ? -(x) : (x))
      15             : 
      16             : /* High water mark to determine when the marshalled object is dangerously deep
      17             :  * and risks coring the interpreter.  When the object stack gets this deep,
      18             :  * raise an exception instead of continuing.
      19             :  * On Windows debug builds, reduce this value.
      20             :  */
      21             : #if defined(MS_WINDOWS) && defined(_DEBUG)
      22             : #define MAX_MARSHAL_STACK_DEPTH 1500
      23             : #else
      24             : #define MAX_MARSHAL_STACK_DEPTH 2000
      25             : #endif
      26             : 
      27             : #define TYPE_NULL               '0'
      28             : #define TYPE_NONE               'N'
      29             : #define TYPE_FALSE              'F'
      30             : #define TYPE_TRUE               'T'
      31             : #define TYPE_STOPITER           'S'
      32             : #define TYPE_ELLIPSIS           '.'
      33             : #define TYPE_INT                'i'
      34             : /* TYPE_INT64 is deprecated. It is not
      35             :    generated anymore, and support for reading it
      36             :    will be removed in Python 3.4. */
      37             : #define TYPE_INT64              'I'
      38             : #define TYPE_FLOAT              'f'
      39             : #define TYPE_BINARY_FLOAT       'g'
      40             : #define TYPE_COMPLEX            'x'
      41             : #define TYPE_BINARY_COMPLEX     'y'
      42             : #define TYPE_LONG               'l'
      43             : #define TYPE_STRING             's'
      44             : #define TYPE_TUPLE              '('
      45             : #define TYPE_LIST               '['
      46             : #define TYPE_DICT               '{'
      47             : #define TYPE_CODE               'c'
      48             : #define TYPE_UNICODE            'u'
      49             : #define TYPE_UNKNOWN            '?'
      50             : #define TYPE_SET                '<'
      51             : #define TYPE_FROZENSET          '>'
      52             : 
      53             : #define WFERR_OK 0
      54             : #define WFERR_UNMARSHALLABLE 1
      55             : #define WFERR_NESTEDTOODEEP 2
      56             : #define WFERR_NOMEMORY 3
      57             : 
      58             : typedef struct {
      59             :     FILE *fp;
      60             :     int error;  /* see WFERR_* values */
      61             :     int depth;
      62             :     /* If fp == NULL, the following are valid: */
      63             :     PyObject *readable;    /* Stream-like object being read from */
      64             :     PyObject *str;
      65             :     PyObject *current_filename;
      66             :     char *ptr;
      67             :     char *end;
      68             :     int version;
      69             : } WFILE;
      70             : 
      71             : #define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
      72             :                       else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
      73             :                            else w_more(c, p)
      74             : 
      75             : static void
      76           0 : w_more(int c, WFILE *p)
      77             : {
      78             :     Py_ssize_t size, newsize;
      79           0 :     if (p->str == NULL)
      80           0 :         return; /* An error already occurred */
      81           0 :     size = PyBytes_Size(p->str);
      82           0 :     newsize = size + size + 1024;
      83           0 :     if (newsize > 32*1024*1024) {
      84           0 :         newsize = size + (size >> 3);           /* 12.5% overallocation */
      85             :     }
      86           0 :     if (_PyBytes_Resize(&p->str, newsize) != 0) {
      87           0 :         p->ptr = p->end = NULL;
      88             :     }
      89             :     else {
      90           0 :         p->ptr = PyBytes_AS_STRING((PyBytesObject *)p->str) + size;
      91           0 :         p->end =
      92           0 :             PyBytes_AS_STRING((PyBytesObject *)p->str) + newsize;
      93           0 :         *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
      94             :     }
      95             : }
      96             : 
      97             : static void
      98           0 : w_string(char *s, int n, WFILE *p)
      99             : {
     100           0 :     if (p->fp != NULL) {
     101           0 :         fwrite(s, 1, n, p->fp);
     102             :     }
     103             :     else {
     104           0 :         while (--n >= 0) {
     105           0 :             w_byte(*s, p);
     106           0 :             s++;
     107             :         }
     108             :     }
     109           0 : }
     110             : 
     111             : static void
     112           0 : w_short(int x, WFILE *p)
     113             : {
     114           0 :     w_byte((char)( x      & 0xff), p);
     115           0 :     w_byte((char)((x>> 8) & 0xff), p);
     116           0 : }
     117             : 
     118             : static void
     119           0 : w_long(long x, WFILE *p)
     120             : {
     121           0 :     w_byte((char)( x      & 0xff), p);
     122           0 :     w_byte((char)((x>> 8) & 0xff), p);
     123           0 :     w_byte((char)((x>>16) & 0xff), p);
     124           0 :     w_byte((char)((x>>24) & 0xff), p);
     125           0 : }
     126             : 
     127             : /* We assume that Python longs are stored internally in base some power of
     128             :    2**15; for the sake of portability we'll always read and write them in base
     129             :    exactly 2**15. */
     130             : 
     131             : #define PyLong_MARSHAL_SHIFT 15
     132             : #define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
     133             : #define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
     134             : #if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
     135             : #error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
     136             : #endif
     137             : #define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
     138             : 
     139             : static void
     140           0 : w_PyLong(const PyLongObject *ob, WFILE *p)
     141             : {
     142             :     Py_ssize_t i, j, n, l;
     143             :     digit d;
     144             : 
     145           0 :     w_byte(TYPE_LONG, p);
     146           0 :     if (Py_SIZE(ob) == 0) {
     147           0 :         w_long((long)0, p);
     148           0 :         return;
     149             :     }
     150             : 
     151             :     /* set l to number of base PyLong_MARSHAL_BASE digits */
     152           0 :     n = ABS(Py_SIZE(ob));
     153           0 :     l = (n-1) * PyLong_MARSHAL_RATIO;
     154           0 :     d = ob->ob_digit[n-1];
     155             :     assert(d != 0); /* a PyLong is always normalized */
     156             :     do {
     157           0 :         d >>= PyLong_MARSHAL_SHIFT;
     158           0 :         l++;
     159           0 :     } while (d != 0);
     160           0 :     w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
     161             : 
     162           0 :     for (i=0; i < n-1; i++) {
     163           0 :         d = ob->ob_digit[i];
     164           0 :         for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
     165           0 :             w_short(d & PyLong_MARSHAL_MASK, p);
     166           0 :             d >>= PyLong_MARSHAL_SHIFT;
     167             :         }
     168             :         assert (d == 0);
     169             :     }
     170           0 :     d = ob->ob_digit[n-1];
     171             :     do {
     172           0 :         w_short(d & PyLong_MARSHAL_MASK, p);
     173           0 :         d >>= PyLong_MARSHAL_SHIFT;
     174           0 :     } while (d != 0);
     175             : }
     176             : 
     177             : static void
     178           0 : w_object(PyObject *v, WFILE *p)
     179             : {
     180             :     Py_ssize_t i, n;
     181             : 
     182           0 :     p->depth++;
     183             : 
     184           0 :     if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
     185           0 :         p->error = WFERR_NESTEDTOODEEP;
     186             :     }
     187           0 :     else if (v == NULL) {
     188           0 :         w_byte(TYPE_NULL, p);
     189             :     }
     190           0 :     else if (v == Py_None) {
     191           0 :         w_byte(TYPE_NONE, p);
     192             :     }
     193           0 :     else if (v == PyExc_StopIteration) {
     194           0 :         w_byte(TYPE_STOPITER, p);
     195             :     }
     196           0 :     else if (v == Py_Ellipsis) {
     197           0 :         w_byte(TYPE_ELLIPSIS, p);
     198             :     }
     199           0 :     else if (v == Py_False) {
     200           0 :         w_byte(TYPE_FALSE, p);
     201             :     }
     202           0 :     else if (v == Py_True) {
     203           0 :         w_byte(TYPE_TRUE, p);
     204             :     }
     205           0 :     else if (PyLong_CheckExact(v)) {
     206           0 :         long x = PyLong_AsLong(v);
     207           0 :         if ((x == -1)  && PyErr_Occurred()) {
     208           0 :             PyLongObject *ob = (PyLongObject *)v;
     209           0 :             PyErr_Clear();
     210           0 :             w_PyLong(ob, p);
     211             :         }
     212             :         else {
     213             : #if SIZEOF_LONG > 4
     214             :             long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
     215             :             if (y && y != -1) {
     216             :                 /* Too large for TYPE_INT */
     217             :                 w_PyLong((PyLongObject*)v, p);
     218             :             }
     219             :             else
     220             : #endif
     221             :             {
     222           0 :                 w_byte(TYPE_INT, p);
     223           0 :                 w_long(x, p);
     224             :             }
     225             :         }
     226             :     }
     227           0 :     else if (PyFloat_CheckExact(v)) {
     228           0 :         if (p->version > 1) {
     229             :             unsigned char buf[8];
     230           0 :             if (_PyFloat_Pack8(PyFloat_AsDouble(v),
     231             :                                buf, 1) < 0) {
     232           0 :                 p->error = WFERR_UNMARSHALLABLE;
     233             :                 return;
     234             :             }
     235           0 :             w_byte(TYPE_BINARY_FLOAT, p);
     236           0 :             w_string((char*)buf, 8, p);
     237             :         }
     238             :         else {
     239           0 :             char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
     240             :                                               'g', 17, 0, NULL);
     241           0 :             if (!buf) {
     242           0 :                 p->error = WFERR_NOMEMORY;
     243           0 :                 return;
     244             :             }
     245           0 :             n = strlen(buf);
     246           0 :             w_byte(TYPE_FLOAT, p);
     247           0 :             w_byte((int)n, p);
     248           0 :             w_string(buf, (int)n, p);
     249           0 :             PyMem_Free(buf);
     250             :         }
     251             :     }
     252           0 :     else if (PyComplex_CheckExact(v)) {
     253           0 :         if (p->version > 1) {
     254             :             unsigned char buf[8];
     255           0 :             if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
     256             :                                buf, 1) < 0) {
     257           0 :                 p->error = WFERR_UNMARSHALLABLE;
     258             :                 return;
     259             :             }
     260           0 :             w_byte(TYPE_BINARY_COMPLEX, p);
     261           0 :             w_string((char*)buf, 8, p);
     262           0 :             if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
     263             :                                buf, 1) < 0) {
     264           0 :                 p->error = WFERR_UNMARSHALLABLE;
     265             :                 return;
     266             :             }
     267           0 :             w_string((char*)buf, 8, p);
     268             :         }
     269             :         else {
     270             :             char *buf;
     271           0 :             w_byte(TYPE_COMPLEX, p);
     272           0 :             buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
     273             :                                         'g', 17, 0, NULL);
     274           0 :             if (!buf) {
     275           0 :                 p->error = WFERR_NOMEMORY;
     276           0 :                 return;
     277             :             }
     278           0 :             n = strlen(buf);
     279           0 :             w_byte((int)n, p);
     280           0 :             w_string(buf, (int)n, p);
     281           0 :             PyMem_Free(buf);
     282           0 :             buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
     283             :                                         'g', 17, 0, NULL);
     284           0 :             if (!buf) {
     285           0 :                 p->error = WFERR_NOMEMORY;
     286           0 :                 return;
     287             :             }
     288           0 :             n = strlen(buf);
     289           0 :             w_byte((int)n, p);
     290           0 :             w_string(buf, (int)n, p);
     291           0 :             PyMem_Free(buf);
     292             :         }
     293             :     }
     294           0 :     else if (PyBytes_CheckExact(v)) {
     295           0 :         w_byte(TYPE_STRING, p);
     296           0 :         n = PyBytes_GET_SIZE(v);
     297             :         if (n > INT_MAX) {
     298             :             /* huge strings are not supported */
     299             :             p->depth--;
     300             :             p->error = WFERR_UNMARSHALLABLE;
     301             :             return;
     302             :         }
     303           0 :         w_long((long)n, p);
     304           0 :         w_string(PyBytes_AS_STRING(v), (int)n, p);
     305             :     }
     306           0 :     else if (PyUnicode_CheckExact(v)) {
     307             :         PyObject *utf8;
     308           0 :         utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
     309           0 :         if (utf8 == NULL) {
     310           0 :             p->depth--;
     311           0 :             p->error = WFERR_UNMARSHALLABLE;
     312           0 :             return;
     313             :         }
     314           0 :         w_byte(TYPE_UNICODE, p);
     315           0 :         n = PyBytes_GET_SIZE(utf8);
     316             :         if (n > INT_MAX) {
     317             :             p->depth--;
     318             :             p->error = WFERR_UNMARSHALLABLE;
     319             :             return;
     320             :         }
     321           0 :         w_long((long)n, p);
     322           0 :         w_string(PyBytes_AS_STRING(utf8), (int)n, p);
     323           0 :         Py_DECREF(utf8);
     324             :     }
     325           0 :     else if (PyTuple_CheckExact(v)) {
     326           0 :         w_byte(TYPE_TUPLE, p);
     327           0 :         n = PyTuple_Size(v);
     328           0 :         w_long((long)n, p);
     329           0 :         for (i = 0; i < n; i++) {
     330           0 :             w_object(PyTuple_GET_ITEM(v, i), p);
     331             :         }
     332             :     }
     333           0 :     else if (PyList_CheckExact(v)) {
     334           0 :         w_byte(TYPE_LIST, p);
     335           0 :         n = PyList_GET_SIZE(v);
     336           0 :         w_long((long)n, p);
     337           0 :         for (i = 0; i < n; i++) {
     338           0 :             w_object(PyList_GET_ITEM(v, i), p);
     339             :         }
     340             :     }
     341           0 :     else if (PyDict_CheckExact(v)) {
     342             :         Py_ssize_t pos;
     343             :         PyObject *key, *value;
     344           0 :         w_byte(TYPE_DICT, p);
     345             :         /* This one is NULL object terminated! */
     346           0 :         pos = 0;
     347           0 :         while (PyDict_Next(v, &pos, &key, &value)) {
     348           0 :             w_object(key, p);
     349           0 :             w_object(value, p);
     350             :         }
     351           0 :         w_object((PyObject *)NULL, p);
     352             :     }
     353           0 :     else if (PyAnySet_CheckExact(v)) {
     354             :         PyObject *value, *it;
     355             : 
     356           0 :         if (PyObject_TypeCheck(v, &PySet_Type))
     357           0 :             w_byte(TYPE_SET, p);
     358             :         else
     359           0 :             w_byte(TYPE_FROZENSET, p);
     360           0 :         n = PyObject_Size(v);
     361           0 :         if (n == -1) {
     362           0 :             p->depth--;
     363           0 :             p->error = WFERR_UNMARSHALLABLE;
     364           0 :             return;
     365             :         }
     366           0 :         w_long((long)n, p);
     367           0 :         it = PyObject_GetIter(v);
     368           0 :         if (it == NULL) {
     369           0 :             p->depth--;
     370           0 :             p->error = WFERR_UNMARSHALLABLE;
     371           0 :             return;
     372             :         }
     373           0 :         while ((value = PyIter_Next(it)) != NULL) {
     374           0 :             w_object(value, p);
     375           0 :             Py_DECREF(value);
     376             :         }
     377           0 :         Py_DECREF(it);
     378           0 :         if (PyErr_Occurred()) {
     379           0 :             p->depth--;
     380           0 :             p->error = WFERR_UNMARSHALLABLE;
     381           0 :             return;
     382             :         }
     383             :     }
     384           0 :     else if (PyCode_Check(v)) {
     385           0 :         PyCodeObject *co = (PyCodeObject *)v;
     386           0 :         w_byte(TYPE_CODE, p);
     387           0 :         w_long(co->co_argcount, p);
     388           0 :         w_long(co->co_kwonlyargcount, p);
     389           0 :         w_long(co->co_nlocals, p);
     390           0 :         w_long(co->co_stacksize, p);
     391           0 :         w_long(co->co_flags, p);
     392           0 :         w_object(co->co_code, p);
     393           0 :         w_object(co->co_consts, p);
     394           0 :         w_object(co->co_names, p);
     395           0 :         w_object(co->co_varnames, p);
     396           0 :         w_object(co->co_freevars, p);
     397           0 :         w_object(co->co_cellvars, p);
     398           0 :         w_object(co->co_filename, p);
     399           0 :         w_object(co->co_name, p);
     400           0 :         w_long(co->co_firstlineno, p);
     401           0 :         w_object(co->co_lnotab, p);
     402             :     }
     403           0 :     else if (PyObject_CheckBuffer(v)) {
     404             :         /* Write unknown buffer-style objects as a string */
     405             :         char *s;
     406             :         Py_buffer view;
     407           0 :         if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
     408           0 :             w_byte(TYPE_UNKNOWN, p);
     409           0 :             p->depth--;
     410           0 :             p->error = WFERR_UNMARSHALLABLE;
     411             :             return;
     412             :         }
     413           0 :         w_byte(TYPE_STRING, p);
     414           0 :         n = view.len;
     415           0 :         s = view.buf;
     416             :         if (n > INT_MAX) {
     417             :             p->depth--;
     418             :             p->error = WFERR_UNMARSHALLABLE;
     419             :             return;
     420             :         }
     421           0 :         w_long((long)n, p);
     422           0 :         w_string(s, (int)n, p);
     423           0 :         PyBuffer_Release(&view);
     424             :     }
     425             :     else {
     426           0 :         w_byte(TYPE_UNKNOWN, p);
     427           0 :         p->error = WFERR_UNMARSHALLABLE;
     428             :     }
     429           0 :     p->depth--;
     430             : }
     431             : 
     432             : /* version currently has no effect for writing longs. */
     433             : void
     434           0 : PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
     435             : {
     436             :     WFILE wf;
     437           0 :     wf.fp = fp;
     438           0 :     wf.error = WFERR_OK;
     439           0 :     wf.depth = 0;
     440           0 :     wf.version = version;
     441           0 :     w_long(x, &wf);
     442           0 : }
     443             : 
     444             : void
     445           0 : PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
     446             : {
     447             :     WFILE wf;
     448           0 :     wf.fp = fp;
     449           0 :     wf.error = WFERR_OK;
     450           0 :     wf.depth = 0;
     451           0 :     wf.version = version;
     452           0 :     w_object(x, &wf);
     453           0 : }
     454             : 
     455             : typedef WFILE RFILE; /* Same struct with different invariants */
     456             : 
     457             : #define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
     458             : 
     459             : static int
     460       65341 : r_string(char *s, int n, RFILE *p)
     461             : {
     462             :     char *ptr;
     463             :     int read, left;
     464             : 
     465       65341 :     if (!p->readable) {
     466       65341 :         if (p->fp != NULL)
     467             :             /* The result fits into int because it must be <=n. */
     468           0 :             read = (int) fread(s, 1, n, p->fp);
     469             :         else {
     470       65341 :             left = (int)(p->end - p->ptr);
     471       65341 :             read = (left < n) ? left : n;
     472       65341 :             memcpy(s, p->ptr, read);
     473       65341 :             p->ptr += read;
     474             :         }
     475             :     }
     476             :     else {
     477             :         _Py_IDENTIFIER(read);
     478             : 
     479           0 :         PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "i", n);
     480           0 :         read = 0;
     481           0 :         if (data != NULL) {
     482           0 :             if (!PyBytes_Check(data)) {
     483           0 :                 PyErr_Format(PyExc_TypeError,
     484             :                              "f.read() returned not bytes but %.100s",
     485           0 :                              data->ob_type->tp_name);
     486             :             }
     487             :             else {
     488           0 :                 read = PyBytes_GET_SIZE(data);
     489           0 :                 if (read > 0) {
     490           0 :                     ptr = PyBytes_AS_STRING(data);
     491           0 :                     memcpy(s, ptr, read);
     492             :                 }
     493             :             }
     494           0 :             Py_DECREF(data);
     495             :         }
     496             :     }
     497       65341 :     if (!PyErr_Occurred() && (read < n)) {
     498           0 :         PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
     499             :     }
     500       65341 :     return read;
     501             : }
     502             : 
     503             : 
     504             : static int
     505       35168 : r_byte(RFILE *p)
     506             : {
     507       35168 :     int c = EOF;
     508             :     unsigned char ch;
     509             :     int n;
     510             : 
     511       35168 :     if (!p->readable)
     512       35168 :         c = p->fp ? getc(p->fp) : rs_byte(p);
     513             :     else {
     514           0 :         n = r_string((char *) &ch, 1, p);
     515           0 :         if (n > 0)
     516           0 :             c = ch;
     517             :     }
     518       35168 :     return c;
     519             : }
     520             : 
     521             : static int
     522          14 : r_short(RFILE *p)
     523             : {
     524             :     register short x;
     525             :     unsigned char buffer[2];
     526             : 
     527          14 :     r_string((char *) buffer, 2, p);
     528          14 :     x = buffer[0];
     529          14 :     x |= buffer[1] << 8;
     530             :     /* Sign-extension, in case short greater than 16 bits */
     531          14 :     x |= -(x & 0x8000);
     532          14 :     return x;
     533             : }
     534             : 
     535             : static long
     536       40473 : r_long(RFILE *p)
     537             : {
     538             :     register long x;
     539             :     unsigned char buffer[4];
     540             : 
     541       40473 :     r_string((char *) buffer, 4, p);
     542       40473 :     x = buffer[0];
     543       40473 :     x |= (long)buffer[1] << 8;
     544       40473 :     x |= (long)buffer[2] << 16;
     545       40473 :     x |= (long)buffer[3] << 24;
     546             : #if SIZEOF_LONG > 4
     547             :     /* Sign extension for 64-bit machines */
     548             :     x |= -(x & 0x80000000L);
     549             : #endif
     550       40473 :     return x;
     551             : }
     552             : 
     553             : /* r_long64 deals with the TYPE_INT64 code.  On a machine with
     554             :    sizeof(long) > 4, it returns a Python int object, else a Python long
     555             :    object.  Note that w_long64 writes out TYPE_INT if 32 bits is enough,
     556             :    so there's no inefficiency here in returning a PyLong on 32-bit boxes
     557             :    for everything written via TYPE_INT64 (i.e., if an int is written via
     558             :    TYPE_INT64, it *needs* more than 32 bits).
     559             : */
     560             : static PyObject *
     561           0 : r_long64(RFILE *p)
     562             : {
     563           0 :     PyObject *result = NULL;
     564           0 :     long lo4 = r_long(p);
     565           0 :     long hi4 = r_long(p);
     566             : 
     567           0 :     if (!PyErr_Occurred()) {
     568             : #if SIZEOF_LONG > 4
     569             :         long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
     570             :         result = PyLong_FromLong(x);
     571             : #else
     572             :         unsigned char buf[8];
     573           0 :         int one = 1;
     574           0 :         int is_little_endian = (int)*(char*)&one;
     575           0 :         if (is_little_endian) {
     576           0 :             memcpy(buf, &lo4, 4);
     577           0 :             memcpy(buf+4, &hi4, 4);
     578             :         }
     579             :         else {
     580           0 :             memcpy(buf, &hi4, 4);
     581           0 :             memcpy(buf+4, &lo4, 4);
     582             :         }
     583           0 :         result = _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
     584             : #endif
     585             :     }
     586           0 :     return result;
     587             : }
     588             : 
     589             : static PyObject *
     590           4 : r_PyLong(RFILE *p)
     591             : {
     592             :     PyLongObject *ob;
     593             :     int size, i, j, md, shorts_in_top_digit;
     594             :     long n;
     595             :     digit d;
     596             : 
     597           4 :     n = r_long(p);
     598           4 :     if (PyErr_Occurred())
     599           0 :         return NULL;
     600           4 :     if (n == 0)
     601           0 :         return (PyObject *)_PyLong_New(0);
     602           4 :     if (n < -INT_MAX || n > INT_MAX) {
     603           0 :         PyErr_SetString(PyExc_ValueError,
     604             :                        "bad marshal data (long size out of range)");
     605           0 :         return NULL;
     606             :     }
     607             : 
     608           4 :     size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
     609           4 :     shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
     610           4 :     ob = _PyLong_New(size);
     611           4 :     if (ob == NULL)
     612           0 :         return NULL;
     613           4 :     Py_SIZE(ob) = n > 0 ? size : -size;
     614             : 
     615          14 :     for (i = 0; i < size-1; i++) {
     616          10 :         d = 0;
     617          20 :         for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
     618          10 :             md = r_short(p);
     619          10 :             if (PyErr_Occurred())
     620           0 :                 break;
     621          10 :             if (md < 0 || md > PyLong_MARSHAL_BASE)
     622             :                 goto bad_digit;
     623          10 :             d += (digit)md << j*PyLong_MARSHAL_SHIFT;
     624             :         }
     625          10 :         ob->ob_digit[i] = d;
     626             :     }
     627           4 :     d = 0;
     628           8 :     for (j=0; j < shorts_in_top_digit; j++) {
     629           4 :         md = r_short(p);
     630           4 :         if (PyErr_Occurred())
     631           0 :             break;
     632           4 :         if (md < 0 || md > PyLong_MARSHAL_BASE)
     633             :             goto bad_digit;
     634             :         /* topmost marshal digit should be nonzero */
     635           4 :         if (md == 0 && j == shorts_in_top_digit - 1) {
     636           0 :             Py_DECREF(ob);
     637           0 :             PyErr_SetString(PyExc_ValueError,
     638             :                 "bad marshal data (unnormalized long data)");
     639           0 :             return NULL;
     640             :         }
     641           4 :         d += (digit)md << j*PyLong_MARSHAL_SHIFT;
     642             :     }
     643           4 :     if (PyErr_Occurred()) {
     644           0 :         Py_DECREF(ob);
     645           0 :         return NULL;
     646             :     }
     647             :     /* top digit should be nonzero, else the resulting PyLong won't be
     648             :        normalized */
     649           4 :     ob->ob_digit[size-1] = d;
     650           4 :     return (PyObject *)ob;
     651             :   bad_digit:
     652           0 :     Py_DECREF(ob);
     653           0 :     PyErr_SetString(PyExc_ValueError,
     654             :                     "bad marshal data (digit out of range in long)");
     655           0 :     return NULL;
     656             : }
     657             : 
     658             : 
     659             : static PyObject *
     660       35168 : r_object(RFILE *p)
     661             : {
     662             :     /* NULL is a valid return value, it does not necessarily means that
     663             :        an exception is set. */
     664             :     PyObject *v, *v2;
     665             :     long i, n;
     666       35168 :     int type = r_byte(p);
     667             :     PyObject *retval;
     668             : 
     669       35168 :     p->depth++;
     670             : 
     671       35168 :     if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
     672           0 :         p->depth--;
     673           0 :         PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
     674           0 :         return NULL;
     675             :     }
     676             : 
     677       35168 :     switch (type) {
     678             : 
     679             :     case EOF:
     680           0 :         PyErr_SetString(PyExc_EOFError,
     681             :                         "EOF read where object expected");
     682           0 :         retval = NULL;
     683           0 :         break;
     684             : 
     685             :     case TYPE_NULL:
     686           0 :         retval = NULL;
     687           0 :         break;
     688             : 
     689             :     case TYPE_NONE:
     690        1104 :         Py_INCREF(Py_None);
     691        1104 :         retval = Py_None;
     692        1104 :         break;
     693             : 
     694             :     case TYPE_STOPITER:
     695           0 :         Py_INCREF(PyExc_StopIteration);
     696           0 :         retval = PyExc_StopIteration;
     697           0 :         break;
     698             : 
     699             :     case TYPE_ELLIPSIS:
     700           0 :         Py_INCREF(Py_Ellipsis);
     701           0 :         retval = Py_Ellipsis;
     702           0 :         break;
     703             : 
     704             :     case TYPE_FALSE:
     705          75 :         Py_INCREF(Py_False);
     706          75 :         retval = Py_False;
     707          75 :         break;
     708             : 
     709             :     case TYPE_TRUE:
     710          70 :         Py_INCREF(Py_True);
     711          70 :         retval = Py_True;
     712          70 :         break;
     713             : 
     714             :     case TYPE_INT:
     715        1062 :         n = r_long(p);
     716        1062 :         retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
     717        1062 :         break;
     718             : 
     719             :     case TYPE_INT64:
     720           0 :         retval = r_long64(p);
     721           0 :         break;
     722             : 
     723             :     case TYPE_LONG:
     724           4 :         retval = r_PyLong(p);
     725           4 :         break;
     726             : 
     727             :     case TYPE_FLOAT:
     728             :         {
     729             :             char buf[256];
     730             :             double dx;
     731           0 :             retval = NULL;
     732           0 :             n = r_byte(p);
     733           0 :             if (n == EOF || r_string(buf, (int)n, p) != n) {
     734           0 :                 PyErr_SetString(PyExc_EOFError,
     735             :                     "EOF read where object expected");
     736             :                 break;
     737             :             }
     738           0 :             buf[n] = '\0';
     739           0 :             dx = PyOS_string_to_double(buf, NULL, NULL);
     740           0 :             if (dx == -1.0 && PyErr_Occurred())
     741             :                 break;
     742           0 :             retval = PyFloat_FromDouble(dx);
     743             :             break;
     744             :         }
     745             : 
     746             :     case TYPE_BINARY_FLOAT:
     747             :         {
     748             :             unsigned char buf[8];
     749             :             double x;
     750           1 :             if (r_string((char*)buf, 8, p) != 8) {
     751           0 :                 PyErr_SetString(PyExc_EOFError,
     752             :                     "EOF read where object expected");
     753           0 :                 retval = NULL;
     754             :                 break;
     755             :             }
     756           1 :             x = _PyFloat_Unpack8(buf, 1);
     757           1 :             if (x == -1.0 && PyErr_Occurred()) {
     758           0 :                 retval = NULL;
     759             :                 break;
     760             :             }
     761           1 :             retval = PyFloat_FromDouble(x);
     762             :             break;
     763             :         }
     764             : 
     765             :     case TYPE_COMPLEX:
     766             :         {
     767             :             char buf[256];
     768             :             Py_complex c;
     769           0 :             retval = NULL;
     770           0 :             n = r_byte(p);
     771           0 :             if (n == EOF || r_string(buf, (int)n, p) != n) {
     772           0 :                 PyErr_SetString(PyExc_EOFError,
     773             :                     "EOF read where object expected");
     774             :                 break;
     775             :             }
     776           0 :             buf[n] = '\0';
     777           0 :             c.real = PyOS_string_to_double(buf, NULL, NULL);
     778           0 :             if (c.real == -1.0 && PyErr_Occurred())
     779             :                 break;
     780           0 :             n = r_byte(p);
     781           0 :             if (n == EOF || r_string(buf, (int)n, p) != n) {
     782           0 :                 PyErr_SetString(PyExc_EOFError,
     783             :                     "EOF read where object expected");
     784             :                 break;
     785             :             }
     786           0 :             buf[n] = '\0';
     787           0 :             c.imag = PyOS_string_to_double(buf, NULL, NULL);
     788           0 :             if (c.imag == -1.0 && PyErr_Occurred())
     789             :                 break;
     790           0 :             retval = PyComplex_FromCComplex(c);
     791             :             break;
     792             :         }
     793             : 
     794             :     case TYPE_BINARY_COMPLEX:
     795             :         {
     796             :             unsigned char buf[8];
     797             :             Py_complex c;
     798           0 :             if (r_string((char*)buf, 8, p) != 8) {
     799           0 :                 PyErr_SetString(PyExc_EOFError,
     800             :                     "EOF read where object expected");
     801           0 :                 retval = NULL;
     802             :                 break;
     803             :             }
     804           0 :             c.real = _PyFloat_Unpack8(buf, 1);
     805           0 :             if (c.real == -1.0 && PyErr_Occurred()) {
     806           0 :                 retval = NULL;
     807             :                 break;
     808             :             }
     809           0 :             if (r_string((char*)buf, 8, p) != 8) {
     810           0 :                 PyErr_SetString(PyExc_EOFError,
     811             :                     "EOF read where object expected");
     812           0 :                 retval = NULL;
     813             :                 break;
     814             :             }
     815           0 :             c.imag = _PyFloat_Unpack8(buf, 1);
     816           0 :             if (c.imag == -1.0 && PyErr_Occurred()) {
     817           0 :                 retval = NULL;
     818             :                 break;
     819             :             }
     820           0 :             retval = PyComplex_FromCComplex(c);
     821             :             break;
     822             :         }
     823             : 
     824             :     case TYPE_STRING:
     825        2663 :         n = r_long(p);
     826        2663 :         if (PyErr_Occurred()) {
     827           0 :             retval = NULL;
     828           0 :             break;
     829             :         }
     830        2663 :         if (n < 0 || n > INT_MAX) {
     831           0 :             PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
     832           0 :             retval = NULL;
     833           0 :             break;
     834             :         }
     835        2663 :         v = PyBytes_FromStringAndSize((char *)NULL, n);
     836        2663 :         if (v == NULL) {
     837           0 :             retval = NULL;
     838           0 :             break;
     839             :         }
     840        2663 :         if (r_string(PyBytes_AS_STRING(v), (int)n, p) != n) {
     841           0 :             Py_DECREF(v);
     842           0 :             PyErr_SetString(PyExc_EOFError,
     843             :                             "EOF read where object expected");
     844           0 :             retval = NULL;
     845           0 :             break;
     846             :         }
     847        2663 :         retval = v;
     848        2663 :         break;
     849             : 
     850             :     case TYPE_UNICODE:
     851             :         {
     852             :         char *buffer;
     853             : 
     854       22190 :         n = r_long(p);
     855       22190 :         if (PyErr_Occurred()) {
     856           0 :             retval = NULL;
     857           0 :             break;
     858             :         }
     859       22190 :         if (n < 0 || n > INT_MAX) {
     860           0 :             PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
     861           0 :             retval = NULL;
     862           0 :             break;
     863             :         }
     864       22190 :         buffer = PyMem_NEW(char, n);
     865       22190 :         if (buffer == NULL) {
     866           0 :             retval = PyErr_NoMemory();
     867           0 :             break;
     868             :         }
     869       22190 :         if (r_string(buffer, (int)n, p) != n) {
     870           0 :             PyMem_DEL(buffer);
     871           0 :             PyErr_SetString(PyExc_EOFError,
     872             :                 "EOF read where object expected");
     873           0 :             retval = NULL;
     874           0 :             break;
     875             :         }
     876       22190 :         v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
     877       22190 :         PyMem_DEL(buffer);
     878       22190 :         retval = v;
     879       22190 :         break;
     880             :         }
     881             : 
     882             :     case TYPE_TUPLE:
     883        6687 :         n = r_long(p);
     884        6687 :         if (PyErr_Occurred()) {
     885           0 :             retval = NULL;
     886           0 :             break;
     887             :         }
     888        6687 :         if (n < 0 || n > INT_MAX) {
     889           0 :             PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
     890           0 :             retval = NULL;
     891           0 :             break;
     892             :         }
     893        6687 :         v = PyTuple_New((int)n);
     894        6687 :         if (v == NULL) {
     895           0 :             retval = NULL;
     896           0 :             break;
     897             :         }
     898       30007 :         for (i = 0; i < n; i++) {
     899       23320 :             v2 = r_object(p);
     900       23320 :             if ( v2 == NULL ) {
     901           0 :                 if (!PyErr_Occurred())
     902           0 :                     PyErr_SetString(PyExc_TypeError,
     903             :                         "NULL object in marshal data for tuple");
     904           0 :                 Py_DECREF(v);
     905           0 :                 v = NULL;
     906           0 :                 break;
     907             :             }
     908       23320 :             PyTuple_SET_ITEM(v, (int)i, v2);
     909             :         }
     910        6687 :         retval = v;
     911        6687 :         break;
     912             : 
     913             :     case TYPE_LIST:
     914           0 :         n = r_long(p);
     915           0 :         if (PyErr_Occurred()) {
     916           0 :             retval = NULL;
     917           0 :             break;
     918             :         }
     919           0 :         if (n < 0 || n > INT_MAX) {
     920           0 :             PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
     921           0 :             retval = NULL;
     922           0 :             break;
     923             :         }
     924           0 :         v = PyList_New((int)n);
     925           0 :         if (v == NULL) {
     926           0 :             retval = NULL;
     927           0 :             break;
     928             :         }
     929           0 :         for (i = 0; i < n; i++) {
     930           0 :             v2 = r_object(p);
     931           0 :             if ( v2 == NULL ) {
     932           0 :                 if (!PyErr_Occurred())
     933           0 :                     PyErr_SetString(PyExc_TypeError,
     934             :                         "NULL object in marshal data for list");
     935           0 :                 Py_DECREF(v);
     936           0 :                 v = NULL;
     937           0 :                 break;
     938             :             }
     939           0 :             PyList_SET_ITEM(v, (int)i, v2);
     940             :         }
     941           0 :         retval = v;
     942           0 :         break;
     943             : 
     944             :     case TYPE_DICT:
     945           0 :         v = PyDict_New();
     946           0 :         if (v == NULL) {
     947           0 :             retval = NULL;
     948           0 :             break;
     949             :         }
     950             :         for (;;) {
     951             :             PyObject *key, *val;
     952           0 :             key = r_object(p);
     953           0 :             if (key == NULL)
     954           0 :                 break;
     955           0 :             val = r_object(p);
     956           0 :             if (val != NULL)
     957           0 :                 PyDict_SetItem(v, key, val);
     958           0 :             Py_DECREF(key);
     959           0 :             Py_XDECREF(val);
     960           0 :         }
     961           0 :         if (PyErr_Occurred()) {
     962           0 :             Py_DECREF(v);
     963           0 :             v = NULL;
     964             :         }
     965           0 :         retval = v;
     966           0 :         break;
     967             : 
     968             :     case TYPE_SET:
     969             :     case TYPE_FROZENSET:
     970           1 :         n = r_long(p);
     971           1 :         if (PyErr_Occurred()) {
     972           0 :             retval = NULL;
     973           0 :             break;
     974             :         }
     975           1 :         if (n < 0 || n > INT_MAX) {
     976           0 :             PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
     977           0 :             retval = NULL;
     978           0 :             break;
     979             :         }
     980           1 :         v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
     981           1 :         if (v == NULL) {
     982           0 :             retval = NULL;
     983           0 :             break;
     984             :         }
     985           4 :         for (i = 0; i < n; i++) {
     986           3 :             v2 = r_object(p);
     987           3 :             if ( v2 == NULL ) {
     988           0 :                 if (!PyErr_Occurred())
     989           0 :                     PyErr_SetString(PyExc_TypeError,
     990             :                         "NULL object in marshal data for set");
     991           0 :                 Py_DECREF(v);
     992           0 :                 v = NULL;
     993           0 :                 break;
     994             :             }
     995           3 :             if (PySet_Add(v, v2) == -1) {
     996           0 :                 Py_DECREF(v);
     997           0 :                 Py_DECREF(v2);
     998           0 :                 v = NULL;
     999           0 :                 break;
    1000             :             }
    1001           3 :             Py_DECREF(v2);
    1002             :         }
    1003           1 :         retval = v;
    1004           1 :         break;
    1005             : 
    1006             :     case TYPE_CODE:
    1007             :         {
    1008             :             int argcount;
    1009             :             int kwonlyargcount;
    1010             :             int nlocals;
    1011             :             int stacksize;
    1012             :             int flags;
    1013        1311 :             PyObject *code = NULL;
    1014        1311 :             PyObject *consts = NULL;
    1015        1311 :             PyObject *names = NULL;
    1016        1311 :             PyObject *varnames = NULL;
    1017        1311 :             PyObject *freevars = NULL;
    1018        1311 :             PyObject *cellvars = NULL;
    1019        1311 :             PyObject *filename = NULL;
    1020        1311 :             PyObject *name = NULL;
    1021             :             int firstlineno;
    1022        1311 :             PyObject *lnotab = NULL;
    1023             : 
    1024        1311 :             v = NULL;
    1025             : 
    1026             :             /* XXX ignore long->int overflows for now */
    1027        1311 :             argcount = (int)r_long(p);
    1028        1311 :             if (PyErr_Occurred())
    1029           0 :                 goto code_error;
    1030        1311 :             kwonlyargcount = (int)r_long(p);
    1031        1311 :             if (PyErr_Occurred())
    1032           0 :                 goto code_error;
    1033        1311 :             nlocals = (int)r_long(p);
    1034        1311 :             if (PyErr_Occurred())
    1035           0 :                 goto code_error;
    1036        1311 :             stacksize = (int)r_long(p);
    1037        1311 :             if (PyErr_Occurred())
    1038           0 :                 goto code_error;
    1039        1311 :             flags = (int)r_long(p);
    1040        1311 :             if (PyErr_Occurred())
    1041           0 :                 goto code_error;
    1042        1311 :             code = r_object(p);
    1043        1311 :             if (code == NULL)
    1044           0 :                 goto code_error;
    1045        1311 :             consts = r_object(p);
    1046        1311 :             if (consts == NULL)
    1047           0 :                 goto code_error;
    1048        1311 :             names = r_object(p);
    1049        1311 :             if (names == NULL)
    1050           0 :                 goto code_error;
    1051        1311 :             varnames = r_object(p);
    1052        1311 :             if (varnames == NULL)
    1053           0 :                 goto code_error;
    1054        1311 :             freevars = r_object(p);
    1055        1311 :             if (freevars == NULL)
    1056           0 :                 goto code_error;
    1057        1311 :             cellvars = r_object(p);
    1058        1311 :             if (cellvars == NULL)
    1059           0 :                 goto code_error;
    1060        1311 :             filename = r_object(p);
    1061        1311 :             if (filename == NULL)
    1062           0 :                 goto code_error;
    1063        1311 :             if (PyUnicode_CheckExact(filename)) {
    1064        1311 :                 if (p->current_filename != NULL) {
    1065        1265 :                     if (!PyUnicode_Compare(filename, p->current_filename)) {
    1066        1265 :                         Py_DECREF(filename);
    1067        1265 :                         Py_INCREF(p->current_filename);
    1068        1265 :                         filename = p->current_filename;
    1069             :                     }
    1070             :                 }
    1071             :                 else {
    1072          46 :                     p->current_filename = filename;
    1073             :                 }
    1074             :             }
    1075        1311 :             name = r_object(p);
    1076        1311 :             if (name == NULL)
    1077           0 :                 goto code_error;
    1078        1311 :             firstlineno = (int)r_long(p);
    1079        1311 :             lnotab = r_object(p);
    1080        1311 :             if (lnotab == NULL)
    1081           0 :                 goto code_error;
    1082             : 
    1083        1311 :             v = (PyObject *) PyCode_New(
    1084             :                             argcount, kwonlyargcount,
    1085             :                             nlocals, stacksize, flags,
    1086             :                             code, consts, names, varnames,
    1087             :                             freevars, cellvars, filename, name,
    1088             :                             firstlineno, lnotab);
    1089             : 
    1090             :           code_error:
    1091        1311 :             Py_XDECREF(code);
    1092        1311 :             Py_XDECREF(consts);
    1093        1311 :             Py_XDECREF(names);
    1094        1311 :             Py_XDECREF(varnames);
    1095        1311 :             Py_XDECREF(freevars);
    1096        1311 :             Py_XDECREF(cellvars);
    1097        1311 :             Py_XDECREF(filename);
    1098        1311 :             Py_XDECREF(name);
    1099        1311 :             Py_XDECREF(lnotab);
    1100             :         }
    1101        1311 :         retval = v;
    1102        1311 :         break;
    1103             : 
    1104             :     default:
    1105             :         /* Bogus data got written, which isn't ideal.
    1106             :            This will let you keep working and recover. */
    1107           0 :         PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
    1108           0 :         retval = NULL;
    1109           0 :         break;
    1110             : 
    1111             :     }
    1112       35168 :     p->depth--;
    1113       35168 :     return retval;
    1114             : }
    1115             : 
    1116             : static PyObject *
    1117          45 : read_object(RFILE *p)
    1118             : {
    1119             :     PyObject *v;
    1120          45 :     if (PyErr_Occurred()) {
    1121           0 :         fprintf(stderr, "XXX readobject called with exception set\n");
    1122           0 :         return NULL;
    1123             :     }
    1124          45 :     v = r_object(p);
    1125          45 :     if (v == NULL && !PyErr_Occurred())
    1126           0 :         PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
    1127          45 :     return v;
    1128             : }
    1129             : 
    1130             : int
    1131           0 : PyMarshal_ReadShortFromFile(FILE *fp)
    1132             : {
    1133             :     RFILE rf;
    1134             :     assert(fp);
    1135           0 :     rf.readable = NULL;
    1136           0 :     rf.fp = fp;
    1137           0 :     rf.current_filename = NULL;
    1138           0 :     rf.end = rf.ptr = NULL;
    1139           0 :     return r_short(&rf);
    1140             : }
    1141             : 
    1142             : long
    1143           0 : PyMarshal_ReadLongFromFile(FILE *fp)
    1144             : {
    1145             :     RFILE rf;
    1146           0 :     rf.fp = fp;
    1147           0 :     rf.readable = NULL;
    1148           0 :     rf.current_filename = NULL;
    1149           0 :     rf.ptr = rf.end = NULL;
    1150           0 :     return r_long(&rf);
    1151             : }
    1152             : 
    1153             : #ifdef HAVE_FSTAT
    1154             : /* Return size of file in bytes; < 0 if unknown. */
    1155             : static off_t
    1156           0 : getfilesize(FILE *fp)
    1157             : {
    1158             :     struct stat st;
    1159           0 :     if (fstat(fileno(fp), &st) != 0)
    1160           0 :         return -1;
    1161             :     else
    1162           0 :         return st.st_size;
    1163             : }
    1164             : #endif
    1165             : 
    1166             : /* If we can get the size of the file up-front, and it's reasonably small,
    1167             :  * read it in one gulp and delegate to ...FromString() instead.  Much quicker
    1168             :  * than reading a byte at a time from file; speeds .pyc imports.
    1169             :  * CAUTION:  since this may read the entire remainder of the file, don't
    1170             :  * call it unless you know you're done with the file.
    1171             :  */
    1172             : PyObject *
    1173           0 : PyMarshal_ReadLastObjectFromFile(FILE *fp)
    1174             : {
    1175             : /* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
    1176             : #define REASONABLE_FILE_LIMIT (1L << 18)
    1177             : #ifdef HAVE_FSTAT
    1178             :     off_t filesize;
    1179           0 :     filesize = getfilesize(fp);
    1180           0 :     if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
    1181           0 :         char* pBuf = (char *)PyMem_MALLOC(filesize);
    1182           0 :         if (pBuf != NULL) {
    1183             :             PyObject* v;
    1184             :             size_t n;
    1185             :             /* filesize must fit into an int, because it
    1186             :                is smaller than REASONABLE_FILE_LIMIT */
    1187           0 :             n = fread(pBuf, 1, (int)filesize, fp);
    1188           0 :             v = PyMarshal_ReadObjectFromString(pBuf, n);
    1189           0 :             PyMem_FREE(pBuf);
    1190           0 :             return v;
    1191             :         }
    1192             : 
    1193             :     }
    1194             : #endif
    1195             :     /* We don't have fstat, or we do but the file is larger than
    1196             :      * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
    1197             :      */
    1198           0 :     return PyMarshal_ReadObjectFromFile(fp);
    1199             : 
    1200             : #undef REASONABLE_FILE_LIMIT
    1201             : }
    1202             : 
    1203             : PyObject *
    1204           0 : PyMarshal_ReadObjectFromFile(FILE *fp)
    1205             : {
    1206             :     RFILE rf;
    1207             :     PyObject *result;
    1208           0 :     rf.fp = fp;
    1209           0 :     rf.readable = NULL;
    1210           0 :     rf.current_filename = NULL;
    1211           0 :     rf.depth = 0;
    1212           0 :     rf.ptr = rf.end = NULL;
    1213           0 :     result = r_object(&rf);
    1214           0 :     return result;
    1215             : }
    1216             : 
    1217             : PyObject *
    1218           1 : PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
    1219             : {
    1220             :     RFILE rf;
    1221             :     PyObject *result;
    1222           1 :     rf.fp = NULL;
    1223           1 :     rf.readable = NULL;
    1224           1 :     rf.current_filename = NULL;
    1225           1 :     rf.ptr = str;
    1226           1 :     rf.end = str + len;
    1227           1 :     rf.depth = 0;
    1228           1 :     result = r_object(&rf);
    1229           1 :     return result;
    1230             : }
    1231             : 
    1232             : PyObject *
    1233           0 : PyMarshal_WriteObjectToString(PyObject *x, int version)
    1234             : {
    1235             :     WFILE wf;
    1236             : 
    1237           0 :     wf.fp = NULL;
    1238           0 :     wf.readable = NULL;
    1239           0 :     wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
    1240           0 :     if (wf.str == NULL)
    1241           0 :         return NULL;
    1242           0 :     wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str);
    1243           0 :     wf.end = wf.ptr + PyBytes_Size(wf.str);
    1244           0 :     wf.error = WFERR_OK;
    1245           0 :     wf.depth = 0;
    1246           0 :     wf.version = version;
    1247           0 :     w_object(x, &wf);
    1248           0 :     if (wf.str != NULL) {
    1249           0 :         char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
    1250             :         if (wf.ptr - base > PY_SSIZE_T_MAX) {
    1251             :             Py_DECREF(wf.str);
    1252             :             PyErr_SetString(PyExc_OverflowError,
    1253             :                             "too much marshal data for a string");
    1254             :             return NULL;
    1255             :         }
    1256           0 :         if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
    1257           0 :             return NULL;
    1258             :     }
    1259           0 :     if (wf.error != WFERR_OK) {
    1260           0 :         Py_XDECREF(wf.str);
    1261           0 :         if (wf.error == WFERR_NOMEMORY)
    1262           0 :             PyErr_NoMemory();
    1263             :         else
    1264           0 :             PyErr_SetString(PyExc_ValueError,
    1265           0 :               (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
    1266             :                :"object too deeply nested to marshal");
    1267           0 :         return NULL;
    1268             :     }
    1269           0 :     return wf.str;
    1270             : }
    1271             : 
    1272             : /* And an interface for Python programs... */
    1273             : 
    1274             : static PyObject *
    1275           0 : marshal_dump(PyObject *self, PyObject *args)
    1276             : {
    1277             :     /* XXX Quick hack -- need to do this differently */
    1278             :     PyObject *x;
    1279             :     PyObject *f;
    1280           0 :     int version = Py_MARSHAL_VERSION;
    1281             :     PyObject *s;
    1282             :     PyObject *res;
    1283             :     _Py_IDENTIFIER(write);
    1284             : 
    1285           0 :     if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
    1286           0 :         return NULL;
    1287           0 :     s = PyMarshal_WriteObjectToString(x, version);
    1288           0 :     if (s == NULL)
    1289           0 :         return NULL;
    1290           0 :     res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
    1291           0 :     Py_DECREF(s);
    1292           0 :     return res;
    1293             : }
    1294             : 
    1295             : PyDoc_STRVAR(dump_doc,
    1296             : "dump(value, file[, version])\n\
    1297             : \n\
    1298             : Write the value on the open file. The value must be a supported type.\n\
    1299             : The file must be an open file object such as sys.stdout or returned by\n\
    1300             : open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
    1301             : \n\
    1302             : If the value has (or contains an object that has) an unsupported type, a\n\
    1303             : ValueError exception is raised — but garbage data will also be written\n\
    1304             : to the file. The object will not be properly read back by load()\n\
    1305             : \n\
    1306             : The version argument indicates the data format that dump should use.");
    1307             : 
    1308             : static PyObject *
    1309           0 : marshal_load(PyObject *self, PyObject *f)
    1310             : {
    1311             :     PyObject *data, *result;
    1312             :     _Py_IDENTIFIER(read);
    1313             :     RFILE rf;
    1314             : 
    1315             :     /*
    1316             :      * Make a call to the read method, but read zero bytes.
    1317             :      * This is to ensure that the object passed in at least
    1318             :      * has a read method which returns bytes.
    1319             :      */
    1320           0 :     data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
    1321           0 :     if (data == NULL)
    1322           0 :         return NULL;
    1323           0 :     if (!PyBytes_Check(data)) {
    1324           0 :         PyErr_Format(PyExc_TypeError,
    1325             :                      "f.read() returned not bytes but %.100s",
    1326           0 :                      data->ob_type->tp_name);
    1327           0 :         result = NULL;
    1328             :     }
    1329             :     else {
    1330           0 :         rf.depth = 0;
    1331           0 :         rf.fp = NULL;
    1332           0 :         rf.readable = f;
    1333           0 :         rf.current_filename = NULL;
    1334           0 :         result = read_object(&rf);
    1335             :     }
    1336           0 :     Py_DECREF(data);
    1337           0 :     return result;
    1338             : }
    1339             : 
    1340             : PyDoc_STRVAR(load_doc,
    1341             : "load(file)\n\
    1342             : \n\
    1343             : Read one value from the open file and return it. If no valid value is\n\
    1344             : read (e.g. because the data has a different Python version’s\n\
    1345             : incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
    1346             : The file must be an open file object opened in binary mode ('rb' or\n\
    1347             : 'r+b').\n\
    1348             : \n\
    1349             : Note: If an object containing an unsupported type was marshalled with\n\
    1350             : dump(), load() will substitute None for the unmarshallable type.");
    1351             : 
    1352             : 
    1353             : static PyObject *
    1354           0 : marshal_dumps(PyObject *self, PyObject *args)
    1355             : {
    1356             :     PyObject *x;
    1357           0 :     int version = Py_MARSHAL_VERSION;
    1358           0 :     if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
    1359           0 :         return NULL;
    1360           0 :     return PyMarshal_WriteObjectToString(x, version);
    1361             : }
    1362             : 
    1363             : PyDoc_STRVAR(dumps_doc,
    1364             : "dumps(value[, version])\n\
    1365             : \n\
    1366             : Return the string that would be written to a file by dump(value, file).\n\
    1367             : The value must be a supported type. Raise a ValueError exception if\n\
    1368             : value has (or contains an object that has) an unsupported type.\n\
    1369             : \n\
    1370             : The version argument indicates the data format that dumps should use.");
    1371             : 
    1372             : 
    1373             : static PyObject *
    1374          45 : marshal_loads(PyObject *self, PyObject *args)
    1375             : {
    1376             :     RFILE rf;
    1377             :     Py_buffer p;
    1378             :     char *s;
    1379             :     Py_ssize_t n;
    1380             :     PyObject* result;
    1381          45 :     if (!PyArg_ParseTuple(args, "y*:loads", &p))
    1382           0 :         return NULL;
    1383          45 :     s = p.buf;
    1384          45 :     n = p.len;
    1385          45 :     rf.fp = NULL;
    1386          45 :     rf.readable = NULL;
    1387          45 :     rf.current_filename = NULL;
    1388          45 :     rf.ptr = s;
    1389          45 :     rf.end = s + n;
    1390          45 :     rf.depth = 0;
    1391          45 :     result = read_object(&rf);
    1392          45 :     PyBuffer_Release(&p);
    1393          45 :     return result;
    1394             : }
    1395             : 
    1396             : PyDoc_STRVAR(loads_doc,
    1397             : "loads(bytes)\n\
    1398             : \n\
    1399             : Convert the bytes object to a value. If no valid value is found, raise\n\
    1400             : EOFError, ValueError or TypeError. Extra characters in the input are\n\
    1401             : ignored.");
    1402             : 
    1403             : static PyMethodDef marshal_methods[] = {
    1404             :     {"dump",            marshal_dump,   METH_VARARGS,   dump_doc},
    1405             :     {"load",            marshal_load,   METH_O,         load_doc},
    1406             :     {"dumps",           marshal_dumps,  METH_VARARGS,   dumps_doc},
    1407             :     {"loads",           marshal_loads,  METH_VARARGS,   loads_doc},
    1408             :     {NULL,              NULL}           /* sentinel */
    1409             : };
    1410             : 
    1411             : 
    1412             : PyDoc_STRVAR(module_doc,
    1413             : "This module contains functions that can read and write Python values in\n\
    1414             : a binary format. The format is specific to Python, but independent of\n\
    1415             : machine architecture issues.\n\
    1416             : \n\
    1417             : Not all Python object types are supported; in general, only objects\n\
    1418             : whose value is independent from a particular invocation of Python can be\n\
    1419             : written and read by this module. The following types are supported:\n\
    1420             : None, integers, floating point numbers, strings, bytes, bytearrays,\n\
    1421             : tuples, lists, sets, dictionaries, and code objects, where it\n\
    1422             : should be understood that tuples, lists and dictionaries are only\n\
    1423             : supported as long as the values contained therein are themselves\n\
    1424             : supported; and recursive lists and dictionaries should not be written\n\
    1425             : (they will cause infinite loops).\n\
    1426             : \n\
    1427             : Variables:\n\
    1428             : \n\
    1429             : version -- indicates the format that the module uses. Version 0 is the\n\
    1430             :     historical format, version 1 shares interned strings and version 2\n\
    1431             :     uses a binary format for floating point numbers.\n\
    1432             : \n\
    1433             : Functions:\n\
    1434             : \n\
    1435             : dump() -- write value to a file\n\
    1436             : load() -- read value from a file\n\
    1437             : dumps() -- write value to a string\n\
    1438             : loads() -- read value from a string");
    1439             : 
    1440             : 
    1441             : 
    1442             : static struct PyModuleDef marshalmodule = {
    1443             :     PyModuleDef_HEAD_INIT,
    1444             :     "marshal",
    1445             :     module_doc,
    1446             :     0,
    1447             :     marshal_methods,
    1448             :     NULL,
    1449             :     NULL,
    1450             :     NULL,
    1451             :     NULL
    1452             : };
    1453             : 
    1454             : PyMODINIT_FUNC
    1455           1 : PyMarshal_Init(void)
    1456             : {
    1457           1 :     PyObject *mod = PyModule_Create(&marshalmodule);
    1458           1 :     if (mod == NULL)
    1459           0 :         return NULL;
    1460           1 :     PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
    1461           1 :     return mod;
    1462             : }

Generated by: LCOV version 1.10