blob: 5b8de9919217846fc508f76d406c4b4ab66df9c0 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001
2/* Write Python objects to files and read them back.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07003 This is primarily intended for writing and reading compiled Python code,
4 even though dicts, lists, sets and frozensets, not commonly seen in
5 code objects, are supported.
6 Version 3 of this protocol properly supports circular links
7 and sharing. */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00008
Thomas Wouters695934a2006-03-01 23:49:13 +00009#define PY_SSIZE_T_CLEAN
10
Guido van Rossum79f25d91997-04-29 20:08:16 +000011#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000012#include "longintrepr.h"
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000013#include "code.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000014#include "marshal.h"
Serhiy Storchakace921c622015-02-11 15:53:31 +020015#include "../Modules/hashtable.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000016
Fred Drake6da0b912000-06-28 18:47:56 +000017/* High water mark to determine when the marshalled object is dangerously deep
18 * and risks coring the interpreter. When the object stack gets this deep,
19 * raise an exception instead of continuing.
Guido van Rossum63175a12007-08-29 20:39:13 +000020 * On Windows debug builds, reduce this value.
Fred Drake6da0b912000-06-28 18:47:56 +000021 */
Guido van Rossum63175a12007-08-29 20:39:13 +000022#if defined(MS_WINDOWS) && defined(_DEBUG)
Steve Dowerf6c69e62014-11-01 15:15:16 -070023#define MAX_MARSHAL_STACK_DEPTH 1000
Guido van Rossum63175a12007-08-29 20:39:13 +000024#else
Guido van Rossumd59da4b2007-05-22 18:11:13 +000025#define MAX_MARSHAL_STACK_DEPTH 2000
Guido van Rossum63175a12007-08-29 20:39:13 +000026#endif
Fred Drake6da0b912000-06-28 18:47:56 +000027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028#define TYPE_NULL '0'
29#define TYPE_NONE 'N'
30#define TYPE_FALSE 'F'
31#define TYPE_TRUE 'T'
32#define TYPE_STOPITER 'S'
33#define TYPE_ELLIPSIS '.'
34#define TYPE_INT 'i'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035#define TYPE_FLOAT 'f'
36#define TYPE_BINARY_FLOAT 'g'
37#define TYPE_COMPLEX 'x'
38#define TYPE_BINARY_COMPLEX 'y'
39#define TYPE_LONG 'l'
40#define TYPE_STRING 's'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070041#define TYPE_INTERNED 't'
42#define TYPE_REF 'r'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043#define TYPE_TUPLE '('
44#define TYPE_LIST '['
45#define TYPE_DICT '{'
46#define TYPE_CODE 'c'
47#define TYPE_UNICODE 'u'
48#define TYPE_UNKNOWN '?'
49#define TYPE_SET '<'
50#define TYPE_FROZENSET '>'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070051#define FLAG_REF '\x80' /* with a type, add obj to index */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000052
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020053#define TYPE_ASCII 'a'
54#define TYPE_ASCII_INTERNED 'A'
55#define TYPE_SMALL_TUPLE ')'
56#define TYPE_SHORT_ASCII 'z'
57#define TYPE_SHORT_ASCII_INTERNED 'Z'
58
Eric Smithb1a03cf2009-04-21 11:57:38 +000059#define WFERR_OK 0
60#define WFERR_UNMARSHALLABLE 1
61#define WFERR_NESTEDTOODEEP 2
62#define WFERR_NOMEMORY 3
63
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000064typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 FILE *fp;
66 int error; /* see WFERR_* values */
67 int depth;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 PyObject *str;
69 char *ptr;
70 char *end;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020071 char *buf;
Serhiy Storchakace921c622015-02-11 15:53:31 +020072 _Py_hashtable_t *hashtable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 int version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000074} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000075
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020076#define w_byte(c, p) do { \
77 if ((p)->ptr != (p)->end || w_reserve((p), 1)) \
78 *(p)->ptr++ = (c); \
79 } while(0)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000080
81static void
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020082w_flush(WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000083{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020084 assert(p->fp != NULL);
85 fwrite(p->buf, 1, p->ptr - p->buf, p->fp);
86 p->ptr = p->buf;
87}
88
89static int
90w_reserve(WFILE *p, Py_ssize_t needed)
91{
92 Py_ssize_t pos, size, delta;
93 if (p->ptr == NULL)
94 return 0; /* An error already occurred */
95 if (p->fp != NULL) {
96 w_flush(p);
97 return needed <= p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 }
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020099 assert(p->str != NULL);
100 pos = p->ptr - p->buf;
101 size = PyBytes_Size(p->str);
102 if (size > 16*1024*1024)
103 delta = (size >> 3); /* 12.5% overallocation */
104 else
105 delta = size + 1024;
106 delta = Py_MAX(delta, needed);
107 if (delta > PY_SSIZE_T_MAX - size) {
108 p->error = WFERR_NOMEMORY;
109 return 0;
110 }
111 size += delta;
112 if (_PyBytes_Resize(&p->str, size) != 0) {
113 p->ptr = p->buf = p->end = NULL;
114 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 }
116 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200117 p->buf = PyBytes_AS_STRING(p->str);
118 p->ptr = p->buf + pos;
119 p->end = p->buf + size;
120 return 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122}
123
124static void
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300125w_string(const char *s, Py_ssize_t n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000126{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200127 Py_ssize_t m;
128 if (!n || p->ptr == NULL)
129 return;
130 m = p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 if (p->fp != NULL) {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200132 if (n <= m) {
133 Py_MEMCPY(p->ptr, s, n);
134 p->ptr += n;
135 }
136 else {
137 w_flush(p);
138 fwrite(s, 1, n, p->fp);
139 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 }
141 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200142 if (n <= m || w_reserve(p, n - m)) {
143 Py_MEMCPY(p->ptr, s, n);
144 p->ptr += n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 }
146 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000147}
148
149static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000150w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 w_byte((char)( x & 0xff), p);
153 w_byte((char)((x>> 8) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000154}
155
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000156static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000157w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 w_byte((char)( x & 0xff), p);
160 w_byte((char)((x>> 8) & 0xff), p);
161 w_byte((char)((x>>16) & 0xff), p);
162 w_byte((char)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000163}
164
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200165#define SIZE32_MAX 0x7FFFFFFF
166
167#if SIZEOF_SIZE_T > 4
168# define W_SIZE(n, p) do { \
169 if ((n) > SIZE32_MAX) { \
170 (p)->depth--; \
171 (p)->error = WFERR_UNMARSHALLABLE; \
172 return; \
173 } \
174 w_long((long)(n), p); \
175 } while(0)
176#else
177# define W_SIZE w_long
178#endif
179
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300180static void
181w_pstring(const char *s, Py_ssize_t n, WFILE *p)
182{
183 W_SIZE(n, p);
184 w_string(s, n, p);
185}
186
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200187static void
188w_short_pstring(const char *s, Py_ssize_t n, WFILE *p)
189{
Antoine Pitroub30f2712013-10-12 23:14:47 +0200190 w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200191 w_string(s, n, p);
192}
193
Serhiy Storchaka95949422013-08-27 19:40:23 +0300194/* We assume that Python ints are stored internally in base some power of
Mark Dickinsonbd792642009-03-18 20:06:12 +0000195 2**15; for the sake of portability we'll always read and write them in base
196 exactly 2**15. */
197
198#define PyLong_MARSHAL_SHIFT 15
199#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
200#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
201#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
202#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
203#endif
204#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
205
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700206#define W_TYPE(t, p) do { \
207 w_byte((t) | flag, (p)); \
208} while(0)
209
Mark Dickinsonbd792642009-03-18 20:06:12 +0000210static void
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700211w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
Mark Dickinsonbd792642009-03-18 20:06:12 +0000212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 Py_ssize_t i, j, n, l;
214 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000215
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700216 W_TYPE(TYPE_LONG, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 if (Py_SIZE(ob) == 0) {
218 w_long((long)0, p);
219 return;
220 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 /* set l to number of base PyLong_MARSHAL_BASE digits */
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200223 n = Py_ABS(Py_SIZE(ob));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 l = (n-1) * PyLong_MARSHAL_RATIO;
225 d = ob->ob_digit[n-1];
226 assert(d != 0); /* a PyLong is always normalized */
227 do {
228 d >>= PyLong_MARSHAL_SHIFT;
229 l++;
230 } while (d != 0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200231 if (l > SIZE32_MAX) {
232 p->depth--;
233 p->error = WFERR_UNMARSHALLABLE;
234 return;
235 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 for (i=0; i < n-1; i++) {
239 d = ob->ob_digit[i];
240 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
241 w_short(d & PyLong_MARSHAL_MASK, p);
242 d >>= PyLong_MARSHAL_SHIFT;
243 }
244 assert (d == 0);
245 }
246 d = ob->ob_digit[n-1];
247 do {
248 w_short(d & PyLong_MARSHAL_MASK, p);
249 d >>= PyLong_MARSHAL_SHIFT;
250 } while (d != 0);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000251}
252
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700253static int
254w_ref(PyObject *v, char *flag, WFILE *p)
255{
Serhiy Storchakace921c622015-02-11 15:53:31 +0200256 _Py_hashtable_entry_t *entry;
257 int w;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700258
Serhiy Storchakace921c622015-02-11 15:53:31 +0200259 if (p->version < 3 || p->hashtable == NULL)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700260 return 0; /* not writing object references */
261
262 /* if it has only one reference, it definitely isn't shared */
263 if (Py_REFCNT(v) == 1)
264 return 0;
265
Serhiy Storchakace921c622015-02-11 15:53:31 +0200266 entry = _Py_hashtable_get_entry(p->hashtable, v);
267 if (entry != NULL) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700268 /* write the reference index to the stream */
Serhiy Storchakace921c622015-02-11 15:53:31 +0200269 _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, &w, sizeof(w), entry);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700270 /* we don't store "long" indices in the dict */
271 assert(0 <= w && w <= 0x7fffffff);
272 w_byte(TYPE_REF, p);
273 w_long(w, p);
274 return 1;
275 } else {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200276 size_t s = p->hashtable->entries;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700277 /* we don't support long indices */
278 if (s >= 0x7fffffff) {
279 PyErr_SetString(PyExc_ValueError, "too many objects");
280 goto err;
281 }
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200282 w = (int)s;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200283 Py_INCREF(v);
284 if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) {
285 Py_DECREF(v);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700286 goto err;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200287 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700288 *flag |= FLAG_REF;
289 return 0;
290 }
291err:
292 p->error = WFERR_UNMARSHALLABLE;
293 return 1;
294}
295
296static void
297w_complex_object(PyObject *v, char flag, WFILE *p);
298
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000299static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000300w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000301{
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700302 char flag = '\0';
Fred Drake6da0b912000-06-28 18:47:56 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 p->depth++;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
307 p->error = WFERR_NESTEDTOODEEP;
308 }
309 else if (v == NULL) {
310 w_byte(TYPE_NULL, p);
311 }
312 else if (v == Py_None) {
313 w_byte(TYPE_NONE, p);
314 }
315 else if (v == PyExc_StopIteration) {
316 w_byte(TYPE_STOPITER, p);
317 }
318 else if (v == Py_Ellipsis) {
319 w_byte(TYPE_ELLIPSIS, p);
320 }
321 else if (v == Py_False) {
322 w_byte(TYPE_FALSE, p);
323 }
324 else if (v == Py_True) {
325 w_byte(TYPE_TRUE, p);
326 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700327 else if (!w_ref(v, &flag, p))
328 w_complex_object(v, flag, p);
329
330 p->depth--;
331}
332
333static void
334w_complex_object(PyObject *v, char flag, WFILE *p)
335{
336 Py_ssize_t i, n;
337
338 if (PyLong_CheckExact(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 long x = PyLong_AsLong(v);
340 if ((x == -1) && PyErr_Occurred()) {
341 PyLongObject *ob = (PyLongObject *)v;
342 PyErr_Clear();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700343 w_PyLong(ob, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 }
345 else {
Guido van Rossumc1547d91996-12-10 15:39:04 +0000346#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
348 if (y && y != -1) {
Martin v. Löwis7e395722012-07-28 19:44:05 +0200349 /* Too large for TYPE_INT */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700350 w_PyLong((PyLongObject*)v, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 }
352 else
Guido van Rossumc1547d91996-12-10 15:39:04 +0000353#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700355 W_TYPE(TYPE_INT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 w_long(x, p);
357 }
358 }
359 }
360 else if (PyFloat_CheckExact(v)) {
361 if (p->version > 1) {
362 unsigned char buf[8];
363 if (_PyFloat_Pack8(PyFloat_AsDouble(v),
364 buf, 1) < 0) {
365 p->error = WFERR_UNMARSHALLABLE;
366 return;
367 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700368 W_TYPE(TYPE_BINARY_FLOAT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 w_string((char*)buf, 8, p);
370 }
371 else {
372 char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
373 'g', 17, 0, NULL);
374 if (!buf) {
375 p->error = WFERR_NOMEMORY;
376 return;
377 }
378 n = strlen(buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700379 W_TYPE(TYPE_FLOAT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 w_byte((int)n, p);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200381 w_string(buf, n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 PyMem_Free(buf);
383 }
384 }
385 else if (PyComplex_CheckExact(v)) {
386 if (p->version > 1) {
387 unsigned char buf[8];
388 if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
389 buf, 1) < 0) {
390 p->error = WFERR_UNMARSHALLABLE;
391 return;
392 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700393 W_TYPE(TYPE_BINARY_COMPLEX, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 w_string((char*)buf, 8, p);
395 if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
396 buf, 1) < 0) {
397 p->error = WFERR_UNMARSHALLABLE;
398 return;
399 }
400 w_string((char*)buf, 8, p);
401 }
402 else {
403 char *buf;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700404 W_TYPE(TYPE_COMPLEX, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
406 'g', 17, 0, NULL);
407 if (!buf) {
408 p->error = WFERR_NOMEMORY;
409 return;
410 }
411 n = strlen(buf);
412 w_byte((int)n, p);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200413 w_string(buf, n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 PyMem_Free(buf);
415 buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
416 'g', 17, 0, NULL);
417 if (!buf) {
418 p->error = WFERR_NOMEMORY;
419 return;
420 }
421 n = strlen(buf);
422 w_byte((int)n, p);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200423 w_string(buf, n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 PyMem_Free(buf);
425 }
426 }
427 else if (PyBytes_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700428 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300429 w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 }
431 else if (PyUnicode_CheckExact(v)) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200432 if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
433 int is_short = PyUnicode_GET_LENGTH(v) < 256;
434 if (is_short) {
435 if (PyUnicode_CHECK_INTERNED(v))
436 W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
437 else
438 W_TYPE(TYPE_SHORT_ASCII, p);
439 w_short_pstring((char *) PyUnicode_1BYTE_DATA(v),
440 PyUnicode_GET_LENGTH(v), p);
441 }
442 else {
443 if (PyUnicode_CHECK_INTERNED(v))
444 W_TYPE(TYPE_ASCII_INTERNED, p);
445 else
446 W_TYPE(TYPE_ASCII, p);
447 w_pstring((char *) PyUnicode_1BYTE_DATA(v),
448 PyUnicode_GET_LENGTH(v), p);
449 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200451 else {
452 PyObject *utf8;
453 utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
454 if (utf8 == NULL) {
455 p->depth--;
456 p->error = WFERR_UNMARSHALLABLE;
457 return;
458 }
459 if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
460 W_TYPE(TYPE_INTERNED, p);
461 else
462 W_TYPE(TYPE_UNICODE, p);
463 w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
464 Py_DECREF(utf8);
465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 }
467 else if (PyTuple_CheckExact(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 n = PyTuple_Size(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200469 if (p->version >= 4 && n < 256) {
470 W_TYPE(TYPE_SMALL_TUPLE, p);
Victor Stinnerda062552013-11-16 00:13:29 +0100471 w_byte((unsigned char)n, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200472 }
473 else {
474 W_TYPE(TYPE_TUPLE, p);
475 W_SIZE(n, p);
476 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 for (i = 0; i < n; i++) {
478 w_object(PyTuple_GET_ITEM(v, i), p);
479 }
480 }
481 else if (PyList_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700482 W_TYPE(TYPE_LIST, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 n = PyList_GET_SIZE(v);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200484 W_SIZE(n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 for (i = 0; i < n; i++) {
486 w_object(PyList_GET_ITEM(v, i), p);
487 }
488 }
489 else if (PyDict_CheckExact(v)) {
490 Py_ssize_t pos;
491 PyObject *key, *value;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700492 W_TYPE(TYPE_DICT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 /* This one is NULL object terminated! */
494 pos = 0;
495 while (PyDict_Next(v, &pos, &key, &value)) {
496 w_object(key, p);
497 w_object(value, p);
498 }
499 w_object((PyObject *)NULL, p);
500 }
501 else if (PyAnySet_CheckExact(v)) {
502 PyObject *value, *it;
Raymond Hettingera422c342005-01-11 03:03:27 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (PyObject_TypeCheck(v, &PySet_Type))
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700505 W_TYPE(TYPE_SET, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 else
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700507 W_TYPE(TYPE_FROZENSET, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 n = PyObject_Size(v);
509 if (n == -1) {
510 p->depth--;
511 p->error = WFERR_UNMARSHALLABLE;
512 return;
513 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200514 W_SIZE(n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 it = PyObject_GetIter(v);
516 if (it == NULL) {
517 p->depth--;
518 p->error = WFERR_UNMARSHALLABLE;
519 return;
520 }
521 while ((value = PyIter_Next(it)) != NULL) {
522 w_object(value, p);
523 Py_DECREF(value);
524 }
525 Py_DECREF(it);
526 if (PyErr_Occurred()) {
527 p->depth--;
528 p->error = WFERR_UNMARSHALLABLE;
529 return;
530 }
531 }
532 else if (PyCode_Check(v)) {
533 PyCodeObject *co = (PyCodeObject *)v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700534 W_TYPE(TYPE_CODE, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 w_long(co->co_argcount, p);
536 w_long(co->co_kwonlyargcount, p);
537 w_long(co->co_nlocals, p);
538 w_long(co->co_stacksize, p);
539 w_long(co->co_flags, p);
540 w_object(co->co_code, p);
541 w_object(co->co_consts, p);
542 w_object(co->co_names, p);
543 w_object(co->co_varnames, p);
544 w_object(co->co_freevars, p);
545 w_object(co->co_cellvars, p);
546 w_object(co->co_filename, p);
547 w_object(co->co_name, p);
548 w_long(co->co_firstlineno, p);
549 w_object(co->co_lnotab, p);
550 }
551 else if (PyObject_CheckBuffer(v)) {
Serhiy Storchakab757c832014-12-05 22:25:22 +0200552 /* Write unknown bytes-like objects as a byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 Py_buffer view;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100554 if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 w_byte(TYPE_UNKNOWN, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100556 p->depth--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 p->error = WFERR_UNMARSHALLABLE;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100558 return;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700560 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300561 w_pstring(view.buf, view.len, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100562 PyBuffer_Release(&view);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 }
564 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700565 W_TYPE(TYPE_UNKNOWN, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 p->error = WFERR_UNMARSHALLABLE;
567 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000568}
569
Serhiy Storchakace921c622015-02-11 15:53:31 +0200570static int
571w_init_refs(WFILE *wf, int version)
572{
573 if (version >= 3) {
574 wf->hashtable = _Py_hashtable_new(sizeof(int), _Py_hashtable_hash_ptr,
575 _Py_hashtable_compare_direct);
576 if (wf->hashtable == NULL) {
577 PyErr_NoMemory();
578 return -1;
579 }
580 }
581 return 0;
582}
583
584static int
585w_decref_entry(_Py_hashtable_entry_t *entry, void *Py_UNUSED(data))
586{
587 Py_XDECREF(entry->key);
588 return 0;
589}
590
591static void
592w_clear_refs(WFILE *wf)
593{
594 if (wf->hashtable != NULL) {
595 _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL);
596 _Py_hashtable_destroy(wf->hashtable);
597 }
598}
599
Serhiy Storchaka95949422013-08-27 19:40:23 +0300600/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000601void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000602PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000603{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200604 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200606 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200608 wf.ptr = wf.buf = buf;
609 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 wf.version = version;
612 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200613 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000614}
615
616void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000617PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000618{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200619 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200621 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200623 wf.ptr = wf.buf = buf;
624 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200627 if (w_init_refs(&wf, version))
628 return; /* caller mush check PyErr_Occurred() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200630 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200631 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000632}
633
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200634typedef struct {
635 FILE *fp;
636 int depth;
637 PyObject *readable; /* Stream-like object being read from */
638 PyObject *current_filename;
639 char *ptr;
640 char *end;
641 char *buf;
642 Py_ssize_t buf_size;
643 PyObject *refs; /* a list */
644} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000645
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200646static char *
647r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000648{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200649 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100650
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200651 if (p->ptr != NULL) {
652 /* Fast path for loads() */
653 char *res = p->ptr;
654 Py_ssize_t left = p->end - p->ptr;
655 if (left < n) {
656 PyErr_SetString(PyExc_EOFError,
657 "marshal data too short");
658 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100659 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200660 p->ptr += n;
661 return res;
662 }
663 if (p->buf == NULL) {
664 p->buf = PyMem_MALLOC(n);
665 if (p->buf == NULL) {
666 PyErr_NoMemory();
667 return NULL;
668 }
669 p->buf_size = n;
670 }
671 else if (p->buf_size < n) {
672 p->buf = PyMem_REALLOC(p->buf, n);
673 if (p->buf == NULL) {
674 PyErr_NoMemory();
675 return NULL;
676 }
677 p->buf_size = n;
678 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100679
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200680 if (!p->readable) {
681 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200682 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100683 }
684 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200685 _Py_IDENTIFIER(readinto);
686 PyObject *res, *mview;
687 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200688
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200689 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
690 return NULL;
691 mview = PyMemoryView_FromBuffer(&buf);
692 if (mview == NULL)
693 return NULL;
694
695 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
696 if (res != NULL) {
697 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
698 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100699 }
700 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200701 if (read != n) {
702 if (!PyErr_Occurred()) {
703 if (read > n)
704 PyErr_Format(PyExc_ValueError,
705 "read() returned too much data: "
706 "%zd bytes requested, %zd returned",
707 n, read);
708 else
709 PyErr_SetString(PyExc_EOFError,
710 "EOF read where not expected");
711 }
712 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100713 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200714 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100715}
716
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100717static int
718r_byte(RFILE *p)
719{
720 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100721
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200722 if (p->ptr != NULL) {
723 if (p->ptr < p->end)
724 c = (unsigned char) *p->ptr++;
725 return c;
726 }
727 if (!p->readable) {
728 assert(p->fp);
729 c = getc(p->fp);
730 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100731 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200732 char *ptr = r_string(1, p);
733 if (ptr != NULL)
734 c = *(unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100735 }
736 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000737}
738
739static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000740r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000741{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200742 short x = -1;
743 unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100744
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200745 buffer = (unsigned char *) r_string(2, p);
746 if (buffer != NULL) {
747 x = buffer[0];
748 x |= buffer[1] << 8;
749 /* Sign-extension, in case short greater than 16 bits */
750 x |= -(x & 0x8000);
751 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000753}
754
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000755static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000756r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000757{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200758 long x = -1;
759 unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100760
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200761 buffer = (unsigned char *) r_string(4, p);
762 if (buffer != NULL) {
763 x = buffer[0];
764 x |= (long)buffer[1] << 8;
765 x |= (long)buffer[2] << 16;
766 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000767#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200768 /* Sign extension for 64-bit machines */
769 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000770#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200771 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000773}
774
Guido van Rossum79f25d91997-04-29 20:08:16 +0000775static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000776r_PyLong(RFILE *p)
777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200779 long n, size, i;
780 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100784 if (PyErr_Occurred())
785 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 if (n == 0)
787 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200788 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 PyErr_SetString(PyExc_ValueError,
790 "bad marshal data (long size out of range)");
791 return NULL;
792 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000793
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200794 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
795 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 ob = _PyLong_New(size);
797 if (ob == NULL)
798 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 Py_SIZE(ob) = n > 0 ? size : -size;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 for (i = 0; i < size-1; i++) {
803 d = 0;
804 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
805 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100806 if (PyErr_Occurred()) {
807 Py_DECREF(ob);
808 return NULL;
809 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 if (md < 0 || md > PyLong_MARSHAL_BASE)
811 goto bad_digit;
812 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
813 }
814 ob->ob_digit[i] = d;
815 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 d = 0;
818 for (j=0; j < shorts_in_top_digit; j++) {
819 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100820 if (PyErr_Occurred()) {
821 Py_DECREF(ob);
822 return NULL;
823 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 if (md < 0 || md > PyLong_MARSHAL_BASE)
825 goto bad_digit;
826 /* topmost marshal digit should be nonzero */
827 if (md == 0 && j == shorts_in_top_digit - 1) {
828 Py_DECREF(ob);
829 PyErr_SetString(PyExc_ValueError,
830 "bad marshal data (unnormalized long data)");
831 return NULL;
832 }
833 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
834 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100835 if (PyErr_Occurred()) {
836 Py_DECREF(ob);
837 return NULL;
838 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 /* top digit should be nonzero, else the resulting PyLong won't be
840 normalized */
841 ob->ob_digit[size-1] = d;
842 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000843 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 Py_DECREF(ob);
845 PyErr_SetString(PyExc_ValueError,
846 "bad marshal data (digit out of range in long)");
847 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000848}
849
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700850/* allocate the reflist index for a new object. Return -1 on failure */
851static Py_ssize_t
852r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700853{
854 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200855 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700856 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700857 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700858 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700859 }
860 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700861 return -1;
862 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700863 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700864 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700865}
866
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700867/* insert the new object 'o' to the reflist at previously
868 * allocated index 'idx'.
869 * 'o' can be NULL, in which case nothing is done.
870 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
871 * if 'o' was non-NULL, and the function fails, 'o' is released and
872 * NULL returned. This simplifies error checking at the call site since
873 * a single test for NULL for the function result is enough.
874 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700875static PyObject *
876r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
877{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700878 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200879 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
880 Py_INCREF(o);
881 PyList_SET_ITEM(p->refs, idx, o);
882 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700883 }
884 return o;
885}
886
887/* combination of both above, used when an object can be
888 * created whenever it is seen in the file, as opposed to
889 * after having loaded its sub-objects.
890 */
891static PyObject *
892r_ref(PyObject *o, int flag, RFILE *p)
893{
Victor Stinner359fabc2013-10-31 17:09:01 +0100894 assert(flag & FLAG_REF);
895 if (o == NULL)
896 return NULL;
897 if (PyList_Append(p->refs, o) < 0) {
898 Py_DECREF(o); /* release the new object */
899 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700900 }
901 return o;
902}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000903
904static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000905r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 /* NULL is a valid return value, it does not necessarily means that
908 an exception is set. */
909 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500910 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700912 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200913 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200914 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000915
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700916 if (code == EOF) {
917 PyErr_SetString(PyExc_EOFError,
918 "EOF read where object expected");
919 return NULL;
920 }
921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
925 p->depth--;
926 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
927 return NULL;
928 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000929
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700930 flag = code & FLAG_REF;
931 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700932
933#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700934 if (flag) \
935 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700936} while (0)
937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 case TYPE_NONE:
944 Py_INCREF(Py_None);
945 retval = Py_None;
946 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 case TYPE_STOPITER:
949 Py_INCREF(PyExc_StopIteration);
950 retval = PyExc_StopIteration;
951 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 case TYPE_ELLIPSIS:
954 Py_INCREF(Py_Ellipsis);
955 retval = Py_Ellipsis;
956 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 case TYPE_FALSE:
959 Py_INCREF(Py_False);
960 retval = Py_False;
961 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 case TYPE_TRUE:
964 Py_INCREF(Py_True);
965 retval = Py_True;
966 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100969 n = r_long(p);
970 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700971 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 case TYPE_LONG:
975 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700976 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 case TYPE_FLOAT:
980 {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200981 char buf[256], *ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 double dx;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +0300984 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 PyErr_SetString(PyExc_EOFError,
986 "EOF read where object expected");
987 break;
988 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200989 ptr = r_string(n, p);
990 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +0300991 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200992 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 buf[n] = '\0';
994 dx = PyOS_string_to_double(buf, NULL, NULL);
995 if (dx == -1.0 && PyErr_Occurred())
996 break;
997 retval = PyFloat_FromDouble(dx);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700998 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 break;
1000 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 case TYPE_BINARY_FLOAT:
1003 {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001004 unsigned char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 double x;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001006 buf = (unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001007 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 x = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001010 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001013 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 break;
1015 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 case TYPE_COMPLEX:
1018 {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001019 char buf[256], *ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 Py_complex c;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001022 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyErr_SetString(PyExc_EOFError,
1024 "EOF read where object expected");
1025 break;
1026 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001027 ptr = r_string(n, p);
1028 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001029 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001030 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 buf[n] = '\0';
1032 c.real = PyOS_string_to_double(buf, NULL, NULL);
1033 if (c.real == -1.0 && PyErr_Occurred())
1034 break;
1035 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001036 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 PyErr_SetString(PyExc_EOFError,
1038 "EOF read where object expected");
1039 break;
1040 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001041 ptr = r_string(n, p);
1042 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001043 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001044 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 buf[n] = '\0';
1046 c.imag = PyOS_string_to_double(buf, NULL, NULL);
1047 if (c.imag == -1.0 && PyErr_Occurred())
1048 break;
1049 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001050 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 break;
1052 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 case TYPE_BINARY_COMPLEX:
1055 {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001056 unsigned char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 Py_complex c;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001058 buf = (unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001059 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 c.real = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001062 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001064 buf = (unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001065 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 c.imag = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001068 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001071 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 break;
1073 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001076 {
1077 char *ptr;
1078 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001079 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001080 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001081 if (n < 0 || n > SIZE32_MAX) {
1082 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001083 break;
1084 }
1085 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001086 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001087 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001088 ptr = r_string(n, p);
1089 if (ptr == NULL) {
1090 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001091 break;
1092 }
1093 memcpy(PyBytes_AS_STRING(v), ptr, n);
1094 retval = v;
1095 R_REF(retval);
1096 break;
1097 }
1098
1099 case TYPE_ASCII_INTERNED:
1100 is_interned = 1;
1101 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001103 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001104 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001105 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001106 PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 break;
1108 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001109 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001110
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001111 case TYPE_SHORT_ASCII_INTERNED:
1112 is_interned = 1;
1113 case TYPE_SHORT_ASCII:
1114 n = r_byte(p);
1115 if (n == EOF) {
1116 PyErr_SetString(PyExc_EOFError,
1117 "EOF read where object expected");
1118 break;
1119 }
1120 _read_ascii:
1121 {
1122 char *ptr;
1123 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001124 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001125 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001126 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001127 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001128 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001129 if (is_interned)
1130 PyUnicode_InternInPlace(&v);
1131 retval = v;
1132 R_REF(retval);
1133 break;
1134 }
1135
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001136 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001137 is_interned = 1;
1138 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 {
1140 char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001143 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001144 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001145 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 break;
1148 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001149 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001150 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001151 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001152 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001153 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001155 else {
1156 v = PyUnicode_New(0, 0);
1157 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001158 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001159 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001160 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001161 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001163 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 break;
1165 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001166
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001167 case TYPE_SMALL_TUPLE:
1168 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001169 if (PyErr_Occurred())
1170 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001171 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 case TYPE_TUPLE:
1173 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001174 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001175 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001176 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 break;
1179 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001180 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001181 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001182 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001183 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 for (i = 0; i < n; i++) {
1187 v2 = r_object(p);
1188 if ( v2 == NULL ) {
1189 if (!PyErr_Occurred())
1190 PyErr_SetString(PyExc_TypeError,
1191 "NULL object in marshal data for tuple");
1192 Py_DECREF(v);
1193 v = NULL;
1194 break;
1195 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001196 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 }
1198 retval = v;
1199 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 case TYPE_LIST:
1202 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001203 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001204 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001205 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 break;
1208 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001209 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001210 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001211 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 for (i = 0; i < n; i++) {
1214 v2 = r_object(p);
1215 if ( v2 == NULL ) {
1216 if (!PyErr_Occurred())
1217 PyErr_SetString(PyExc_TypeError,
1218 "NULL object in marshal data for list");
1219 Py_DECREF(v);
1220 v = NULL;
1221 break;
1222 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001223 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 }
1225 retval = v;
1226 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 case TYPE_DICT:
1229 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001230 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001231 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 for (;;) {
1234 PyObject *key, *val;
1235 key = r_object(p);
1236 if (key == NULL)
1237 break;
1238 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001239 if (val == NULL) {
1240 Py_DECREF(key);
1241 break;
1242 }
1243 if (PyDict_SetItem(v, key, val) < 0) {
1244 Py_DECREF(key);
1245 Py_DECREF(val);
1246 break;
1247 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001249 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 }
1251 if (PyErr_Occurred()) {
1252 Py_DECREF(v);
1253 v = NULL;
1254 }
1255 retval = v;
1256 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 case TYPE_SET:
1259 case TYPE_FROZENSET:
1260 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001261 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001262 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001263 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 break;
1266 }
1267 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001268 if (type == TYPE_SET) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001269 R_REF(v);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001270 } else {
1271 /* must use delayed registration of frozensets because they must
1272 * be init with a refcount of 1
1273 */
1274 idx = r_ref_reserve(flag, p);
1275 if (idx < 0)
1276 Py_CLEAR(v); /* signal error */
1277 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001278 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 for (i = 0; i < n; i++) {
1282 v2 = r_object(p);
1283 if ( v2 == NULL ) {
1284 if (!PyErr_Occurred())
1285 PyErr_SetString(PyExc_TypeError,
1286 "NULL object in marshal data for set");
1287 Py_DECREF(v);
1288 v = NULL;
1289 break;
1290 }
1291 if (PySet_Add(v, v2) == -1) {
1292 Py_DECREF(v);
1293 Py_DECREF(v2);
1294 v = NULL;
1295 break;
1296 }
1297 Py_DECREF(v2);
1298 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001299 if (type != TYPE_SET)
1300 v = r_ref_insert(v, idx, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 retval = v;
1302 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 case TYPE_CODE:
1305 {
1306 int argcount;
1307 int kwonlyargcount;
1308 int nlocals;
1309 int stacksize;
1310 int flags;
1311 PyObject *code = NULL;
1312 PyObject *consts = NULL;
1313 PyObject *names = NULL;
1314 PyObject *varnames = NULL;
1315 PyObject *freevars = NULL;
1316 PyObject *cellvars = NULL;
1317 PyObject *filename = NULL;
1318 PyObject *name = NULL;
1319 int firstlineno;
1320 PyObject *lnotab = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001321
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001322 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001323 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001324 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 /* XXX ignore long->int overflows for now */
1329 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001330 if (PyErr_Occurred())
1331 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 kwonlyargcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001333 if (PyErr_Occurred())
1334 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 nlocals = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001336 if (PyErr_Occurred())
1337 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 stacksize = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001339 if (PyErr_Occurred())
1340 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 flags = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001342 if (PyErr_Occurred())
1343 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 code = r_object(p);
1345 if (code == NULL)
1346 goto code_error;
1347 consts = r_object(p);
1348 if (consts == NULL)
1349 goto code_error;
1350 names = r_object(p);
1351 if (names == NULL)
1352 goto code_error;
1353 varnames = r_object(p);
1354 if (varnames == NULL)
1355 goto code_error;
1356 freevars = r_object(p);
1357 if (freevars == NULL)
1358 goto code_error;
1359 cellvars = r_object(p);
1360 if (cellvars == NULL)
1361 goto code_error;
1362 filename = r_object(p);
1363 if (filename == NULL)
1364 goto code_error;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001365 if (PyUnicode_CheckExact(filename)) {
1366 if (p->current_filename != NULL) {
1367 if (!PyUnicode_Compare(filename, p->current_filename)) {
1368 Py_DECREF(filename);
1369 Py_INCREF(p->current_filename);
1370 filename = p->current_filename;
1371 }
1372 }
1373 else {
1374 p->current_filename = filename;
1375 }
1376 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 name = r_object(p);
1378 if (name == NULL)
1379 goto code_error;
1380 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001381 if (firstlineno == -1 && PyErr_Occurred())
1382 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 lnotab = r_object(p);
1384 if (lnotab == NULL)
1385 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 v = (PyObject *) PyCode_New(
1388 argcount, kwonlyargcount,
1389 nlocals, stacksize, flags,
1390 code, consts, names, varnames,
1391 freevars, cellvars, filename, name,
1392 firstlineno, lnotab);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001393 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 code_error:
1396 Py_XDECREF(code);
1397 Py_XDECREF(consts);
1398 Py_XDECREF(names);
1399 Py_XDECREF(varnames);
1400 Py_XDECREF(freevars);
1401 Py_XDECREF(cellvars);
1402 Py_XDECREF(filename);
1403 Py_XDECREF(name);
1404 Py_XDECREF(lnotab);
1405 }
1406 retval = v;
1407 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001408
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001409 case TYPE_REF:
1410 n = r_long(p);
1411 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001412 if (n == -1 && PyErr_Occurred())
1413 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001414 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001415 break;
1416 }
1417 v = PyList_GET_ITEM(p->refs, n);
1418 if (v == Py_None) {
1419 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001420 break;
1421 }
1422 Py_INCREF(v);
1423 retval = v;
1424 break;
1425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 default:
1427 /* Bogus data got written, which isn't ideal.
1428 This will let you keep working and recover. */
1429 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 break;
1431
1432 }
1433 p->depth--;
1434 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001435}
1436
Neal Norwitzd85c4522004-06-13 20:31:49 +00001437static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001438read_object(RFILE *p)
1439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 PyObject *v;
1441 if (PyErr_Occurred()) {
1442 fprintf(stderr, "XXX readobject called with exception set\n");
1443 return NULL;
1444 }
1445 v = r_object(p);
1446 if (v == NULL && !PyErr_Occurred())
1447 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1448 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001449}
1450
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001451int
1452PyMarshal_ReadShortFromFile(FILE *fp)
1453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001455 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001457 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 rf.fp = fp;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001459 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001461 rf.buf = NULL;
1462 res = r_short(&rf);
1463 if (rf.buf != NULL)
1464 PyMem_FREE(rf.buf);
1465 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001466}
1467
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001468long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001469PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001472 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001474 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001475 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001477 rf.buf = NULL;
1478 res = r_long(&rf);
1479 if (rf.buf != NULL)
1480 PyMem_FREE(rf.buf);
1481 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001482}
1483
Steve Dowerf2f373f2015-02-21 08:44:05 -08001484/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001485static off_t
1486getfilesize(FILE *fp)
1487{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001488 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001489 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001491#if SIZEOF_OFF_T == 4
1492 else if (st.st_size >= INT_MAX)
1493 return (off_t)INT_MAX;
1494#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001496 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001497}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001498
Tim Peters691e0e92001-01-18 04:39:16 +00001499/* If we can get the size of the file up-front, and it's reasonably small,
1500 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1501 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001502 * CAUTION: since this may read the entire remainder of the file, don't
1503 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001504 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001505PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001506PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001507{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001508/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001509#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 off_t filesize;
1511 filesize = getfilesize(fp);
1512 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1513 char* pBuf = (char *)PyMem_MALLOC(filesize);
1514 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001515 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1516 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 PyMem_FREE(pBuf);
1518 return v;
1519 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 /* We don't have fstat, or we do but the file is larger than
1523 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1524 */
1525 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001526
Tim Peters691e0e92001-01-18 04:39:16 +00001527#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001528}
1529
Guido van Rossum79f25d91997-04-29 20:08:16 +00001530PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001531PyMarshal_ReadObjectFromFile(FILE *fp)
1532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 RFILE rf;
1534 PyObject *result;
1535 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001536 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001537 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 rf.depth = 0;
1539 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001540 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001541 rf.refs = PyList_New(0);
1542 if (rf.refs == NULL)
1543 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001545 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001546 if (rf.buf != NULL)
1547 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001549}
1550
1551PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001552PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 RFILE rf;
1555 PyObject *result;
1556 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001557 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001558 rf.current_filename = NULL;
Serhiy Storchakac6792272013-10-19 21:03:34 +03001559 rf.ptr = (char *)str;
1560 rf.end = (char *)str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001561 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001563 rf.refs = PyList_New(0);
1564 if (rf.refs == NULL)
1565 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001567 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001568 if (rf.buf != NULL)
1569 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001571}
1572
Guido van Rossum79f25d91997-04-29 20:08:16 +00001573PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001574PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001577
Serhiy Storchakace921c622015-02-11 15:53:31 +02001578 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1580 if (wf.str == NULL)
1581 return NULL;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +02001582 wf.ptr = wf.buf = PyBytes_AS_STRING((PyBytesObject *)wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 wf.end = wf.ptr + PyBytes_Size(wf.str);
1584 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001586 if (w_init_refs(&wf, version)) {
1587 Py_DECREF(wf.str);
1588 return NULL;
1589 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001591 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 if (wf.str != NULL) {
1593 char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
1594 if (wf.ptr - base > PY_SSIZE_T_MAX) {
1595 Py_DECREF(wf.str);
1596 PyErr_SetString(PyExc_OverflowError,
1597 "too much marshal data for a string");
1598 return NULL;
1599 }
1600 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1601 return NULL;
1602 }
1603 if (wf.error != WFERR_OK) {
1604 Py_XDECREF(wf.str);
1605 if (wf.error == WFERR_NOMEMORY)
1606 PyErr_NoMemory();
1607 else
1608 PyErr_SetString(PyExc_ValueError,
1609 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1610 :"object too deeply nested to marshal");
1611 return NULL;
1612 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001613 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001614}
1615
Guido van Rossum64b45521991-06-07 13:58:22 +00001616/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001617
Guido van Rossum79f25d91997-04-29 20:08:16 +00001618static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001619marshal_dump(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 /* XXX Quick hack -- need to do this differently */
1622 PyObject *x;
1623 PyObject *f;
1624 int version = Py_MARSHAL_VERSION;
1625 PyObject *s;
1626 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001627 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
1630 return NULL;
1631 s = PyMarshal_WriteObjectToString(x, version);
1632 if (s == NULL)
1633 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001634 res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 Py_DECREF(s);
1636 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001637}
1638
R. David Murraydd226ea2009-05-13 12:27:21 +00001639PyDoc_STRVAR(dump_doc,
1640"dump(value, file[, version])\n\
1641\n\
1642Write the value on the open file. The value must be a supported type.\n\
1643The file must be an open file object such as sys.stdout or returned by\n\
1644open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
1645\n\
1646If the value has (or contains an object that has) an unsupported type, a\n\
Serhiy Storchaka225821c2015-12-18 13:05:04 +02001647ValueError exception is raised - but garbage data will also be written\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001648to the file. The object will not be properly read back by load()\n\
1649\n\
1650The version argument indicates the data format that dump should use.");
1651
Guido van Rossum79f25d91997-04-29 20:08:16 +00001652static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001653marshal_load(PyObject *self, PyObject *f)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001656 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001658
1659 /*
1660 * Make a call to the read method, but read zero bytes.
1661 * This is to ensure that the object passed in at least
1662 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001663 * This can be removed if we guarantee good error handling
1664 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001665 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001666 data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 if (data == NULL)
1668 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001669 if (!PyBytes_Check(data)) {
1670 PyErr_Format(PyExc_TypeError,
1671 "f.read() returned not bytes but %.100s",
1672 data->ob_type->tp_name);
1673 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 }
1675 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001676 rf.depth = 0;
1677 rf.fp = NULL;
1678 rf.readable = f;
Vinay Sajipaac0f752011-07-02 18:42:21 +01001679 rf.current_filename = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001680 rf.ptr = rf.end = NULL;
1681 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001682 if ((rf.refs = PyList_New(0)) != NULL) {
1683 result = read_object(&rf);
1684 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001685 if (rf.buf != NULL)
1686 PyMem_FREE(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001687 } else
1688 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 Py_DECREF(data);
1691 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001692}
1693
R. David Murraydd226ea2009-05-13 12:27:21 +00001694PyDoc_STRVAR(load_doc,
1695"load(file)\n\
1696\n\
1697Read one value from the open file and return it. If no valid value is\n\
Serhiy Storchaka225821c2015-12-18 13:05:04 +02001698read (e.g. because the data has a different Python version's\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001699incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
1700The file must be an open file object opened in binary mode ('rb' or\n\
1701'r+b').\n\
1702\n\
1703Note: If an object containing an unsupported type was marshalled with\n\
1704dump(), load() will substitute None for the unmarshallable type.");
1705
1706
Guido van Rossum79f25d91997-04-29 20:08:16 +00001707static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001708marshal_dumps(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001709{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 PyObject *x;
1711 int version = Py_MARSHAL_VERSION;
1712 if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
1713 return NULL;
1714 return PyMarshal_WriteObjectToString(x, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001715}
1716
R. David Murraydd226ea2009-05-13 12:27:21 +00001717PyDoc_STRVAR(dumps_doc,
1718"dumps(value[, version])\n\
1719\n\
1720Return the string that would be written to a file by dump(value, file).\n\
1721The value must be a supported type. Raise a ValueError exception if\n\
1722value has (or contains an object that has) an unsupported type.\n\
1723\n\
1724The version argument indicates the data format that dumps should use.");
1725
1726
Guido van Rossum79f25d91997-04-29 20:08:16 +00001727static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001728marshal_loads(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 RFILE rf;
1731 Py_buffer p;
1732 char *s;
1733 Py_ssize_t n;
1734 PyObject* result;
Antoine Pitrou4a90ef02012-03-03 02:35:32 +01001735 if (!PyArg_ParseTuple(args, "y*:loads", &p))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 return NULL;
1737 s = p.buf;
1738 n = p.len;
1739 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001740 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001741 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 rf.ptr = s;
1743 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001745 if ((rf.refs = PyList_New(0)) == NULL)
1746 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 result = read_object(&rf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 PyBuffer_Release(&p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001749 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001751}
1752
R. David Murraydd226ea2009-05-13 12:27:21 +00001753PyDoc_STRVAR(loads_doc,
Antoine Pitrou4a90ef02012-03-03 02:35:32 +01001754"loads(bytes)\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001755\n\
Antoine Pitrou4a90ef02012-03-03 02:35:32 +01001756Convert the bytes object to a value. If no valid value is found, raise\n\
1757EOFError, ValueError or TypeError. Extra characters in the input are\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001758ignored.");
1759
Guido van Rossum79f25d91997-04-29 20:08:16 +00001760static PyMethodDef marshal_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 {"dump", marshal_dump, METH_VARARGS, dump_doc},
1762 {"load", marshal_load, METH_O, load_doc},
1763 {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
1764 {"loads", marshal_loads, METH_VARARGS, loads_doc},
1765 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001766};
1767
R. David Murraydd226ea2009-05-13 12:27:21 +00001768
1769PyDoc_STRVAR(module_doc,
1770"This module contains functions that can read and write Python values in\n\
1771a binary format. The format is specific to Python, but independent of\n\
1772machine architecture issues.\n\
1773\n\
1774Not all Python object types are supported; in general, only objects\n\
1775whose value is independent from a particular invocation of Python can be\n\
1776written and read by this module. The following types are supported:\n\
1777None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1778tuples, lists, sets, dictionaries, and code objects, where it\n\
1779should be understood that tuples, lists and dictionaries are only\n\
1780supported as long as the values contained therein are themselves\n\
1781supported; and recursive lists and dictionaries should not be written\n\
1782(they will cause infinite loops).\n\
1783\n\
1784Variables:\n\
1785\n\
1786version -- indicates the format that the module uses. Version 0 is the\n\
1787 historical format, version 1 shares interned strings and version 2\n\
1788 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001789 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001790\n\
1791Functions:\n\
1792\n\
1793dump() -- write value to a file\n\
1794load() -- read value from a file\n\
1795dumps() -- write value to a string\n\
1796loads() -- read value from a string");
1797
1798
1799
Brett Cannon429ef652008-06-27 00:35:35 +00001800static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 PyModuleDef_HEAD_INIT,
1802 "marshal",
1803 module_doc,
1804 0,
1805 marshal_methods,
1806 NULL,
1807 NULL,
1808 NULL,
1809 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001810};
1811
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001812PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001813PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 PyObject *mod = PyModule_Create(&marshalmodule);
1816 if (mod == NULL)
1817 return NULL;
1818 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
1819 return mod;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001820}