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