blob: 6b285aaa41ed30d6450f4628908bf088687b37c7 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001
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
Thomas Wouters695934a2006-03-01 23:49:13 +00007#define PY_SSIZE_T_CLEAN
8
Guido van Rossum79f25d91997-04-29 20:08:16 +00009#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000010#include "longintrepr.h"
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000011#include "code.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000012#include "marshal.h"
13
Mark Dickinsonefc82f72009-03-20 15:51:55 +000014#define ABS(x) ((x) < 0 ? -(x) : (x))
15
Fred Drake6da0b912000-06-28 18:47:56 +000016/* 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 */
Neal Norwitzf6b0e4d2007-05-17 07:04:46 +000020#define MAX_MARSHAL_STACK_DEPTH 2000
Fred Drake6da0b912000-06-28 18:47:56 +000021
Antoine Pitrouc83ea132010-05-09 14:46:46 +000022#define TYPE_NULL '0'
23#define TYPE_NONE 'N'
24#define TYPE_FALSE 'F'
25#define TYPE_TRUE 'T'
26#define TYPE_STOPITER 'S'
27#define TYPE_ELLIPSIS '.'
28#define TYPE_INT 'i'
29#define TYPE_INT64 'I'
30#define TYPE_FLOAT 'f'
31#define TYPE_BINARY_FLOAT 'g'
32#define TYPE_COMPLEX 'x'
33#define TYPE_BINARY_COMPLEX 'y'
34#define TYPE_LONG 'l'
35#define TYPE_STRING 's'
36#define TYPE_INTERNED 't'
37#define TYPE_STRINGREF 'R'
38#define TYPE_TUPLE '('
39#define TYPE_LIST '['
40#define TYPE_DICT '{'
41#define TYPE_CODE 'c'
42#define TYPE_UNICODE 'u'
43#define TYPE_UNKNOWN '?'
44#define TYPE_SET '<'
45#define TYPE_FROZENSET '>'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000046
Eric Smith15669272009-10-19 00:34:12 +000047#define WFERR_OK 0
48#define WFERR_UNMARSHALLABLE 1
49#define WFERR_NESTEDTOODEEP 2
50#define WFERR_NOMEMORY 3
51
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000052typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000053 FILE *fp;
54 int error; /* see WFERR_* values */
55 int depth;
56 /* If fp == NULL, the following are valid: */
57 PyObject *str;
58 char *ptr;
59 char *end;
60 PyObject *strings; /* dict on marshal, list on unmarshal */
61 int version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000062} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000063
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000064#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
Antoine Pitrouc83ea132010-05-09 14:46:46 +000065 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
66 else w_more(c, p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000067
68static void
Fredrik Lundh11534382000-07-23 18:24:06 +000069w_more(int c, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 Py_ssize_t size, newsize;
72 if (p->str == NULL)
73 return; /* An error already occurred */
74 size = PyString_Size(p->str);
75 newsize = size + size + 1024;
76 if (newsize > 32*1024*1024) {
77 newsize = size + (size >> 3); /* 12.5% overallocation */
78 }
79 if (_PyString_Resize(&p->str, newsize) != 0) {
80 p->ptr = p->end = NULL;
81 }
82 else {
83 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
84 p->end =
85 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
86 *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
87 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000088}
89
90static void
Serhiy Storchakafe2e8392013-07-11 19:14:07 +030091w_string(const char *s, Py_ssize_t n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000092{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 if (p->fp != NULL) {
94 fwrite(s, 1, n, p->fp);
95 }
96 else {
97 while (--n >= 0) {
98 w_byte(*s, p);
99 s++;
100 }
101 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000102}
103
104static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000105w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000106{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000107 w_byte((char)( x & 0xff), p);
108 w_byte((char)((x>> 8) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000109}
110
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000112w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000113{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000114 w_byte((char)( x & 0xff), p);
115 w_byte((char)((x>> 8) & 0xff), p);
116 w_byte((char)((x>>16) & 0xff), p);
117 w_byte((char)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000118}
119
Guido van Rossumc1547d91996-12-10 15:39:04 +0000120#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000121static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000122w_long64(long x, WFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000123{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000124 w_long(x, p);
125 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000126}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000127#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000128
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200129#define SIZE32_MAX 0x7FFFFFFF
130
131#if SIZEOF_SIZE_T > 4
132# define W_SIZE(n, p) do { \
133 if ((n) > SIZE32_MAX) { \
134 (p)->depth--; \
135 (p)->error = WFERR_UNMARSHALLABLE; \
136 return; \
137 } \
138 w_long((long)(n), p); \
139 } while(0)
140#else
141# define W_SIZE w_long
142#endif
143
Serhiy Storchakafe2e8392013-07-11 19:14:07 +0300144static void
145w_pstring(const char *s, Py_ssize_t n, WFILE *p)
146{
147 W_SIZE(n, p);
148 w_string(s, n, p);
149}
150
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000151/* We assume that Python longs are stored internally in base some power of
152 2**15; for the sake of portability we'll always read and write them in base
153 exactly 2**15. */
154
155#define PyLong_MARSHAL_SHIFT 15
156#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
157#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
158#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
159#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
160#endif
161#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
162
163static void
164w_PyLong(const PyLongObject *ob, WFILE *p)
165{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000166 Py_ssize_t i, j, n, l;
167 digit d;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000168
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000169 w_byte(TYPE_LONG, p);
170 if (Py_SIZE(ob) == 0) {
171 w_long((long)0, p);
172 return;
173 }
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000174
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000175 /* set l to number of base PyLong_MARSHAL_BASE digits */
176 n = ABS(Py_SIZE(ob));
177 l = (n-1) * PyLong_MARSHAL_RATIO;
178 d = ob->ob_digit[n-1];
179 assert(d != 0); /* a PyLong is always normalized */
180 do {
181 d >>= PyLong_MARSHAL_SHIFT;
182 l++;
183 } while (d != 0);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200184 if (l > SIZE32_MAX) {
185 p->depth--;
186 p->error = WFERR_UNMARSHALLABLE;
187 return;
188 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000189 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000190
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 for (i=0; i < n-1; i++) {
192 d = ob->ob_digit[i];
193 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
194 w_short(d & PyLong_MARSHAL_MASK, p);
195 d >>= PyLong_MARSHAL_SHIFT;
196 }
197 assert (d == 0);
198 }
199 d = ob->ob_digit[n-1];
200 do {
201 w_short(d & PyLong_MARSHAL_MASK, p);
202 d >>= PyLong_MARSHAL_SHIFT;
203 } while (d != 0);
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000204}
205
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000206static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000207w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000209 Py_ssize_t i, n;
Fred Drake6da0b912000-06-28 18:47:56 +0000210
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000211 p->depth++;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000212
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000213 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
214 p->error = WFERR_NESTEDTOODEEP;
215 }
216 else if (v == NULL) {
217 w_byte(TYPE_NULL, p);
218 }
219 else if (v == Py_None) {
220 w_byte(TYPE_NONE, p);
221 }
222 else if (v == PyExc_StopIteration) {
223 w_byte(TYPE_STOPITER, p);
224 }
225 else if (v == Py_Ellipsis) {
226 w_byte(TYPE_ELLIPSIS, p);
227 }
228 else if (v == Py_False) {
229 w_byte(TYPE_FALSE, p);
230 }
231 else if (v == Py_True) {
232 w_byte(TYPE_TRUE, p);
233 }
234 else if (PyInt_CheckExact(v)) {
235 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000236#if SIZEOF_LONG > 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000237 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
238 if (y && y != -1) {
239 w_byte(TYPE_INT64, p);
240 w_long64(x, p);
241 }
242 else
Guido van Rossumc1547d91996-12-10 15:39:04 +0000243#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000244 {
245 w_byte(TYPE_INT, p);
246 w_long(x, p);
247 }
248 }
249 else if (PyLong_CheckExact(v)) {
250 PyLongObject *ob = (PyLongObject *)v;
251 w_PyLong(ob, p);
252 }
253 else if (PyFloat_CheckExact(v)) {
254 if (p->version > 1) {
255 unsigned char buf[8];
256 if (_PyFloat_Pack8(PyFloat_AsDouble(v),
257 buf, 1) < 0) {
258 p->error = WFERR_UNMARSHALLABLE;
259 return;
260 }
261 w_byte(TYPE_BINARY_FLOAT, p);
262 w_string((char*)buf, 8, p);
263 }
264 else {
265 char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
266 'g', 17, 0, NULL);
267 if (!buf) {
268 p->error = WFERR_NOMEMORY;
269 return;
270 }
271 n = strlen(buf);
272 w_byte(TYPE_FLOAT, p);
273 w_byte((int)n, p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200274 w_string(buf, n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000275 PyMem_Free(buf);
276 }
277 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000278#ifndef WITHOUT_COMPLEX
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 else if (PyComplex_CheckExact(v)) {
280 if (p->version > 1) {
281 unsigned char buf[8];
282 if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
283 buf, 1) < 0) {
284 p->error = WFERR_UNMARSHALLABLE;
285 return;
286 }
287 w_byte(TYPE_BINARY_COMPLEX, p);
288 w_string((char*)buf, 8, p);
289 if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
290 buf, 1) < 0) {
291 p->error = WFERR_UNMARSHALLABLE;
292 return;
293 }
294 w_string((char*)buf, 8, p);
295 }
296 else {
297 char *buf;
298 w_byte(TYPE_COMPLEX, p);
299 buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
300 'g', 17, 0, NULL);
301 if (!buf) {
302 p->error = WFERR_NOMEMORY;
303 return;
304 }
305 n = strlen(buf);
306 w_byte((int)n, p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200307 w_string(buf, n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000308 PyMem_Free(buf);
309 buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
310 'g', 17, 0, NULL);
311 if (!buf) {
312 p->error = WFERR_NOMEMORY;
313 return;
314 }
315 n = strlen(buf);
316 w_byte((int)n, p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200317 w_string(buf, n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000318 PyMem_Free(buf);
319 }
320 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000321#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000322 else if (PyString_CheckExact(v)) {
323 if (p->strings && PyString_CHECK_INTERNED(v)) {
324 PyObject *o = PyDict_GetItem(p->strings, v);
325 if (o) {
326 long w = PyInt_AsLong(o);
327 w_byte(TYPE_STRINGREF, p);
328 w_long(w, p);
329 goto exit;
330 }
331 else {
332 int ok;
333 o = PyInt_FromSsize_t(PyDict_Size(p->strings));
334 ok = o &&
335 PyDict_SetItem(p->strings, v, o) >= 0;
336 Py_XDECREF(o);
337 if (!ok) {
338 p->depth--;
339 p->error = WFERR_UNMARSHALLABLE;
340 return;
341 }
342 w_byte(TYPE_INTERNED, p);
343 }
344 }
345 else {
346 w_byte(TYPE_STRING, p);
347 }
Serhiy Storchakafe2e8392013-07-11 19:14:07 +0300348 w_pstring(PyBytes_AS_STRING(v), PyString_GET_SIZE(v), p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000349 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000350#ifdef Py_USING_UNICODE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 else if (PyUnicode_CheckExact(v)) {
352 PyObject *utf8;
353 utf8 = PyUnicode_AsUTF8String(v);
354 if (utf8 == NULL) {
355 p->depth--;
356 p->error = WFERR_UNMARSHALLABLE;
357 return;
358 }
359 w_byte(TYPE_UNICODE, p);
Serhiy Storchakafe2e8392013-07-11 19:14:07 +0300360 w_pstring(PyString_AS_STRING(utf8), PyString_GET_SIZE(utf8), p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000361 Py_DECREF(utf8);
362 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000363#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000364 else if (PyTuple_CheckExact(v)) {
365 w_byte(TYPE_TUPLE, p);
366 n = PyTuple_Size(v);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200367 W_SIZE(n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 for (i = 0; i < n; i++) {
369 w_object(PyTuple_GET_ITEM(v, i), p);
370 }
371 }
372 else if (PyList_CheckExact(v)) {
373 w_byte(TYPE_LIST, p);
374 n = PyList_GET_SIZE(v);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200375 W_SIZE(n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 for (i = 0; i < n; i++) {
377 w_object(PyList_GET_ITEM(v, i), p);
378 }
379 }
380 else if (PyDict_CheckExact(v)) {
381 Py_ssize_t pos;
382 PyObject *key, *value;
383 w_byte(TYPE_DICT, p);
384 /* This one is NULL object terminated! */
385 pos = 0;
386 while (PyDict_Next(v, &pos, &key, &value)) {
387 w_object(key, p);
388 w_object(value, p);
389 }
390 w_object((PyObject *)NULL, p);
391 }
392 else if (PyAnySet_CheckExact(v)) {
393 PyObject *value, *it;
Raymond Hettingera422c342005-01-11 03:03:27 +0000394
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000395 if (PyObject_TypeCheck(v, &PySet_Type))
396 w_byte(TYPE_SET, p);
397 else
398 w_byte(TYPE_FROZENSET, p);
399 n = PyObject_Size(v);
400 if (n == -1) {
401 p->depth--;
402 p->error = WFERR_UNMARSHALLABLE;
403 return;
404 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200405 W_SIZE(n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000406 it = PyObject_GetIter(v);
407 if (it == NULL) {
408 p->depth--;
409 p->error = WFERR_UNMARSHALLABLE;
410 return;
411 }
412 while ((value = PyIter_Next(it)) != NULL) {
413 w_object(value, p);
414 Py_DECREF(value);
415 }
416 Py_DECREF(it);
417 if (PyErr_Occurred()) {
418 p->depth--;
419 p->error = WFERR_UNMARSHALLABLE;
420 return;
421 }
422 }
423 else if (PyCode_Check(v)) {
424 PyCodeObject *co = (PyCodeObject *)v;
425 w_byte(TYPE_CODE, p);
426 w_long(co->co_argcount, p);
427 w_long(co->co_nlocals, p);
428 w_long(co->co_stacksize, p);
429 w_long(co->co_flags, p);
430 w_object(co->co_code, p);
431 w_object(co->co_consts, p);
432 w_object(co->co_names, p);
433 w_object(co->co_varnames, p);
434 w_object(co->co_freevars, p);
435 w_object(co->co_cellvars, p);
436 w_object(co->co_filename, p);
437 w_object(co->co_name, p);
438 w_long(co->co_firstlineno, p);
439 w_object(co->co_lnotab, p);
440 }
441 else if (PyObject_CheckReadBuffer(v)) {
442 /* Write unknown buffer-style objects as a string */
443 char *s;
444 PyBufferProcs *pb = v->ob_type->tp_as_buffer;
445 w_byte(TYPE_STRING, p);
446 n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
Serhiy Storchakafe2e8392013-07-11 19:14:07 +0300447 w_pstring(s, n, p);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000448 }
449 else {
450 w_byte(TYPE_UNKNOWN, p);
451 p->error = WFERR_UNMARSHALLABLE;
452 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000453 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 p->depth--;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000455}
456
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000457/* version currently has no effect for writing longs. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000458void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000459PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000460{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 WFILE wf;
462 wf.fp = fp;
463 wf.error = WFERR_OK;
464 wf.depth = 0;
465 wf.strings = NULL;
466 wf.version = version;
467 w_long(x, &wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000468}
469
470void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000471PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000472{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000473 WFILE wf;
474 wf.fp = fp;
475 wf.error = WFERR_OK;
476 wf.depth = 0;
477 wf.strings = (version > 0) ? PyDict_New() : NULL;
478 wf.version = version;
479 w_object(x, &wf);
480 Py_XDECREF(wf.strings);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000481}
482
483typedef WFILE RFILE; /* Same struct with different invariants */
484
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000485#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
Guido van Rossum8d617a61995-03-09 12:12:11 +0000486
487#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000488
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200489static Py_ssize_t
490r_string(char *s, Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000491{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000492 if (p->fp != NULL)
493 /* The result fits into int because it must be <=n. */
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200494 return fread(s, 1, n, p->fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000495 if (p->end - p->ptr < n)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200496 n = p->end - p->ptr;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000497 memcpy(s, p->ptr, n);
498 p->ptr += n;
499 return n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000500}
501
502static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000503r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000504{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000505 register short x;
506 x = r_byte(p);
507 x |= r_byte(p) << 8;
508 /* Sign-extension, in case short greater than 16 bits */
509 x |= -(x & 0x8000);
510 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000511}
512
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000513static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000514r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000515{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000516 register long x;
517 register FILE *fp = p->fp;
518 if (fp) {
519 x = getc(fp);
520 x |= (long)getc(fp) << 8;
521 x |= (long)getc(fp) << 16;
522 x |= (long)getc(fp) << 24;
523 }
524 else {
525 x = rs_byte(p);
526 x |= (long)rs_byte(p) << 8;
527 x |= (long)rs_byte(p) << 16;
528 x |= (long)rs_byte(p) << 24;
529 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000530#if SIZEOF_LONG > 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000531 /* Sign extension for 64-bit machines */
532 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000533#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000534 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000535}
536
Tim Peters82112372001-08-29 02:28:42 +0000537/* r_long64 deals with the TYPE_INT64 code. On a machine with
538 sizeof(long) > 4, it returns a Python int object, else a Python long
539 object. Note that w_long64 writes out TYPE_INT if 32 bits is enough,
540 so there's no inefficiency here in returning a PyLong on 32-bit boxes
541 for everything written via TYPE_INT64 (i.e., if an int is written via
542 TYPE_INT64, it *needs* more than 32 bits).
543*/
544static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000545r_long64(RFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000546{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000547 long lo4 = r_long(p);
548 long hi4 = r_long(p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000549#if SIZEOF_LONG > 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
551 return PyInt_FromLong(x);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000552#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000553 unsigned char buf[8];
554 int one = 1;
555 int is_little_endian = (int)*(char*)&one;
556 if (is_little_endian) {
557 memcpy(buf, &lo4, 4);
558 memcpy(buf+4, &hi4, 4);
559 }
560 else {
561 memcpy(buf, &hi4, 4);
562 memcpy(buf+4, &lo4, 4);
563 }
564 return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000565#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000566}
567
Guido van Rossum79f25d91997-04-29 20:08:16 +0000568static PyObject *
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000569r_PyLong(RFILE *p)
570{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000571 PyLongObject *ob;
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200572 long n, size, i;
573 int j, md, shorts_in_top_digit;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000574 digit d;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000575
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000576 n = r_long(p);
577 if (n == 0)
578 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200579 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000580 PyErr_SetString(PyExc_ValueError,
581 "bad marshal data (long size out of range)");
582 return NULL;
583 }
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000584
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000585 size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
586 shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
587 ob = _PyLong_New(size);
588 if (ob == NULL)
589 return NULL;
590 Py_SIZE(ob) = n > 0 ? size : -size;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000591
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000592 for (i = 0; i < size-1; i++) {
593 d = 0;
594 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
595 md = r_short(p);
596 if (md < 0 || md > PyLong_MARSHAL_BASE)
597 goto bad_digit;
598 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
599 }
600 ob->ob_digit[i] = d;
601 }
602 d = 0;
603 for (j=0; j < shorts_in_top_digit; j++) {
604 md = r_short(p);
605 if (md < 0 || md > PyLong_MARSHAL_BASE)
606 goto bad_digit;
607 /* topmost marshal digit should be nonzero */
608 if (md == 0 && j == shorts_in_top_digit - 1) {
609 Py_DECREF(ob);
610 PyErr_SetString(PyExc_ValueError,
611 "bad marshal data (unnormalized long data)");
612 return NULL;
613 }
614 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
615 }
616 /* top digit should be nonzero, else the resulting PyLong won't be
617 normalized */
618 ob->ob_digit[size-1] = d;
619 return (PyObject *)ob;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000620 bad_digit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000621 Py_DECREF(ob);
622 PyErr_SetString(PyExc_ValueError,
623 "bad marshal data (digit out of range in long)");
624 return NULL;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000625}
626
627
628static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000629r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000630{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000631 /* NULL is a valid return value, it does not necessarily means that
632 an exception is set. */
633 PyObject *v, *v2;
634 long i, n;
635 int type = r_byte(p);
636 PyObject *retval;
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000637
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000638 p->depth++;
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000639
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000640 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
641 p->depth--;
642 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
643 return NULL;
644 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000645
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000646 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000647
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000648 case EOF:
649 PyErr_SetString(PyExc_EOFError,
650 "EOF read where object expected");
651 retval = NULL;
652 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000653
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000654 case TYPE_NULL:
655 retval = NULL;
656 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000657
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000658 case TYPE_NONE:
659 Py_INCREF(Py_None);
660 retval = Py_None;
661 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000662
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000663 case TYPE_STOPITER:
664 Py_INCREF(PyExc_StopIteration);
665 retval = PyExc_StopIteration;
666 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000667
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000668 case TYPE_ELLIPSIS:
669 Py_INCREF(Py_Ellipsis);
670 retval = Py_Ellipsis;
671 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000672
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000673 case TYPE_FALSE:
674 Py_INCREF(Py_False);
675 retval = Py_False;
676 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000677
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 case TYPE_TRUE:
679 Py_INCREF(Py_True);
680 retval = Py_True;
681 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000682
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000683 case TYPE_INT:
684 retval = PyInt_FromLong(r_long(p));
685 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000686
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000687 case TYPE_INT64:
688 retval = r_long64(p);
689 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000690
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000691 case TYPE_LONG:
692 retval = r_PyLong(p);
693 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000694
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000695 case TYPE_FLOAT:
696 {
697 char buf[256];
698 double dx;
699 n = r_byte(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200700 if (n == EOF || r_string(buf, n, p) != n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000701 PyErr_SetString(PyExc_EOFError,
702 "EOF read where object expected");
703 retval = NULL;
704 break;
705 }
706 buf[n] = '\0';
707 dx = PyOS_string_to_double(buf, NULL, NULL);
708 if (dx == -1.0 && PyErr_Occurred()) {
709 retval = NULL;
710 break;
711 }
712 retval = PyFloat_FromDouble(dx);
713 break;
714 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000715
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000716 case TYPE_BINARY_FLOAT:
717 {
718 unsigned char buf[8];
719 double x;
720 if (r_string((char*)buf, 8, p) != 8) {
721 PyErr_SetString(PyExc_EOFError,
722 "EOF read where object expected");
723 retval = NULL;
724 break;
725 }
726 x = _PyFloat_Unpack8(buf, 1);
727 if (x == -1.0 && PyErr_Occurred()) {
728 retval = NULL;
729 break;
730 }
731 retval = PyFloat_FromDouble(x);
732 break;
733 }
Michael W. Hudsondf888462005-06-03 14:41:55 +0000734
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000735#ifndef WITHOUT_COMPLEX
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000736 case TYPE_COMPLEX:
737 {
738 char buf[256];
739 Py_complex c;
740 n = r_byte(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200741 if (n == EOF || r_string(buf, n, p) != n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000742 PyErr_SetString(PyExc_EOFError,
743 "EOF read where object expected");
744 retval = NULL;
745 break;
746 }
747 buf[n] = '\0';
748 c.real = PyOS_string_to_double(buf, NULL, NULL);
749 if (c.real == -1.0 && PyErr_Occurred()) {
750 retval = NULL;
751 break;
752 }
753 n = r_byte(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200754 if (n == EOF || r_string(buf, n, p) != n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000755 PyErr_SetString(PyExc_EOFError,
756 "EOF read where object expected");
757 retval = NULL;
758 break;
759 }
760 buf[n] = '\0';
761 c.imag = PyOS_string_to_double(buf, NULL, NULL);
762 if (c.imag == -1.0 && PyErr_Occurred()) {
763 retval = NULL;
764 break;
765 }
766 retval = PyComplex_FromCComplex(c);
767 break;
768 }
Michael W. Hudsondf888462005-06-03 14:41:55 +0000769
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000770 case TYPE_BINARY_COMPLEX:
771 {
772 unsigned char buf[8];
773 Py_complex c;
774 if (r_string((char*)buf, 8, p) != 8) {
775 PyErr_SetString(PyExc_EOFError,
776 "EOF read where object expected");
777 retval = NULL;
778 break;
779 }
780 c.real = _PyFloat_Unpack8(buf, 1);
781 if (c.real == -1.0 && PyErr_Occurred()) {
782 retval = NULL;
783 break;
784 }
785 if (r_string((char*)buf, 8, p) != 8) {
786 PyErr_SetString(PyExc_EOFError,
787 "EOF read where object expected");
788 retval = NULL;
789 break;
790 }
791 c.imag = _PyFloat_Unpack8(buf, 1);
792 if (c.imag == -1.0 && PyErr_Occurred()) {
793 retval = NULL;
794 break;
795 }
796 retval = PyComplex_FromCComplex(c);
797 break;
798 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000799#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +0000800
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000801 case TYPE_INTERNED:
802 case TYPE_STRING:
803 n = r_long(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200804 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000805 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
806 retval = NULL;
807 break;
808 }
809 v = PyString_FromStringAndSize((char *)NULL, n);
810 if (v == NULL) {
811 retval = NULL;
812 break;
813 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200814 if (r_string(PyString_AS_STRING(v), n, p) != n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000815 Py_DECREF(v);
816 PyErr_SetString(PyExc_EOFError,
817 "EOF read where object expected");
818 retval = NULL;
819 break;
820 }
821 if (type == TYPE_INTERNED) {
822 PyString_InternInPlace(&v);
823 if (PyList_Append(p->strings, v) < 0) {
824 retval = NULL;
825 break;
826 }
827 }
828 retval = v;
829 break;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000830
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000831 case TYPE_STRINGREF:
832 n = r_long(p);
833 if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
834 PyErr_SetString(PyExc_ValueError, "bad marshal data (string ref out of range)");
835 retval = NULL;
836 break;
837 }
838 v = PyList_GET_ITEM(p->strings, n);
839 Py_INCREF(v);
840 retval = v;
841 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000842
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000843#ifdef Py_USING_UNICODE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000844 case TYPE_UNICODE:
845 {
846 char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +0000847
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 n = r_long(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200849 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000850 PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
851 retval = NULL;
852 break;
853 }
854 buffer = PyMem_NEW(char, n);
855 if (buffer == NULL) {
856 retval = PyErr_NoMemory();
857 break;
858 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200859 if (r_string(buffer, n, p) != n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000860 PyMem_DEL(buffer);
861 PyErr_SetString(PyExc_EOFError,
862 "EOF read where object expected");
863 retval = NULL;
864 break;
865 }
866 v = PyUnicode_DecodeUTF8(buffer, n, NULL);
867 PyMem_DEL(buffer);
868 retval = v;
869 break;
870 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000871#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +0000872
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000873 case TYPE_TUPLE:
874 n = r_long(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200875 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000876 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
877 retval = NULL;
878 break;
879 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200880 v = PyTuple_New(n);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000881 if (v == NULL) {
882 retval = NULL;
883 break;
884 }
885 for (i = 0; i < n; i++) {
886 v2 = r_object(p);
887 if ( v2 == NULL ) {
888 if (!PyErr_Occurred())
889 PyErr_SetString(PyExc_TypeError,
890 "NULL object in marshal data for tuple");
891 Py_DECREF(v);
892 v = NULL;
893 break;
894 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200895 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000896 }
897 retval = v;
898 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000899
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000900 case TYPE_LIST:
901 n = r_long(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200902 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000903 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
904 retval = NULL;
905 break;
906 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200907 v = PyList_New(n);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000908 if (v == NULL) {
909 retval = NULL;
910 break;
911 }
912 for (i = 0; i < n; i++) {
913 v2 = r_object(p);
914 if ( v2 == NULL ) {
915 if (!PyErr_Occurred())
916 PyErr_SetString(PyExc_TypeError,
917 "NULL object in marshal data for list");
918 Py_DECREF(v);
919 v = NULL;
920 break;
921 }
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200922 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000923 }
924 retval = v;
925 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000926
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000927 case TYPE_DICT:
928 v = PyDict_New();
929 if (v == NULL) {
930 retval = NULL;
931 break;
932 }
933 for (;;) {
934 PyObject *key, *val;
935 key = r_object(p);
936 if (key == NULL)
937 break;
938 val = r_object(p);
939 if (val != NULL)
940 PyDict_SetItem(v, key, val);
941 Py_DECREF(key);
942 Py_XDECREF(val);
943 }
944 if (PyErr_Occurred()) {
945 Py_DECREF(v);
946 v = NULL;
947 }
948 retval = v;
949 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000950
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000951 case TYPE_SET:
952 case TYPE_FROZENSET:
953 n = r_long(p);
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200954 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000955 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
956 retval = NULL;
957 break;
958 }
959 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
960 if (v == NULL) {
961 retval = NULL;
962 break;
963 }
964 for (i = 0; i < n; i++) {
965 v2 = r_object(p);
966 if ( v2 == NULL ) {
967 if (!PyErr_Occurred())
968 PyErr_SetString(PyExc_TypeError,
969 "NULL object in marshal data for set");
970 Py_DECREF(v);
971 v = NULL;
972 break;
973 }
974 if (PySet_Add(v, v2) == -1) {
975 Py_DECREF(v);
976 Py_DECREF(v2);
977 v = NULL;
978 break;
979 }
980 Py_DECREF(v2);
981 }
982 retval = v;
983 break;
Raymond Hettingera422c342005-01-11 03:03:27 +0000984
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000985 case TYPE_CODE:
986 if (PyEval_GetRestricted()) {
987 PyErr_SetString(PyExc_RuntimeError,
988 "cannot unmarshal code objects in "
989 "restricted execution mode");
990 retval = NULL;
991 break;
992 }
993 else {
994 int argcount;
995 int nlocals;
996 int stacksize;
997 int flags;
998 PyObject *code = NULL;
999 PyObject *consts = NULL;
1000 PyObject *names = NULL;
1001 PyObject *varnames = NULL;
1002 PyObject *freevars = NULL;
1003 PyObject *cellvars = NULL;
1004 PyObject *filename = NULL;
1005 PyObject *name = NULL;
1006 int firstlineno;
1007 PyObject *lnotab = NULL;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001008
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001009 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001010
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001011 /* XXX ignore long->int overflows for now */
1012 argcount = (int)r_long(p);
1013 nlocals = (int)r_long(p);
1014 stacksize = (int)r_long(p);
1015 flags = (int)r_long(p);
1016 code = r_object(p);
1017 if (code == NULL)
1018 goto code_error;
1019 consts = r_object(p);
1020 if (consts == NULL)
1021 goto code_error;
1022 names = r_object(p);
1023 if (names == NULL)
1024 goto code_error;
1025 varnames = r_object(p);
1026 if (varnames == NULL)
1027 goto code_error;
1028 freevars = r_object(p);
1029 if (freevars == NULL)
1030 goto code_error;
1031 cellvars = r_object(p);
1032 if (cellvars == NULL)
1033 goto code_error;
1034 filename = r_object(p);
1035 if (filename == NULL)
1036 goto code_error;
1037 name = r_object(p);
1038 if (name == NULL)
1039 goto code_error;
1040 firstlineno = (int)r_long(p);
1041 lnotab = r_object(p);
1042 if (lnotab == NULL)
1043 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001044
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 v = (PyObject *) PyCode_New(
1046 argcount, nlocals, stacksize, flags,
1047 code, consts, names, varnames,
1048 freevars, cellvars, filename, name,
1049 firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001050
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001051 code_error:
1052 Py_XDECREF(code);
1053 Py_XDECREF(consts);
1054 Py_XDECREF(names);
1055 Py_XDECREF(varnames);
1056 Py_XDECREF(freevars);
1057 Py_XDECREF(cellvars);
1058 Py_XDECREF(filename);
1059 Py_XDECREF(name);
1060 Py_XDECREF(lnotab);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001061
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001062 }
1063 retval = v;
1064 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001065
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001066 default:
1067 /* Bogus data got written, which isn't ideal.
1068 This will let you keep working and recover. */
1069 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
1070 retval = NULL;
1071 break;
1072
1073 }
1074 p->depth--;
1075 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001076}
1077
Neal Norwitzd85c4522004-06-13 20:31:49 +00001078static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001079read_object(RFILE *p)
1080{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001081 PyObject *v;
1082 if (PyErr_Occurred()) {
1083 fprintf(stderr, "XXX readobject called with exception set\n");
1084 return NULL;
1085 }
1086 v = r_object(p);
1087 if (v == NULL && !PyErr_Occurred())
1088 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1089 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001090}
1091
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001092int
1093PyMarshal_ReadShortFromFile(FILE *fp)
1094{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001095 RFILE rf;
1096 assert(fp);
1097 rf.fp = fp;
1098 rf.strings = NULL;
1099 rf.end = rf.ptr = NULL;
1100 return r_short(&rf);
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001101}
1102
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001103long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001104PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001105{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001106 RFILE rf;
1107 rf.fp = fp;
1108 rf.strings = NULL;
1109 rf.ptr = rf.end = NULL;
1110 return r_long(&rf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001111}
1112
Tim Peters691e0e92001-01-18 04:39:16 +00001113#ifdef HAVE_FSTAT
1114/* Return size of file in bytes; < 0 if unknown. */
1115static off_t
1116getfilesize(FILE *fp)
1117{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001118 struct stat st;
1119 if (fstat(fileno(fp), &st) != 0)
1120 return -1;
1121 else
1122 return st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001123}
1124#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +00001125
Tim Peters691e0e92001-01-18 04:39:16 +00001126/* If we can get the size of the file up-front, and it's reasonably small,
1127 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1128 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001129 * CAUTION: since this may read the entire remainder of the file, don't
1130 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001131 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001132PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001133PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001134{
Antoine Pitrou18e63fb2010-04-21 22:53:29 +00001135/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001136#define REASONABLE_FILE_LIMIT (1L << 18)
Tim Peters691e0e92001-01-18 04:39:16 +00001137#ifdef HAVE_FSTAT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001138 off_t filesize;
1139 filesize = getfilesize(fp);
1140 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1141 char* pBuf = (char *)PyMem_MALLOC(filesize);
1142 if (pBuf != NULL) {
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +02001143 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1144 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001145 PyMem_FREE(pBuf);
1146 return v;
1147 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001148
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001149 }
Tim Peters691e0e92001-01-18 04:39:16 +00001150#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001151 /* We don't have fstat, or we do but the file is larger than
1152 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1153 */
1154 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001155
Tim Peters691e0e92001-01-18 04:39:16 +00001156#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001157}
1158
Guido van Rossum79f25d91997-04-29 20:08:16 +00001159PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001160PyMarshal_ReadObjectFromFile(FILE *fp)
1161{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001162 RFILE rf;
1163 PyObject *result;
1164 rf.fp = fp;
1165 rf.strings = PyList_New(0);
1166 rf.depth = 0;
1167 rf.ptr = rf.end = NULL;
1168 result = r_object(&rf);
1169 Py_DECREF(rf.strings);
1170 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001171}
1172
1173PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +00001174PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001175{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001176 RFILE rf;
1177 PyObject *result;
1178 rf.fp = NULL;
1179 rf.ptr = str;
1180 rf.end = str + len;
1181 rf.strings = PyList_New(0);
1182 rf.depth = 0;
1183 result = r_object(&rf);
1184 Py_DECREF(rf.strings);
1185 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001186}
1187
Eric Smith15669272009-10-19 00:34:12 +00001188static void
1189set_error(int error)
1190{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001191 switch (error) {
1192 case WFERR_NOMEMORY:
1193 PyErr_NoMemory();
1194 break;
1195 case WFERR_UNMARSHALLABLE:
1196 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
1197 break;
1198 case WFERR_NESTEDTOODEEP:
1199 default:
1200 PyErr_SetString(PyExc_ValueError,
1201 "object too deeply nested to marshal");
1202 break;
1203 }
Eric Smith15669272009-10-19 00:34:12 +00001204}
1205
Guido van Rossum79f25d91997-04-29 20:08:16 +00001206PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001207PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001208{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001209 WFILE wf;
1210 wf.fp = NULL;
1211 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
1212 if (wf.str == NULL)
1213 return NULL;
1214 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
1215 wf.end = wf.ptr + PyString_Size(wf.str);
1216 wf.error = WFERR_OK;
1217 wf.depth = 0;
1218 wf.version = version;
1219 wf.strings = (version > 0) ? PyDict_New() : NULL;
1220 w_object(x, &wf);
1221 Py_XDECREF(wf.strings);
1222 if (wf.str != NULL) {
1223 char *base = PyString_AS_STRING((PyStringObject *)wf.str);
1224 if (wf.ptr - base > PY_SSIZE_T_MAX) {
1225 Py_DECREF(wf.str);
1226 PyErr_SetString(PyExc_OverflowError,
1227 "too much marshall data for a string");
1228 return NULL;
1229 }
1230 if (_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)))
1231 return NULL;
1232 }
1233 if (wf.error != WFERR_OK) {
1234 Py_XDECREF(wf.str);
1235 set_error(wf.error);
1236 return NULL;
1237 }
1238 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001239}
1240
Guido van Rossum64b45521991-06-07 13:58:22 +00001241/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001242
Guido van Rossum79f25d91997-04-29 20:08:16 +00001243static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001244marshal_dump(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001245{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001246 WFILE wf;
1247 PyObject *x;
1248 PyObject *f;
1249 int version = Py_MARSHAL_VERSION;
1250 if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
1251 return NULL;
1252 if (!PyFile_Check(f)) {
1253 PyErr_SetString(PyExc_TypeError,
1254 "marshal.dump() 2nd arg must be file");
1255 return NULL;
1256 }
1257 wf.fp = PyFile_AsFile(f);
1258 wf.str = NULL;
1259 wf.ptr = wf.end = NULL;
1260 wf.error = WFERR_OK;
1261 wf.depth = 0;
1262 wf.strings = (version > 0) ? PyDict_New() : 0;
1263 wf.version = version;
1264 w_object(x, &wf);
1265 Py_XDECREF(wf.strings);
1266 if (wf.error != WFERR_OK) {
1267 set_error(wf.error);
1268 return NULL;
1269 }
1270 Py_INCREF(Py_None);
1271 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001272}
1273
R. David Murraya3ec6972009-05-13 00:30:29 +00001274PyDoc_STRVAR(dump_doc,
1275"dump(value, file[, version])\n\
1276\n\
1277Write the value on the open file. The value must be a supported type.\n\
1278The file must be an open file object such as sys.stdout or returned by\n\
1279open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
1280\n\
1281If the value has (or contains an object that has) an unsupported type, a\n\
1282ValueError exception is raised but garbage data will also be written\n\
1283to the file. The object will not be properly read back by load()\n\
1284\n\
1285New in version 2.4: The version argument indicates the data format that\n\
1286dump should use.");
1287
Guido van Rossum79f25d91997-04-29 20:08:16 +00001288static PyObject *
Georg Brandlbf92f462006-05-29 21:58:42 +00001289marshal_load(PyObject *self, PyObject *f)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001290{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001291 RFILE rf;
1292 PyObject *result;
1293 if (!PyFile_Check(f)) {
1294 PyErr_SetString(PyExc_TypeError,
1295 "marshal.load() arg must be file");
1296 return NULL;
1297 }
1298 rf.fp = PyFile_AsFile(f);
1299 rf.strings = PyList_New(0);
1300 rf.depth = 0;
1301 result = read_object(&rf);
1302 Py_DECREF(rf.strings);
1303 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001304}
1305
R. David Murraya3ec6972009-05-13 00:30:29 +00001306PyDoc_STRVAR(load_doc,
1307"load(file)\n\
1308\n\
1309Read one value from the open file and return it. If no valid value is\n\
1310read (e.g. because the data has a different Python versions\n\
1311incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
1312The file must be an open file object opened in binary mode ('rb' or\n\
1313'r+b').\n\
1314\n\
1315Note: If an object containing an unsupported type was marshalled with\n\
1316dump(), load() will substitute None for the unmarshallable type.");
1317
1318
Guido van Rossum79f25d91997-04-29 20:08:16 +00001319static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001320marshal_dumps(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001321{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001322 PyObject *x;
1323 int version = Py_MARSHAL_VERSION;
1324 if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
1325 return NULL;
1326 return PyMarshal_WriteObjectToString(x, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001327}
1328
R. David Murraya3ec6972009-05-13 00:30:29 +00001329PyDoc_STRVAR(dumps_doc,
1330"dumps(value[, version])\n\
1331\n\
1332Return the string that would be written to a file by dump(value, file).\n\
1333The value must be a supported type. Raise a ValueError exception if\n\
1334value has (or contains an object that has) an unsupported type.\n\
1335\n\
1336New in version 2.4: The version argument indicates the data format that\n\
R. David Murray525cffc2009-05-13 13:07:14 +00001337dumps should use.");
R. David Murraya3ec6972009-05-13 00:30:29 +00001338
1339
Guido van Rossum79f25d91997-04-29 20:08:16 +00001340static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001341marshal_loads(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001342{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001343 RFILE rf;
1344 char *s;
1345 Py_ssize_t n;
1346 PyObject* result;
1347 if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
1348 return NULL;
1349 rf.fp = NULL;
1350 rf.ptr = s;
1351 rf.end = s + n;
1352 rf.strings = PyList_New(0);
1353 rf.depth = 0;
1354 result = read_object(&rf);
1355 Py_DECREF(rf.strings);
1356 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001357}
1358
R. David Murraya3ec6972009-05-13 00:30:29 +00001359PyDoc_STRVAR(loads_doc,
1360"loads(string)\n\
1361\n\
1362Convert the string to a value. If no valid value is found, raise\n\
1363EOFError, ValueError or TypeError. Extra characters in the string are\n\
1364ignored.");
1365
Guido van Rossum79f25d91997-04-29 20:08:16 +00001366static PyMethodDef marshal_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001367 {"dump", marshal_dump, METH_VARARGS, dump_doc},
1368 {"load", marshal_load, METH_O, load_doc},
1369 {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
1370 {"loads", marshal_loads, METH_VARARGS, loads_doc},
1371 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001372};
1373
R. David Murraya3ec6972009-05-13 00:30:29 +00001374PyDoc_STRVAR(marshal_doc,
1375"This module contains functions that can read and write Python values in\n\
1376a binary format. The format is specific to Python, but independent of\n\
1377machine architecture issues.\n\
1378\n\
1379Not all Python object types are supported; in general, only objects\n\
1380whose value is independent from a particular invocation of Python can be\n\
1381written and read by this module. The following types are supported:\n\
1382None, integers, long integers, floating point numbers, strings, Unicode\n\
1383objects, tuples, lists, sets, dictionaries, and code objects, where it\n\
1384should be understood that tuples, lists and dictionaries are only\n\
1385supported as long as the values contained therein are themselves\n\
1386supported; and recursive lists and dictionaries should not be written\n\
1387(they will cause infinite loops).\n\
1388\n\
1389Variables:\n\
1390\n\
1391version -- indicates the format that the module uses. Version 0 is the\n\
1392 historical format, version 1 (added in Python 2.4) shares interned\n\
1393 strings and version 2 (added in Python 2.5) uses a binary format for\n\
1394 floating point numbers. (New in version 2.4)\n\
1395\n\
1396Functions:\n\
1397\n\
1398dump() -- write value to a file\n\
1399load() -- read value from a file\n\
1400dumps() -- write value to a string\n\
1401loads() -- read value from a string");
1402
1403
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001404PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001405PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001406{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001407 PyObject *mod = Py_InitModule3("marshal", marshal_methods,
1408 marshal_doc);
1409 if (mod == NULL)
1410 return;
1411 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001412}