blob: 22ca49c75629edc783844909655115b723466231 [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) {
Christian Heimesf051e432016-09-13 20:22:02 +0200133 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200134 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)) {
Christian Heimesf051e432016-09-13 20:22:02 +0200143 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200144 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
Victor Stinner285cf0a2016-03-21 22:00:58 +0100266 entry = _Py_HASHTABLE_GET_ENTRY(p->hashtable, v);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200267 if (entry != NULL) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700268 /* write the reference index to the stream */
Victor Stinnere8c6b2f2016-03-23 09:25:01 +0100269 _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, entry, w);
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 Storchaka4652d822017-03-12 10:05:05 +0200552 /* Write unknown bytes-like objects as a bytes object */
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) {
Victor Stinner285cf0a2016-03-21 22:00:58 +0100574 wf->hashtable = _Py_hashtable_new(sizeof(PyObject *), sizeof(int),
575 _Py_hashtable_hash_ptr,
Serhiy Storchakace921c622015-02-11 15:53:31 +0200576 _Py_hashtable_compare_direct);
577 if (wf->hashtable == NULL) {
578 PyErr_NoMemory();
579 return -1;
580 }
581 }
582 return 0;
583}
584
585static int
Victor Stinner285cf0a2016-03-21 22:00:58 +0100586w_decref_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry,
587 void *Py_UNUSED(data))
Serhiy Storchakace921c622015-02-11 15:53:31 +0200588{
Victor Stinner285cf0a2016-03-21 22:00:58 +0100589 PyObject *entry_key;
590
Victor Stinner5dacbd42016-03-23 09:52:13 +0100591 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, entry_key);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100592 Py_XDECREF(entry_key);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200593 return 0;
594}
595
596static void
597w_clear_refs(WFILE *wf)
598{
599 if (wf->hashtable != NULL) {
600 _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL);
601 _Py_hashtable_destroy(wf->hashtable);
602 }
603}
604
Serhiy Storchaka95949422013-08-27 19:40:23 +0300605/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000606void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000607PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000608{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200609 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200611 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200613 wf.ptr = wf.buf = buf;
614 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 wf.version = version;
617 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200618 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000619}
620
621void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000622PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000623{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200624 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200626 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200628 wf.ptr = wf.buf = buf;
629 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200632 if (w_init_refs(&wf, version))
633 return; /* caller mush check PyErr_Occurred() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200635 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200636 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000637}
638
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200639typedef struct {
640 FILE *fp;
641 int depth;
642 PyObject *readable; /* Stream-like object being read from */
643 PyObject *current_filename;
644 char *ptr;
645 char *end;
646 char *buf;
647 Py_ssize_t buf_size;
648 PyObject *refs; /* a list */
649} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000650
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200651static const char *
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200652r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000653{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200654 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100655
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200656 if (p->ptr != NULL) {
657 /* Fast path for loads() */
658 char *res = p->ptr;
659 Py_ssize_t left = p->end - p->ptr;
660 if (left < n) {
661 PyErr_SetString(PyExc_EOFError,
662 "marshal data too short");
663 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100664 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200665 p->ptr += n;
666 return res;
667 }
668 if (p->buf == NULL) {
669 p->buf = PyMem_MALLOC(n);
670 if (p->buf == NULL) {
671 PyErr_NoMemory();
672 return NULL;
673 }
674 p->buf_size = n;
675 }
676 else if (p->buf_size < n) {
677 p->buf = PyMem_REALLOC(p->buf, n);
678 if (p->buf == NULL) {
679 PyErr_NoMemory();
680 return NULL;
681 }
682 p->buf_size = n;
683 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100684
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200685 if (!p->readable) {
686 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200687 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100688 }
689 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200690 _Py_IDENTIFIER(readinto);
691 PyObject *res, *mview;
692 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200693
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200694 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
695 return NULL;
696 mview = PyMemoryView_FromBuffer(&buf);
697 if (mview == NULL)
698 return NULL;
699
700 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
701 if (res != NULL) {
702 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
703 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100704 }
705 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200706 if (read != n) {
707 if (!PyErr_Occurred()) {
708 if (read > n)
709 PyErr_Format(PyExc_ValueError,
710 "read() returned too much data: "
711 "%zd bytes requested, %zd returned",
712 n, read);
713 else
714 PyErr_SetString(PyExc_EOFError,
715 "EOF read where not expected");
716 }
717 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100718 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200719 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100720}
721
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100722static int
723r_byte(RFILE *p)
724{
725 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100726
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200727 if (p->ptr != NULL) {
728 if (p->ptr < p->end)
729 c = (unsigned char) *p->ptr++;
730 return c;
731 }
732 if (!p->readable) {
733 assert(p->fp);
734 c = getc(p->fp);
735 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100736 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200737 const char *ptr = r_string(1, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200738 if (ptr != NULL)
739 c = *(unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100740 }
741 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000742}
743
744static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000745r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000746{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200747 short x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200748 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100749
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200750 buffer = (const unsigned char *) r_string(2, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200751 if (buffer != NULL) {
752 x = buffer[0];
753 x |= buffer[1] << 8;
754 /* Sign-extension, in case short greater than 16 bits */
755 x |= -(x & 0x8000);
756 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000758}
759
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000760static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000761r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000762{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200763 long x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200764 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100765
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200766 buffer = (const unsigned char *) r_string(4, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200767 if (buffer != NULL) {
768 x = buffer[0];
769 x |= (long)buffer[1] << 8;
770 x |= (long)buffer[2] << 16;
771 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000772#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200773 /* Sign extension for 64-bit machines */
774 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000775#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200776 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000778}
779
Guido van Rossum79f25d91997-04-29 20:08:16 +0000780static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000781r_PyLong(RFILE *p)
782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200784 long n, size, i;
785 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100789 if (PyErr_Occurred())
790 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 if (n == 0)
792 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200793 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 PyErr_SetString(PyExc_ValueError,
795 "bad marshal data (long size out of range)");
796 return NULL;
797 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000798
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200799 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
800 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 ob = _PyLong_New(size);
802 if (ob == NULL)
803 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 Py_SIZE(ob) = n > 0 ? size : -size;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 for (i = 0; i < size-1; i++) {
808 d = 0;
809 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
810 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100811 if (PyErr_Occurred()) {
812 Py_DECREF(ob);
813 return NULL;
814 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 if (md < 0 || md > PyLong_MARSHAL_BASE)
816 goto bad_digit;
817 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
818 }
819 ob->ob_digit[i] = d;
820 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 d = 0;
823 for (j=0; j < shorts_in_top_digit; j++) {
824 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100825 if (PyErr_Occurred()) {
826 Py_DECREF(ob);
827 return NULL;
828 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 if (md < 0 || md > PyLong_MARSHAL_BASE)
830 goto bad_digit;
831 /* topmost marshal digit should be nonzero */
832 if (md == 0 && j == shorts_in_top_digit - 1) {
833 Py_DECREF(ob);
834 PyErr_SetString(PyExc_ValueError,
835 "bad marshal data (unnormalized long data)");
836 return NULL;
837 }
838 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
839 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100840 if (PyErr_Occurred()) {
841 Py_DECREF(ob);
842 return NULL;
843 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 /* top digit should be nonzero, else the resulting PyLong won't be
845 normalized */
846 ob->ob_digit[size-1] = d;
847 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000848 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 Py_DECREF(ob);
850 PyErr_SetString(PyExc_ValueError,
851 "bad marshal data (digit out of range in long)");
852 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000853}
854
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700855/* allocate the reflist index for a new object. Return -1 on failure */
856static Py_ssize_t
857r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700858{
859 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200860 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700861 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700862 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700863 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700864 }
865 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700866 return -1;
867 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700868 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700869 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700870}
871
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700872/* insert the new object 'o' to the reflist at previously
873 * allocated index 'idx'.
874 * 'o' can be NULL, in which case nothing is done.
875 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
876 * if 'o' was non-NULL, and the function fails, 'o' is released and
877 * NULL returned. This simplifies error checking at the call site since
878 * a single test for NULL for the function result is enough.
879 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700880static PyObject *
881r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
882{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700883 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200884 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
885 Py_INCREF(o);
886 PyList_SET_ITEM(p->refs, idx, o);
887 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700888 }
889 return o;
890}
891
892/* combination of both above, used when an object can be
893 * created whenever it is seen in the file, as opposed to
894 * after having loaded its sub-objects.
895 */
896static PyObject *
897r_ref(PyObject *o, int flag, RFILE *p)
898{
Victor Stinner359fabc2013-10-31 17:09:01 +0100899 assert(flag & FLAG_REF);
900 if (o == NULL)
901 return NULL;
902 if (PyList_Append(p->refs, o) < 0) {
903 Py_DECREF(o); /* release the new object */
904 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700905 }
906 return o;
907}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000908
909static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000910r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 /* NULL is a valid return value, it does not necessarily means that
913 an exception is set. */
914 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500915 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700917 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200918 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200919 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000920
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700921 if (code == EOF) {
922 PyErr_SetString(PyExc_EOFError,
923 "EOF read where object expected");
924 return NULL;
925 }
926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
930 p->depth--;
931 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
932 return NULL;
933 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000934
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700935 flag = code & FLAG_REF;
936 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700937
938#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700939 if (flag) \
940 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700941} while (0)
942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 case TYPE_NONE:
949 Py_INCREF(Py_None);
950 retval = Py_None;
951 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 case TYPE_STOPITER:
954 Py_INCREF(PyExc_StopIteration);
955 retval = PyExc_StopIteration;
956 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 case TYPE_ELLIPSIS:
959 Py_INCREF(Py_Ellipsis);
960 retval = Py_Ellipsis;
961 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 case TYPE_FALSE:
964 Py_INCREF(Py_False);
965 retval = Py_False;
966 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 case TYPE_TRUE:
969 Py_INCREF(Py_True);
970 retval = Py_True;
971 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100974 n = r_long(p);
975 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
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_LONG:
980 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700981 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 case TYPE_FLOAT:
985 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200986 char buf[256];
987 const char *ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 double dx;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +0300990 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 PyErr_SetString(PyExc_EOFError,
992 "EOF read where object expected");
993 break;
994 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200995 ptr = r_string(n, p);
996 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +0300997 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200998 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 buf[n] = '\0';
1000 dx = PyOS_string_to_double(buf, NULL, NULL);
1001 if (dx == -1.0 && PyErr_Occurred())
1002 break;
1003 retval = PyFloat_FromDouble(dx);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001004 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 break;
1006 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 case TYPE_BINARY_FLOAT:
1009 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001010 const unsigned char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 double x;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001012 buf = (const unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001013 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 x = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001016 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001019 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 break;
1021 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 case TYPE_COMPLEX:
1024 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001025 char buf[256];
1026 const char *ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 Py_complex c;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001029 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyErr_SetString(PyExc_EOFError,
1031 "EOF read where object expected");
1032 break;
1033 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001034 ptr = r_string(n, p);
1035 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001036 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001037 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 buf[n] = '\0';
1039 c.real = PyOS_string_to_double(buf, NULL, NULL);
1040 if (c.real == -1.0 && PyErr_Occurred())
1041 break;
1042 n = r_byte(p);
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001043 if (n == EOF) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 PyErr_SetString(PyExc_EOFError,
1045 "EOF read where object expected");
1046 break;
1047 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001048 ptr = r_string(n, p);
1049 if (ptr == NULL)
Serhiy Storchaka3641a742013-07-11 22:20:47 +03001050 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001051 memcpy(buf, ptr, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 buf[n] = '\0';
1053 c.imag = PyOS_string_to_double(buf, NULL, NULL);
1054 if (c.imag == -1.0 && PyErr_Occurred())
1055 break;
1056 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001057 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 break;
1059 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 case TYPE_BINARY_COMPLEX:
1062 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001063 const unsigned char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 Py_complex c;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001065 buf = (const unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001066 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 c.real = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001069 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 break;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001071 buf = (const unsigned char *) r_string(8, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001072 if (buf == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 c.imag = _PyFloat_Unpack8(buf, 1);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001075 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001078 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 break;
1080 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001083 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001084 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001085 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001086 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001087 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001088 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001089 PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001090 break;
1091 }
1092 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001093 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001094 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001095 ptr = r_string(n, p);
1096 if (ptr == NULL) {
1097 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001098 break;
1099 }
1100 memcpy(PyBytes_AS_STRING(v), ptr, n);
1101 retval = v;
1102 R_REF(retval);
1103 break;
1104 }
1105
1106 case TYPE_ASCII_INTERNED:
1107 is_interned = 1;
Victor Stinnerc0e77362017-09-12 16:09:44 -07001108 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001109 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001111 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001112 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001113 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001114 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 break;
1116 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001117 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001118
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001119 case TYPE_SHORT_ASCII_INTERNED:
1120 is_interned = 1;
Victor Stinnerc0e77362017-09-12 16:09:44 -07001121 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001122 case TYPE_SHORT_ASCII:
1123 n = r_byte(p);
1124 if (n == EOF) {
1125 PyErr_SetString(PyExc_EOFError,
1126 "EOF read where object expected");
1127 break;
1128 }
1129 _read_ascii:
1130 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001131 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001132 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001133 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001134 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001135 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001136 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001137 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001138 if (is_interned)
1139 PyUnicode_InternInPlace(&v);
1140 retval = v;
1141 R_REF(retval);
1142 break;
1143 }
1144
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001145 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001146 is_interned = 1;
Victor Stinnerc0e77362017-09-12 16:09:44 -07001147 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001148 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001150 const char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001153 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001154 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001155 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001156 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 break;
1158 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001159 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001160 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001161 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001162 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001163 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001165 else {
1166 v = PyUnicode_New(0, 0);
1167 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001168 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001169 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001170 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001171 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001173 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 break;
1175 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001176
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001177 case TYPE_SMALL_TUPLE:
1178 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001179 if (PyErr_Occurred())
1180 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001181 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 case TYPE_TUPLE:
1183 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001184 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001185 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001186 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 break;
1189 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001190 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001191 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001192 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001193 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 for (i = 0; i < n; i++) {
1197 v2 = r_object(p);
1198 if ( v2 == NULL ) {
1199 if (!PyErr_Occurred())
1200 PyErr_SetString(PyExc_TypeError,
1201 "NULL object in marshal data for tuple");
1202 Py_DECREF(v);
1203 v = NULL;
1204 break;
1205 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001206 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 }
1208 retval = v;
1209 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 case TYPE_LIST:
1212 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001213 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001214 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001215 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 break;
1218 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001219 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001220 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001221 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 for (i = 0; i < n; i++) {
1224 v2 = r_object(p);
1225 if ( v2 == NULL ) {
1226 if (!PyErr_Occurred())
1227 PyErr_SetString(PyExc_TypeError,
1228 "NULL object in marshal data for list");
1229 Py_DECREF(v);
1230 v = NULL;
1231 break;
1232 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001233 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 }
1235 retval = v;
1236 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 case TYPE_DICT:
1239 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001240 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001241 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 for (;;) {
1244 PyObject *key, *val;
1245 key = r_object(p);
1246 if (key == NULL)
1247 break;
1248 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001249 if (val == NULL) {
1250 Py_DECREF(key);
1251 break;
1252 }
1253 if (PyDict_SetItem(v, key, val) < 0) {
1254 Py_DECREF(key);
1255 Py_DECREF(val);
1256 break;
1257 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001259 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 }
1261 if (PyErr_Occurred()) {
1262 Py_DECREF(v);
1263 v = NULL;
1264 }
1265 retval = v;
1266 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 case TYPE_SET:
1269 case TYPE_FROZENSET:
1270 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001271 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001272 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001273 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 break;
1276 }
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001277
Victor Stinner1aa78932016-01-23 14:15:48 +01001278 if (n == 0 && type == TYPE_FROZENSET) {
1279 /* call frozenset() to get the empty frozenset singleton */
1280 v = PyObject_CallFunction((PyObject*)&PyFrozenSet_Type, NULL);
1281 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 break;
Victor Stinner1aa78932016-01-23 14:15:48 +01001283 R_REF(v);
1284 retval = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 }
Victor Stinner1aa78932016-01-23 14:15:48 +01001286 else {
1287 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1288 if (type == TYPE_SET) {
1289 R_REF(v);
1290 } else {
1291 /* must use delayed registration of frozensets because they must
1292 * be init with a refcount of 1
1293 */
1294 idx = r_ref_reserve(flag, p);
1295 if (idx < 0)
1296 Py_CLEAR(v); /* signal error */
1297 }
1298 if (v == NULL)
1299 break;
1300
1301 for (i = 0; i < n; i++) {
1302 v2 = r_object(p);
1303 if ( v2 == NULL ) {
1304 if (!PyErr_Occurred())
1305 PyErr_SetString(PyExc_TypeError,
1306 "NULL object in marshal data for set");
1307 Py_DECREF(v);
1308 v = NULL;
1309 break;
1310 }
1311 if (PySet_Add(v, v2) == -1) {
1312 Py_DECREF(v);
1313 Py_DECREF(v2);
1314 v = NULL;
1315 break;
1316 }
1317 Py_DECREF(v2);
1318 }
1319 if (type != TYPE_SET)
1320 v = r_ref_insert(v, idx, flag, p);
1321 retval = v;
1322 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 case TYPE_CODE:
1326 {
1327 int argcount;
1328 int kwonlyargcount;
1329 int nlocals;
1330 int stacksize;
1331 int flags;
1332 PyObject *code = NULL;
1333 PyObject *consts = NULL;
1334 PyObject *names = NULL;
1335 PyObject *varnames = NULL;
1336 PyObject *freevars = NULL;
1337 PyObject *cellvars = NULL;
1338 PyObject *filename = NULL;
1339 PyObject *name = NULL;
1340 int firstlineno;
1341 PyObject *lnotab = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001342
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001343 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001344 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001345 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 /* XXX ignore long->int overflows for now */
1350 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001351 if (PyErr_Occurred())
1352 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 kwonlyargcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001354 if (PyErr_Occurred())
1355 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 nlocals = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001357 if (PyErr_Occurred())
1358 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 stacksize = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001360 if (PyErr_Occurred())
1361 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 flags = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001363 if (PyErr_Occurred())
1364 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 code = r_object(p);
1366 if (code == NULL)
1367 goto code_error;
1368 consts = r_object(p);
1369 if (consts == NULL)
1370 goto code_error;
1371 names = r_object(p);
1372 if (names == NULL)
1373 goto code_error;
1374 varnames = r_object(p);
1375 if (varnames == NULL)
1376 goto code_error;
1377 freevars = r_object(p);
1378 if (freevars == NULL)
1379 goto code_error;
1380 cellvars = r_object(p);
1381 if (cellvars == NULL)
1382 goto code_error;
1383 filename = r_object(p);
1384 if (filename == NULL)
1385 goto code_error;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001386 if (PyUnicode_CheckExact(filename)) {
1387 if (p->current_filename != NULL) {
1388 if (!PyUnicode_Compare(filename, p->current_filename)) {
1389 Py_DECREF(filename);
1390 Py_INCREF(p->current_filename);
1391 filename = p->current_filename;
1392 }
1393 }
1394 else {
1395 p->current_filename = filename;
1396 }
1397 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 name = r_object(p);
1399 if (name == NULL)
1400 goto code_error;
1401 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001402 if (firstlineno == -1 && PyErr_Occurred())
1403 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 lnotab = r_object(p);
1405 if (lnotab == NULL)
1406 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 v = (PyObject *) PyCode_New(
1409 argcount, kwonlyargcount,
1410 nlocals, stacksize, flags,
1411 code, consts, names, varnames,
1412 freevars, cellvars, filename, name,
1413 firstlineno, lnotab);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001414 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 code_error:
1417 Py_XDECREF(code);
1418 Py_XDECREF(consts);
1419 Py_XDECREF(names);
1420 Py_XDECREF(varnames);
1421 Py_XDECREF(freevars);
1422 Py_XDECREF(cellvars);
1423 Py_XDECREF(filename);
1424 Py_XDECREF(name);
1425 Py_XDECREF(lnotab);
1426 }
1427 retval = v;
1428 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001429
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001430 case TYPE_REF:
1431 n = r_long(p);
1432 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001433 if (n == -1 && PyErr_Occurred())
1434 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001435 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001436 break;
1437 }
1438 v = PyList_GET_ITEM(p->refs, n);
1439 if (v == Py_None) {
1440 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001441 break;
1442 }
1443 Py_INCREF(v);
1444 retval = v;
1445 break;
1446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 default:
1448 /* Bogus data got written, which isn't ideal.
1449 This will let you keep working and recover. */
1450 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 break;
1452
1453 }
1454 p->depth--;
1455 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001456}
1457
Neal Norwitzd85c4522004-06-13 20:31:49 +00001458static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001459read_object(RFILE *p)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 PyObject *v;
1462 if (PyErr_Occurred()) {
1463 fprintf(stderr, "XXX readobject called with exception set\n");
1464 return NULL;
1465 }
1466 v = r_object(p);
1467 if (v == NULL && !PyErr_Occurred())
1468 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1469 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001470}
1471
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001472int
1473PyMarshal_ReadShortFromFile(FILE *fp)
1474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001476 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001478 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 rf.fp = fp;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001480 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001482 rf.buf = NULL;
1483 res = r_short(&rf);
1484 if (rf.buf != NULL)
1485 PyMem_FREE(rf.buf);
1486 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001487}
1488
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001489long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001490PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001493 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001495 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001496 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001498 rf.buf = NULL;
1499 res = r_long(&rf);
1500 if (rf.buf != NULL)
1501 PyMem_FREE(rf.buf);
1502 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001503}
1504
Steve Dowerf2f373f2015-02-21 08:44:05 -08001505/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001506static off_t
1507getfilesize(FILE *fp)
1508{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001509 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001510 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001512#if SIZEOF_OFF_T == 4
1513 else if (st.st_size >= INT_MAX)
1514 return (off_t)INT_MAX;
1515#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001517 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001518}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001519
Tim Peters691e0e92001-01-18 04:39:16 +00001520/* If we can get the size of the file up-front, and it's reasonably small,
1521 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1522 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001523 * CAUTION: since this may read the entire remainder of the file, don't
1524 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001525 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001526PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001527PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001528{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001529/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001530#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 off_t filesize;
1532 filesize = getfilesize(fp);
1533 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1534 char* pBuf = (char *)PyMem_MALLOC(filesize);
1535 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001536 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1537 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyMem_FREE(pBuf);
1539 return v;
1540 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 /* We don't have fstat, or we do but the file is larger than
1544 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1545 */
1546 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001547
Tim Peters691e0e92001-01-18 04:39:16 +00001548#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001549}
1550
Guido van Rossum79f25d91997-04-29 20:08:16 +00001551PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001552PyMarshal_ReadObjectFromFile(FILE *fp)
1553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 RFILE rf;
1555 PyObject *result;
1556 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001557 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001558 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 rf.depth = 0;
1560 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001561 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001562 rf.refs = PyList_New(0);
1563 if (rf.refs == NULL)
1564 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001566 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001567 if (rf.buf != NULL)
1568 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001570}
1571
1572PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001573PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001574{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 RFILE rf;
1576 PyObject *result;
1577 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001578 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001579 rf.current_filename = NULL;
Serhiy Storchakac6792272013-10-19 21:03:34 +03001580 rf.ptr = (char *)str;
1581 rf.end = (char *)str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001582 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001584 rf.refs = PyList_New(0);
1585 if (rf.refs == NULL)
1586 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001588 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001589 if (rf.buf != NULL)
1590 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001592}
1593
Guido van Rossum79f25d91997-04-29 20:08:16 +00001594PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001595PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001598
Serhiy Storchakace921c622015-02-11 15:53:31 +02001599 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1601 if (wf.str == NULL)
1602 return NULL;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +02001603 wf.ptr = wf.buf = PyBytes_AS_STRING((PyBytesObject *)wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 wf.end = wf.ptr + PyBytes_Size(wf.str);
1605 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001607 if (w_init_refs(&wf, version)) {
1608 Py_DECREF(wf.str);
1609 return NULL;
1610 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001612 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 if (wf.str != NULL) {
1614 char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
1615 if (wf.ptr - base > PY_SSIZE_T_MAX) {
1616 Py_DECREF(wf.str);
1617 PyErr_SetString(PyExc_OverflowError,
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001618 "too much marshal data for a bytes object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 return NULL;
1620 }
1621 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1622 return NULL;
1623 }
1624 if (wf.error != WFERR_OK) {
1625 Py_XDECREF(wf.str);
1626 if (wf.error == WFERR_NOMEMORY)
1627 PyErr_NoMemory();
1628 else
1629 PyErr_SetString(PyExc_ValueError,
1630 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1631 :"object too deeply nested to marshal");
1632 return NULL;
1633 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001634 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001635}
1636
Guido van Rossum64b45521991-06-07 13:58:22 +00001637/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001638
Guido van Rossum79f25d91997-04-29 20:08:16 +00001639static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001640marshal_dump(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 /* XXX Quick hack -- need to do this differently */
1643 PyObject *x;
1644 PyObject *f;
1645 int version = Py_MARSHAL_VERSION;
1646 PyObject *s;
1647 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001648 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
1651 return NULL;
1652 s = PyMarshal_WriteObjectToString(x, version);
1653 if (s == NULL)
1654 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001655 res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 Py_DECREF(s);
1657 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001658}
1659
R. David Murraydd226ea2009-05-13 12:27:21 +00001660PyDoc_STRVAR(dump_doc,
1661"dump(value, file[, version])\n\
1662\n\
1663Write the value on the open file. The value must be a supported type.\n\
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001664The file must be a writeable binary file.\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001665\n\
1666If the value has (or contains an object that has) an unsupported type, a\n\
Serhiy Storchaka225821c2015-12-18 13:05:04 +02001667ValueError exception is raised - but garbage data will also be written\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001668to the file. The object will not be properly read back by load()\n\
1669\n\
1670The version argument indicates the data format that dump should use.");
1671
Guido van Rossum79f25d91997-04-29 20:08:16 +00001672static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001673marshal_load(PyObject *self, PyObject *f)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001676 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001678
1679 /*
1680 * Make a call to the read method, but read zero bytes.
1681 * This is to ensure that the object passed in at least
1682 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001683 * This can be removed if we guarantee good error handling
1684 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001685 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001686 data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 if (data == NULL)
1688 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001689 if (!PyBytes_Check(data)) {
1690 PyErr_Format(PyExc_TypeError,
1691 "f.read() returned not bytes but %.100s",
1692 data->ob_type->tp_name);
1693 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 }
1695 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001696 rf.depth = 0;
1697 rf.fp = NULL;
1698 rf.readable = f;
Vinay Sajipaac0f752011-07-02 18:42:21 +01001699 rf.current_filename = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001700 rf.ptr = rf.end = NULL;
1701 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001702 if ((rf.refs = PyList_New(0)) != NULL) {
1703 result = read_object(&rf);
1704 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001705 if (rf.buf != NULL)
1706 PyMem_FREE(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001707 } else
1708 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001709 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 Py_DECREF(data);
1711 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001712}
1713
R. David Murraydd226ea2009-05-13 12:27:21 +00001714PyDoc_STRVAR(load_doc,
1715"load(file)\n\
1716\n\
1717Read one value from the open file and return it. If no valid value is\n\
Serhiy Storchaka225821c2015-12-18 13:05:04 +02001718read (e.g. because the data has a different Python version's\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001719incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001720The file must be a readable binary file.\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001721\n\
1722Note: If an object containing an unsupported type was marshalled with\n\
1723dump(), load() will substitute None for the unmarshallable type.");
1724
1725
Guido van Rossum79f25d91997-04-29 20:08:16 +00001726static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001727marshal_dumps(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 PyObject *x;
1730 int version = Py_MARSHAL_VERSION;
1731 if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
1732 return NULL;
1733 return PyMarshal_WriteObjectToString(x, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001734}
1735
R. David Murraydd226ea2009-05-13 12:27:21 +00001736PyDoc_STRVAR(dumps_doc,
1737"dumps(value[, version])\n\
1738\n\
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001739Return the bytes object that would be written to a file by dump(value, file).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001740The value must be a supported type. Raise a ValueError exception if\n\
1741value has (or contains an object that has) an unsupported type.\n\
1742\n\
1743The version argument indicates the data format that dumps should use.");
1744
1745
Guido van Rossum79f25d91997-04-29 20:08:16 +00001746static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001747marshal_loads(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 RFILE rf;
1750 Py_buffer p;
1751 char *s;
1752 Py_ssize_t n;
1753 PyObject* result;
Antoine Pitrou4a90ef02012-03-03 02:35:32 +01001754 if (!PyArg_ParseTuple(args, "y*:loads", &p))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 return NULL;
1756 s = p.buf;
1757 n = p.len;
1758 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001759 rf.readable = NULL;
Benjamin Peterson43b06862011-05-27 09:08:01 -05001760 rf.current_filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 rf.ptr = s;
1762 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001764 if ((rf.refs = PyList_New(0)) == NULL)
1765 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 result = read_object(&rf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 PyBuffer_Release(&p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001768 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001770}
1771
R. David Murraydd226ea2009-05-13 12:27:21 +00001772PyDoc_STRVAR(loads_doc,
Antoine Pitrou4a90ef02012-03-03 02:35:32 +01001773"loads(bytes)\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001774\n\
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001775Convert the bytes-like object to a value. If no valid value is found,\n\
1776raise EOFError, ValueError or TypeError. Extra bytes in the input are\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001777ignored.");
1778
Guido van Rossum79f25d91997-04-29 20:08:16 +00001779static PyMethodDef marshal_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 {"dump", marshal_dump, METH_VARARGS, dump_doc},
1781 {"load", marshal_load, METH_O, load_doc},
1782 {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
1783 {"loads", marshal_loads, METH_VARARGS, loads_doc},
1784 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001785};
1786
R. David Murraydd226ea2009-05-13 12:27:21 +00001787
1788PyDoc_STRVAR(module_doc,
1789"This module contains functions that can read and write Python values in\n\
1790a binary format. The format is specific to Python, but independent of\n\
1791machine architecture issues.\n\
1792\n\
1793Not all Python object types are supported; in general, only objects\n\
1794whose value is independent from a particular invocation of Python can be\n\
1795written and read by this module. The following types are supported:\n\
1796None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1797tuples, lists, sets, dictionaries, and code objects, where it\n\
1798should be understood that tuples, lists and dictionaries are only\n\
1799supported as long as the values contained therein are themselves\n\
1800supported; and recursive lists and dictionaries should not be written\n\
1801(they will cause infinite loops).\n\
1802\n\
1803Variables:\n\
1804\n\
1805version -- indicates the format that the module uses. Version 0 is the\n\
1806 historical format, version 1 shares interned strings and version 2\n\
1807 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001808 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001809\n\
1810Functions:\n\
1811\n\
1812dump() -- write value to a file\n\
1813load() -- read value from a file\n\
Serhiy Storchaka4652d822017-03-12 10:05:05 +02001814dumps() -- marshal value as a bytes object\n\
1815loads() -- read value from a bytes-like object");
R. David Murraydd226ea2009-05-13 12:27:21 +00001816
1817
1818
Brett Cannon429ef652008-06-27 00:35:35 +00001819static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 PyModuleDef_HEAD_INIT,
1821 "marshal",
1822 module_doc,
1823 0,
1824 marshal_methods,
1825 NULL,
1826 NULL,
1827 NULL,
1828 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001829};
1830
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001831PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001832PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyObject *mod = PyModule_Create(&marshalmodule);
1835 if (mod == NULL)
1836 return NULL;
1837 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
1838 return mod;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001839}