LCOV - code coverage report
Current view: top level - Python - marshal.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 278 732 38.0 %
Date: 2017-04-19 Functions: 16 30 53.3 %

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

Generated by: LCOV version 1.10