blob: 7c99c1ee13c0eec4a0cfe4f977e1691efc14a34f [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"
Victor Stinnerb6179932020-05-12 02:42:19 +020015#include "pycore_hashtable.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000016
Serhiy Storchaka0767ad42017-03-12 09:20:15 +020017/*[clinic input]
18module marshal
19[clinic start generated code]*/
20/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/
21
22#include "clinic/marshal.c.h"
23
Fred Drake6da0b912000-06-28 18:47:56 +000024/* High water mark to determine when the marshalled object is dangerously deep
25 * and risks coring the interpreter. When the object stack gets this deep,
26 * raise an exception instead of continuing.
Guido van Rossum63175a12007-08-29 20:39:13 +000027 * On Windows debug builds, reduce this value.
Steve Dower2a4a62b2018-06-04 13:25:00 -070028 *
29 * BUG: https://bugs.python.org/issue33720
30 * On Windows PGO builds, the r_object function overallocates its stack and
31 * can cause a stack overflow. We reduce the maximum depth for all Windows
32 * releases to protect against this.
33 * #if defined(MS_WINDOWS) && defined(_DEBUG)
Fred Drake6da0b912000-06-28 18:47:56 +000034 */
Steve Dower2a4a62b2018-06-04 13:25:00 -070035#if defined(MS_WINDOWS)
Steve Dowerf6c69e62014-11-01 15:15:16 -070036#define MAX_MARSHAL_STACK_DEPTH 1000
Guido van Rossum63175a12007-08-29 20:39:13 +000037#else
Guido van Rossumd59da4b2007-05-22 18:11:13 +000038#define MAX_MARSHAL_STACK_DEPTH 2000
Guido van Rossum63175a12007-08-29 20:39:13 +000039#endif
Fred Drake6da0b912000-06-28 18:47:56 +000040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041#define TYPE_NULL '0'
42#define TYPE_NONE 'N'
43#define TYPE_FALSE 'F'
44#define TYPE_TRUE 'T'
45#define TYPE_STOPITER 'S'
46#define TYPE_ELLIPSIS '.'
47#define TYPE_INT 'i'
Serhiy Storchaka00987f62017-11-15 17:41:05 +020048/* TYPE_INT64 is not generated anymore.
49 Supported for backward compatibility only. */
50#define TYPE_INT64 'I'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051#define TYPE_FLOAT 'f'
52#define TYPE_BINARY_FLOAT 'g'
53#define TYPE_COMPLEX 'x'
54#define TYPE_BINARY_COMPLEX 'y'
55#define TYPE_LONG 'l'
56#define TYPE_STRING 's'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070057#define TYPE_INTERNED 't'
58#define TYPE_REF 'r'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059#define TYPE_TUPLE '('
60#define TYPE_LIST '['
61#define TYPE_DICT '{'
62#define TYPE_CODE 'c'
63#define TYPE_UNICODE 'u'
64#define TYPE_UNKNOWN '?'
65#define TYPE_SET '<'
66#define TYPE_FROZENSET '>'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070067#define FLAG_REF '\x80' /* with a type, add obj to index */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000068
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020069#define TYPE_ASCII 'a'
70#define TYPE_ASCII_INTERNED 'A'
71#define TYPE_SMALL_TUPLE ')'
72#define TYPE_SHORT_ASCII 'z'
73#define TYPE_SHORT_ASCII_INTERNED 'Z'
74
Eric Smithb1a03cf2009-04-21 11:57:38 +000075#define WFERR_OK 0
76#define WFERR_UNMARSHALLABLE 1
77#define WFERR_NESTEDTOODEEP 2
78#define WFERR_NOMEMORY 3
79
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000080typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 FILE *fp;
82 int error; /* see WFERR_* values */
83 int depth;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyObject *str;
85 char *ptr;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +030086 const char *end;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020087 char *buf;
Serhiy Storchakace921c622015-02-11 15:53:31 +020088 _Py_hashtable_t *hashtable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 int version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000090} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000091
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020092#define w_byte(c, p) do { \
93 if ((p)->ptr != (p)->end || w_reserve((p), 1)) \
94 *(p)->ptr++ = (c); \
95 } while(0)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000096
97static void
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020098w_flush(WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000099{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200100 assert(p->fp != NULL);
101 fwrite(p->buf, 1, p->ptr - p->buf, p->fp);
102 p->ptr = p->buf;
103}
104
105static int
106w_reserve(WFILE *p, Py_ssize_t needed)
107{
108 Py_ssize_t pos, size, delta;
109 if (p->ptr == NULL)
110 return 0; /* An error already occurred */
111 if (p->fp != NULL) {
112 w_flush(p);
113 return needed <= p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 }
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200115 assert(p->str != NULL);
116 pos = p->ptr - p->buf;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300117 size = PyBytes_GET_SIZE(p->str);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200118 if (size > 16*1024*1024)
119 delta = (size >> 3); /* 12.5% overallocation */
120 else
121 delta = size + 1024;
122 delta = Py_MAX(delta, needed);
123 if (delta > PY_SSIZE_T_MAX - size) {
124 p->error = WFERR_NOMEMORY;
125 return 0;
126 }
127 size += delta;
128 if (_PyBytes_Resize(&p->str, size) != 0) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300129 p->end = p->ptr = p->buf = NULL;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200130 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 }
132 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200133 p->buf = PyBytes_AS_STRING(p->str);
134 p->ptr = p->buf + pos;
135 p->end = p->buf + size;
136 return 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000138}
139
140static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300141w_string(const void *s, Py_ssize_t n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200143 Py_ssize_t m;
144 if (!n || p->ptr == NULL)
145 return;
146 m = p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 if (p->fp != NULL) {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200148 if (n <= m) {
Christian Heimesf051e432016-09-13 20:22:02 +0200149 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200150 p->ptr += n;
151 }
152 else {
153 w_flush(p);
154 fwrite(s, 1, n, p->fp);
155 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 }
157 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200158 if (n <= m || w_reserve(p, n - m)) {
Christian Heimesf051e432016-09-13 20:22:02 +0200159 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200160 p->ptr += n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 }
162 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000163}
164
165static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000166w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 w_byte((char)( x & 0xff), p);
169 w_byte((char)((x>> 8) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170}
171
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000172static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000173w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 w_byte((char)( x & 0xff), p);
176 w_byte((char)((x>> 8) & 0xff), p);
177 w_byte((char)((x>>16) & 0xff), p);
178 w_byte((char)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000179}
180
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200181#define SIZE32_MAX 0x7FFFFFFF
182
183#if SIZEOF_SIZE_T > 4
184# define W_SIZE(n, p) do { \
185 if ((n) > SIZE32_MAX) { \
186 (p)->depth--; \
187 (p)->error = WFERR_UNMARSHALLABLE; \
188 return; \
189 } \
190 w_long((long)(n), p); \
191 } while(0)
192#else
193# define W_SIZE w_long
194#endif
195
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300196static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300197w_pstring(const void *s, Py_ssize_t n, WFILE *p)
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300198{
199 W_SIZE(n, p);
200 w_string(s, n, p);
201}
202
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200203static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300204w_short_pstring(const void *s, Py_ssize_t n, WFILE *p)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200205{
Antoine Pitroub30f2712013-10-12 23:14:47 +0200206 w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200207 w_string(s, n, p);
208}
209
Serhiy Storchaka95949422013-08-27 19:40:23 +0300210/* We assume that Python ints are stored internally in base some power of
Mark Dickinsonbd792642009-03-18 20:06:12 +0000211 2**15; for the sake of portability we'll always read and write them in base
212 exactly 2**15. */
213
214#define PyLong_MARSHAL_SHIFT 15
215#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
216#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
217#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
218#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
219#endif
220#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
221
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700222#define W_TYPE(t, p) do { \
223 w_byte((t) | flag, (p)); \
224} while(0)
225
Mark Dickinsonbd792642009-03-18 20:06:12 +0000226static void
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700227w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
Mark Dickinsonbd792642009-03-18 20:06:12 +0000228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 Py_ssize_t i, j, n, l;
230 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000231
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700232 W_TYPE(TYPE_LONG, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 if (Py_SIZE(ob) == 0) {
234 w_long((long)0, p);
235 return;
236 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 /* set l to number of base PyLong_MARSHAL_BASE digits */
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200239 n = Py_ABS(Py_SIZE(ob));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 l = (n-1) * PyLong_MARSHAL_RATIO;
241 d = ob->ob_digit[n-1];
242 assert(d != 0); /* a PyLong is always normalized */
243 do {
244 d >>= PyLong_MARSHAL_SHIFT;
245 l++;
246 } while (d != 0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200247 if (l > SIZE32_MAX) {
248 p->depth--;
249 p->error = WFERR_UNMARSHALLABLE;
250 return;
251 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 for (i=0; i < n-1; i++) {
255 d = ob->ob_digit[i];
256 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
257 w_short(d & PyLong_MARSHAL_MASK, p);
258 d >>= PyLong_MARSHAL_SHIFT;
259 }
260 assert (d == 0);
261 }
262 d = ob->ob_digit[n-1];
263 do {
264 w_short(d & PyLong_MARSHAL_MASK, p);
265 d >>= PyLong_MARSHAL_SHIFT;
266 } while (d != 0);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000267}
268
Serhiy Storchakac5734992018-07-24 10:55:47 +0300269static void
270w_float_bin(double v, WFILE *p)
271{
272 unsigned char buf[8];
273 if (_PyFloat_Pack8(v, buf, 1) < 0) {
274 p->error = WFERR_UNMARSHALLABLE;
275 return;
276 }
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300277 w_string(buf, 8, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300278}
279
280static void
281w_float_str(double v, WFILE *p)
282{
Serhiy Storchakac5734992018-07-24 10:55:47 +0300283 char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL);
284 if (!buf) {
285 p->error = WFERR_NOMEMORY;
286 return;
287 }
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300288 w_short_pstring(buf, strlen(buf), p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300289 PyMem_Free(buf);
290}
291
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700292static int
293w_ref(PyObject *v, char *flag, WFILE *p)
294{
Serhiy Storchakace921c622015-02-11 15:53:31 +0200295 _Py_hashtable_entry_t *entry;
296 int w;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700297
Serhiy Storchakace921c622015-02-11 15:53:31 +0200298 if (p->version < 3 || p->hashtable == NULL)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700299 return 0; /* not writing object references */
300
301 /* if it has only one reference, it definitely isn't shared */
302 if (Py_REFCNT(v) == 1)
303 return 0;
304
Victor Stinner285cf0a2016-03-21 22:00:58 +0100305 entry = _Py_HASHTABLE_GET_ENTRY(p->hashtable, v);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200306 if (entry != NULL) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700307 /* write the reference index to the stream */
Victor Stinnere8c6b2f2016-03-23 09:25:01 +0100308 _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, entry, w);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700309 /* we don't store "long" indices in the dict */
310 assert(0 <= w && w <= 0x7fffffff);
311 w_byte(TYPE_REF, p);
312 w_long(w, p);
313 return 1;
314 } else {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200315 size_t s = p->hashtable->entries;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700316 /* we don't support long indices */
317 if (s >= 0x7fffffff) {
318 PyErr_SetString(PyExc_ValueError, "too many objects");
319 goto err;
320 }
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200321 w = (int)s;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200322 Py_INCREF(v);
323 if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) {
324 Py_DECREF(v);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700325 goto err;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200326 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700327 *flag |= FLAG_REF;
328 return 0;
329 }
330err:
331 p->error = WFERR_UNMARSHALLABLE;
332 return 1;
333}
334
335static void
336w_complex_object(PyObject *v, char flag, WFILE *p);
337
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000338static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000339w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340{
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700341 char flag = '\0';
Fred Drake6da0b912000-06-28 18:47:56 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 p->depth++;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
346 p->error = WFERR_NESTEDTOODEEP;
347 }
348 else if (v == NULL) {
349 w_byte(TYPE_NULL, p);
350 }
351 else if (v == Py_None) {
352 w_byte(TYPE_NONE, p);
353 }
354 else if (v == PyExc_StopIteration) {
355 w_byte(TYPE_STOPITER, p);
356 }
357 else if (v == Py_Ellipsis) {
358 w_byte(TYPE_ELLIPSIS, p);
359 }
360 else if (v == Py_False) {
361 w_byte(TYPE_FALSE, p);
362 }
363 else if (v == Py_True) {
364 w_byte(TYPE_TRUE, p);
365 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700366 else if (!w_ref(v, &flag, p))
367 w_complex_object(v, flag, p);
368
369 p->depth--;
370}
371
372static void
373w_complex_object(PyObject *v, char flag, WFILE *p)
374{
375 Py_ssize_t i, n;
376
377 if (PyLong_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300378 int overflow;
379 long x = PyLong_AsLongAndOverflow(v, &overflow);
380 if (overflow) {
381 w_PyLong((PyLongObject *)v, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 }
383 else {
Guido van Rossumc1547d91996-12-10 15:39:04 +0000384#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
386 if (y && y != -1) {
Martin v. Löwis7e395722012-07-28 19:44:05 +0200387 /* Too large for TYPE_INT */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700388 w_PyLong((PyLongObject*)v, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 }
390 else
Guido van Rossumc1547d91996-12-10 15:39:04 +0000391#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700393 W_TYPE(TYPE_INT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 w_long(x, p);
395 }
396 }
397 }
398 else if (PyFloat_CheckExact(v)) {
399 if (p->version > 1) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700400 W_TYPE(TYPE_BINARY_FLOAT, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300401 w_float_bin(PyFloat_AS_DOUBLE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 }
403 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700404 W_TYPE(TYPE_FLOAT, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300405 w_float_str(PyFloat_AS_DOUBLE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 }
407 }
408 else if (PyComplex_CheckExact(v)) {
409 if (p->version > 1) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700410 W_TYPE(TYPE_BINARY_COMPLEX, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300411 w_float_bin(PyComplex_RealAsDouble(v), p);
412 w_float_bin(PyComplex_ImagAsDouble(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 }
414 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700415 W_TYPE(TYPE_COMPLEX, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300416 w_float_str(PyComplex_RealAsDouble(v), p);
417 w_float_str(PyComplex_ImagAsDouble(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 }
419 }
420 else if (PyBytes_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700421 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300422 w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
424 else if (PyUnicode_CheckExact(v)) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200425 if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
426 int is_short = PyUnicode_GET_LENGTH(v) < 256;
427 if (is_short) {
428 if (PyUnicode_CHECK_INTERNED(v))
429 W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
430 else
431 W_TYPE(TYPE_SHORT_ASCII, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300432 w_short_pstring(PyUnicode_1BYTE_DATA(v),
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200433 PyUnicode_GET_LENGTH(v), p);
434 }
435 else {
436 if (PyUnicode_CHECK_INTERNED(v))
437 W_TYPE(TYPE_ASCII_INTERNED, p);
438 else
439 W_TYPE(TYPE_ASCII, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300440 w_pstring(PyUnicode_1BYTE_DATA(v),
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200441 PyUnicode_GET_LENGTH(v), p);
442 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200444 else {
445 PyObject *utf8;
446 utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
447 if (utf8 == NULL) {
448 p->depth--;
449 p->error = WFERR_UNMARSHALLABLE;
450 return;
451 }
452 if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
453 W_TYPE(TYPE_INTERNED, p);
454 else
455 W_TYPE(TYPE_UNICODE, p);
456 w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
457 Py_DECREF(utf8);
458 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 }
460 else if (PyTuple_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300461 n = PyTuple_GET_SIZE(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200462 if (p->version >= 4 && n < 256) {
463 W_TYPE(TYPE_SMALL_TUPLE, p);
Victor Stinnerda062552013-11-16 00:13:29 +0100464 w_byte((unsigned char)n, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200465 }
466 else {
467 W_TYPE(TYPE_TUPLE, p);
468 W_SIZE(n, p);
469 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 for (i = 0; i < n; i++) {
471 w_object(PyTuple_GET_ITEM(v, i), p);
472 }
473 }
474 else if (PyList_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700475 W_TYPE(TYPE_LIST, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 n = PyList_GET_SIZE(v);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200477 W_SIZE(n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 for (i = 0; i < n; i++) {
479 w_object(PyList_GET_ITEM(v, i), p);
480 }
481 }
482 else if (PyDict_CheckExact(v)) {
483 Py_ssize_t pos;
484 PyObject *key, *value;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700485 W_TYPE(TYPE_DICT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 /* This one is NULL object terminated! */
487 pos = 0;
488 while (PyDict_Next(v, &pos, &key, &value)) {
489 w_object(key, p);
490 w_object(value, p);
491 }
492 w_object((PyObject *)NULL, p);
493 }
494 else if (PyAnySet_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300495 PyObject *value;
496 Py_ssize_t pos = 0;
497 Py_hash_t hash;
Raymond Hettingera422c342005-01-11 03:03:27 +0000498
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300499 if (PyFrozenSet_CheckExact(v))
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700500 W_TYPE(TYPE_FROZENSET, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300501 else
502 W_TYPE(TYPE_SET, p);
503 n = PySet_GET_SIZE(v);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200504 W_SIZE(n, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300505 while (_PySet_NextEntry(v, &pos, &value, &hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 w_object(value, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
508 }
509 else if (PyCode_Check(v)) {
510 PyCodeObject *co = (PyCodeObject *)v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700511 W_TYPE(TYPE_CODE, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 w_long(co->co_argcount, p);
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100513 w_long(co->co_posonlyargcount, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 w_long(co->co_kwonlyargcount, p);
515 w_long(co->co_nlocals, p);
516 w_long(co->co_stacksize, p);
517 w_long(co->co_flags, p);
518 w_object(co->co_code, p);
519 w_object(co->co_consts, p);
520 w_object(co->co_names, p);
521 w_object(co->co_varnames, p);
522 w_object(co->co_freevars, p);
523 w_object(co->co_cellvars, p);
524 w_object(co->co_filename, p);
525 w_object(co->co_name, p);
526 w_long(co->co_firstlineno, p);
527 w_object(co->co_lnotab, p);
528 }
529 else if (PyObject_CheckBuffer(v)) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +0200530 /* Write unknown bytes-like objects as a bytes object */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 Py_buffer view;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100532 if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 w_byte(TYPE_UNKNOWN, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100534 p->depth--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 p->error = WFERR_UNMARSHALLABLE;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100536 return;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700538 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300539 w_pstring(view.buf, view.len, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100540 PyBuffer_Release(&view);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 }
542 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700543 W_TYPE(TYPE_UNKNOWN, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 p->error = WFERR_UNMARSHALLABLE;
545 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000546}
547
Victor Stinner2d0a3d62020-05-13 02:50:18 +0200548static void
549w_decref_entry(void *key)
550{
551 PyObject *entry_key = (PyObject *)key;
552 Py_XDECREF(entry_key);
553}
554
Serhiy Storchakace921c622015-02-11 15:53:31 +0200555static int
556w_init_refs(WFILE *wf, int version)
557{
558 if (version >= 3) {
Victor Stinner2d0a3d62020-05-13 02:50:18 +0200559 wf->hashtable = _Py_hashtable_new_full(sizeof(int), 0,
560 _Py_hashtable_hash_ptr,
561 _Py_hashtable_compare_direct,
562 w_decref_entry, NULL, NULL);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200563 if (wf->hashtable == NULL) {
564 PyErr_NoMemory();
565 return -1;
566 }
567 }
568 return 0;
569}
570
Serhiy Storchakace921c622015-02-11 15:53:31 +0200571static void
572w_clear_refs(WFILE *wf)
573{
574 if (wf->hashtable != NULL) {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200575 _Py_hashtable_destroy(wf->hashtable);
576 }
577}
578
Serhiy Storchaka95949422013-08-27 19:40:23 +0300579/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000580void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000581PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000582{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200583 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200585 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200587 wf.ptr = wf.buf = buf;
588 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 wf.version = version;
591 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200592 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000593}
594
595void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000596PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000597{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200598 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200600 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200602 wf.ptr = wf.buf = buf;
603 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200606 if (w_init_refs(&wf, version))
607 return; /* caller mush check PyErr_Occurred() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200609 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200610 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000611}
612
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200613typedef struct {
614 FILE *fp;
615 int depth;
616 PyObject *readable; /* Stream-like object being read from */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300617 const char *ptr;
618 const char *end;
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200619 char *buf;
620 Py_ssize_t buf_size;
621 PyObject *refs; /* a list */
622} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000623
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200624static const char *
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200625r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000626{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200627 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100628
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200629 if (p->ptr != NULL) {
630 /* Fast path for loads() */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300631 const char *res = p->ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200632 Py_ssize_t left = p->end - p->ptr;
633 if (left < n) {
634 PyErr_SetString(PyExc_EOFError,
635 "marshal data too short");
636 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100637 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200638 p->ptr += n;
639 return res;
640 }
641 if (p->buf == NULL) {
642 p->buf = PyMem_MALLOC(n);
643 if (p->buf == NULL) {
644 PyErr_NoMemory();
645 return NULL;
646 }
647 p->buf_size = n;
648 }
649 else if (p->buf_size < n) {
Zackery Spytz4c49da02018-12-07 03:11:30 -0700650 char *tmp = PyMem_REALLOC(p->buf, n);
651 if (tmp == NULL) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200652 PyErr_NoMemory();
653 return NULL;
654 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700655 p->buf = tmp;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200656 p->buf_size = n;
657 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100658
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200659 if (!p->readable) {
660 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200661 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100662 }
663 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200664 _Py_IDENTIFIER(readinto);
665 PyObject *res, *mview;
666 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200667
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200668 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
669 return NULL;
670 mview = PyMemoryView_FromBuffer(&buf);
671 if (mview == NULL)
672 return NULL;
673
674 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
675 if (res != NULL) {
676 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
677 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100678 }
679 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200680 if (read != n) {
681 if (!PyErr_Occurred()) {
682 if (read > n)
683 PyErr_Format(PyExc_ValueError,
684 "read() returned too much data: "
685 "%zd bytes requested, %zd returned",
686 n, read);
687 else
688 PyErr_SetString(PyExc_EOFError,
689 "EOF read where not expected");
690 }
691 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100692 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200693 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100694}
695
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100696static int
697r_byte(RFILE *p)
698{
699 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100700
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200701 if (p->ptr != NULL) {
702 if (p->ptr < p->end)
703 c = (unsigned char) *p->ptr++;
704 return c;
705 }
706 if (!p->readable) {
707 assert(p->fp);
708 c = getc(p->fp);
709 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100710 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200711 const char *ptr = r_string(1, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200712 if (ptr != NULL)
Andy Lestere6be9b52020-02-11 20:28:35 -0600713 c = *(const unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100714 }
715 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000716}
717
718static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000719r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000720{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200721 short x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200722 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100723
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200724 buffer = (const unsigned char *) r_string(2, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200725 if (buffer != NULL) {
726 x = buffer[0];
727 x |= buffer[1] << 8;
728 /* Sign-extension, in case short greater than 16 bits */
729 x |= -(x & 0x8000);
730 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000732}
733
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000734static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000735r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000736{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200737 long x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200738 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100739
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200740 buffer = (const unsigned char *) r_string(4, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200741 if (buffer != NULL) {
742 x = buffer[0];
743 x |= (long)buffer[1] << 8;
744 x |= (long)buffer[2] << 16;
745 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000746#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200747 /* Sign extension for 64-bit machines */
748 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000749#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200750 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000752}
753
Serhiy Storchaka00987f62017-11-15 17:41:05 +0200754/* r_long64 deals with the TYPE_INT64 code. */
755static PyObject *
756r_long64(RFILE *p)
757{
758 const unsigned char *buffer = (const unsigned char *) r_string(8, p);
759 if (buffer == NULL) {
760 return NULL;
761 }
762 return _PyLong_FromByteArray(buffer, 8,
763 1 /* little endian */,
764 1 /* signed */);
765}
766
Guido van Rossum79f25d91997-04-29 20:08:16 +0000767static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000768r_PyLong(RFILE *p)
769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200771 long n, size, i;
772 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100776 if (PyErr_Occurred())
777 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 if (n == 0)
779 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200780 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 PyErr_SetString(PyExc_ValueError,
782 "bad marshal data (long size out of range)");
783 return NULL;
784 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000785
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200786 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
787 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 ob = _PyLong_New(size);
789 if (ob == NULL)
790 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100791
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100792 Py_SET_SIZE(ob, n > 0 ? size : -size);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 for (i = 0; i < size-1; i++) {
795 d = 0;
796 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
797 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100798 if (PyErr_Occurred()) {
799 Py_DECREF(ob);
800 return NULL;
801 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 if (md < 0 || md > PyLong_MARSHAL_BASE)
803 goto bad_digit;
804 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
805 }
806 ob->ob_digit[i] = d;
807 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 d = 0;
810 for (j=0; j < shorts_in_top_digit; j++) {
811 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100812 if (PyErr_Occurred()) {
813 Py_DECREF(ob);
814 return NULL;
815 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 if (md < 0 || md > PyLong_MARSHAL_BASE)
817 goto bad_digit;
818 /* topmost marshal digit should be nonzero */
819 if (md == 0 && j == shorts_in_top_digit - 1) {
820 Py_DECREF(ob);
821 PyErr_SetString(PyExc_ValueError,
822 "bad marshal data (unnormalized long data)");
823 return NULL;
824 }
825 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
826 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100827 if (PyErr_Occurred()) {
828 Py_DECREF(ob);
829 return NULL;
830 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 /* top digit should be nonzero, else the resulting PyLong won't be
832 normalized */
833 ob->ob_digit[size-1] = d;
834 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000835 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 Py_DECREF(ob);
837 PyErr_SetString(PyExc_ValueError,
838 "bad marshal data (digit out of range in long)");
839 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000840}
841
Serhiy Storchakac5734992018-07-24 10:55:47 +0300842static double
843r_float_bin(RFILE *p)
844{
845 const unsigned char *buf = (const unsigned char *) r_string(8, p);
846 if (buf == NULL)
847 return -1;
848 return _PyFloat_Unpack8(buf, 1);
849}
850
851/* Issue #33720: Disable inlining for reducing the C stack consumption
852 on PGO builds. */
853_Py_NO_INLINE static double
854r_float_str(RFILE *p)
855{
856 int n;
857 char buf[256];
858 const char *ptr;
859 n = r_byte(p);
860 if (n == EOF) {
861 PyErr_SetString(PyExc_EOFError,
862 "EOF read where object expected");
863 return -1;
864 }
865 ptr = r_string(n, p);
866 if (ptr == NULL) {
867 return -1;
868 }
869 memcpy(buf, ptr, n);
870 buf[n] = '\0';
871 return PyOS_string_to_double(buf, NULL, NULL);
872}
873
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700874/* allocate the reflist index for a new object. Return -1 on failure */
875static Py_ssize_t
876r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700877{
878 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200879 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700880 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700881 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700882 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700883 }
884 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700885 return -1;
886 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700887 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700888 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700889}
890
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700891/* insert the new object 'o' to the reflist at previously
892 * allocated index 'idx'.
893 * 'o' can be NULL, in which case nothing is done.
894 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
895 * if 'o' was non-NULL, and the function fails, 'o' is released and
896 * NULL returned. This simplifies error checking at the call site since
897 * a single test for NULL for the function result is enough.
898 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700899static PyObject *
900r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
901{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700902 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200903 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
904 Py_INCREF(o);
905 PyList_SET_ITEM(p->refs, idx, o);
906 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700907 }
908 return o;
909}
910
911/* combination of both above, used when an object can be
912 * created whenever it is seen in the file, as opposed to
913 * after having loaded its sub-objects.
914 */
915static PyObject *
916r_ref(PyObject *o, int flag, RFILE *p)
917{
Victor Stinner359fabc2013-10-31 17:09:01 +0100918 assert(flag & FLAG_REF);
919 if (o == NULL)
920 return NULL;
921 if (PyList_Append(p->refs, o) < 0) {
922 Py_DECREF(o); /* release the new object */
923 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700924 }
925 return o;
926}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000927
928static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000929r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 /* NULL is a valid return value, it does not necessarily means that
932 an exception is set. */
933 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500934 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700936 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200937 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200938 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000939
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700940 if (code == EOF) {
941 PyErr_SetString(PyExc_EOFError,
942 "EOF read where object expected");
943 return NULL;
944 }
945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
949 p->depth--;
950 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
951 return NULL;
952 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000953
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700954 flag = code & FLAG_REF;
955 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700956
957#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700958 if (flag) \
959 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700960} while (0)
961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 case TYPE_NONE:
968 Py_INCREF(Py_None);
969 retval = Py_None;
970 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 case TYPE_STOPITER:
973 Py_INCREF(PyExc_StopIteration);
974 retval = PyExc_StopIteration;
975 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 case TYPE_ELLIPSIS:
978 Py_INCREF(Py_Ellipsis);
979 retval = Py_Ellipsis;
980 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 case TYPE_FALSE:
983 Py_INCREF(Py_False);
984 retval = Py_False;
985 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 case TYPE_TRUE:
988 Py_INCREF(Py_True);
989 retval = Py_True;
990 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100993 n = r_long(p);
994 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700995 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000997
Serhiy Storchaka00987f62017-11-15 17:41:05 +0200998 case TYPE_INT64:
999 retval = r_long64(p);
1000 R_REF(retval);
1001 break;
1002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 case TYPE_LONG:
1004 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001005 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 case TYPE_FLOAT:
1009 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001010 double x = r_float_str(p);
1011 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001013 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001014 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 break;
1016 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 case TYPE_BINARY_FLOAT:
1019 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001020 double x = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001021 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001024 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 break;
1026 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 case TYPE_COMPLEX:
1029 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001031 c.real = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 if (c.real == -1.0 && PyErr_Occurred())
1033 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001034 c.imag = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 if (c.imag == -1.0 && PyErr_Occurred())
1036 break;
1037 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001038 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 break;
1040 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 case TYPE_BINARY_COMPLEX:
1043 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001045 c.real = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001046 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001048 c.imag = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001049 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001052 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 break;
1054 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001057 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001058 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001059 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001060 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001061 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001062 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001063 PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001064 break;
1065 }
1066 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001067 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001068 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001069 ptr = r_string(n, p);
1070 if (ptr == NULL) {
1071 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001072 break;
1073 }
1074 memcpy(PyBytes_AS_STRING(v), ptr, n);
1075 retval = v;
1076 R_REF(retval);
1077 break;
1078 }
1079
1080 case TYPE_ASCII_INTERNED:
1081 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001082 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001083 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001085 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001086 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001087 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001088 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 break;
1090 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001091 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001092
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001093 case TYPE_SHORT_ASCII_INTERNED:
1094 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001095 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001096 case TYPE_SHORT_ASCII:
1097 n = r_byte(p);
1098 if (n == EOF) {
1099 PyErr_SetString(PyExc_EOFError,
1100 "EOF read where object expected");
1101 break;
1102 }
1103 _read_ascii:
1104 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001105 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001106 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001107 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001108 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001109 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001110 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001111 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001112 if (is_interned)
1113 PyUnicode_InternInPlace(&v);
1114 retval = v;
1115 R_REF(retval);
1116 break;
1117 }
1118
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001119 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001120 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001121 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001122 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001124 const char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001127 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001128 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001129 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001130 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 break;
1132 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001133 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001134 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001135 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001136 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001137 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001139 else {
1140 v = PyUnicode_New(0, 0);
1141 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001142 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001143 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001144 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001145 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001147 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 break;
1149 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001150
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001151 case TYPE_SMALL_TUPLE:
1152 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001153 if (PyErr_Occurred())
1154 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001155 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 case TYPE_TUPLE:
1157 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001158 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001159 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001160 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 break;
1163 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001164 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001165 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001166 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001167 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 for (i = 0; i < n; i++) {
1171 v2 = r_object(p);
1172 if ( v2 == NULL ) {
1173 if (!PyErr_Occurred())
1174 PyErr_SetString(PyExc_TypeError,
1175 "NULL object in marshal data for tuple");
1176 Py_DECREF(v);
1177 v = NULL;
1178 break;
1179 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001180 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 }
1182 retval = v;
1183 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 case TYPE_LIST:
1186 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001187 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001188 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001189 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 break;
1192 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001193 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001194 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001195 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 for (i = 0; i < n; i++) {
1198 v2 = r_object(p);
1199 if ( v2 == NULL ) {
1200 if (!PyErr_Occurred())
1201 PyErr_SetString(PyExc_TypeError,
1202 "NULL object in marshal data for list");
1203 Py_DECREF(v);
1204 v = NULL;
1205 break;
1206 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001207 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 }
1209 retval = v;
1210 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 case TYPE_DICT:
1213 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001214 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001215 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 for (;;) {
1218 PyObject *key, *val;
1219 key = r_object(p);
1220 if (key == NULL)
1221 break;
1222 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001223 if (val == NULL) {
1224 Py_DECREF(key);
1225 break;
1226 }
1227 if (PyDict_SetItem(v, key, val) < 0) {
1228 Py_DECREF(key);
1229 Py_DECREF(val);
1230 break;
1231 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001233 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 }
1235 if (PyErr_Occurred()) {
1236 Py_DECREF(v);
1237 v = NULL;
1238 }
1239 retval = v;
1240 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 case TYPE_SET:
1243 case TYPE_FROZENSET:
1244 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001245 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001246 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001247 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 break;
1250 }
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001251
Victor Stinner1aa78932016-01-23 14:15:48 +01001252 if (n == 0 && type == TYPE_FROZENSET) {
1253 /* call frozenset() to get the empty frozenset singleton */
Victor Stinner4778eab2016-12-01 14:51:04 +01001254 v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type);
Victor Stinner1aa78932016-01-23 14:15:48 +01001255 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 break;
Victor Stinner1aa78932016-01-23 14:15:48 +01001257 R_REF(v);
1258 retval = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 }
Victor Stinner1aa78932016-01-23 14:15:48 +01001260 else {
1261 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1262 if (type == TYPE_SET) {
1263 R_REF(v);
1264 } else {
1265 /* must use delayed registration of frozensets because they must
1266 * be init with a refcount of 1
1267 */
1268 idx = r_ref_reserve(flag, p);
1269 if (idx < 0)
1270 Py_CLEAR(v); /* signal error */
1271 }
1272 if (v == NULL)
1273 break;
1274
1275 for (i = 0; i < n; i++) {
1276 v2 = r_object(p);
1277 if ( v2 == NULL ) {
1278 if (!PyErr_Occurred())
1279 PyErr_SetString(PyExc_TypeError,
1280 "NULL object in marshal data for set");
1281 Py_DECREF(v);
1282 v = NULL;
1283 break;
1284 }
1285 if (PySet_Add(v, v2) == -1) {
1286 Py_DECREF(v);
1287 Py_DECREF(v2);
1288 v = NULL;
1289 break;
1290 }
1291 Py_DECREF(v2);
1292 }
1293 if (type != TYPE_SET)
1294 v = r_ref_insert(v, idx, flag, p);
1295 retval = v;
1296 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 case TYPE_CODE:
1300 {
1301 int argcount;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001302 int posonlyargcount;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 int kwonlyargcount;
1304 int nlocals;
1305 int stacksize;
1306 int flags;
1307 PyObject *code = NULL;
1308 PyObject *consts = NULL;
1309 PyObject *names = NULL;
1310 PyObject *varnames = NULL;
1311 PyObject *freevars = NULL;
1312 PyObject *cellvars = NULL;
1313 PyObject *filename = NULL;
1314 PyObject *name = NULL;
1315 int firstlineno;
1316 PyObject *lnotab = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001317
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001318 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001319 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001320 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 /* XXX ignore long->int overflows for now */
1325 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001326 if (PyErr_Occurred())
1327 goto code_error;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001328 posonlyargcount = (int)r_long(p);
1329 if (PyErr_Occurred()) {
1330 goto code_error;
1331 }
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;
1365 name = r_object(p);
1366 if (name == NULL)
1367 goto code_error;
1368 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001369 if (firstlineno == -1 && PyErr_Occurred())
1370 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 lnotab = r_object(p);
1372 if (lnotab == NULL)
1373 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001374
Pablo Galindo4a2edc32019-07-01 11:35:05 +01001375 v = (PyObject *) PyCode_NewWithPosOnlyArgs(
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001376 argcount, posonlyargcount, kwonlyargcount,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 nlocals, stacksize, flags,
1378 code, consts, names, varnames,
1379 freevars, cellvars, filename, name,
1380 firstlineno, lnotab);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001381 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 code_error:
1384 Py_XDECREF(code);
1385 Py_XDECREF(consts);
1386 Py_XDECREF(names);
1387 Py_XDECREF(varnames);
1388 Py_XDECREF(freevars);
1389 Py_XDECREF(cellvars);
1390 Py_XDECREF(filename);
1391 Py_XDECREF(name);
1392 Py_XDECREF(lnotab);
1393 }
1394 retval = v;
1395 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001396
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001397 case TYPE_REF:
1398 n = r_long(p);
1399 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001400 if (n == -1 && PyErr_Occurred())
1401 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001402 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001403 break;
1404 }
1405 v = PyList_GET_ITEM(p->refs, n);
1406 if (v == Py_None) {
1407 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001408 break;
1409 }
1410 Py_INCREF(v);
1411 retval = v;
1412 break;
1413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 default:
1415 /* Bogus data got written, which isn't ideal.
1416 This will let you keep working and recover. */
1417 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 break;
1419
1420 }
1421 p->depth--;
1422 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001423}
1424
Neal Norwitzd85c4522004-06-13 20:31:49 +00001425static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001426read_object(RFILE *p)
1427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 PyObject *v;
1429 if (PyErr_Occurred()) {
1430 fprintf(stderr, "XXX readobject called with exception set\n");
1431 return NULL;
1432 }
1433 v = r_object(p);
1434 if (v == NULL && !PyErr_Occurred())
1435 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1436 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001437}
1438
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001439int
1440PyMarshal_ReadShortFromFile(FILE *fp)
1441{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001443 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001445 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 rf.fp = fp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001448 rf.buf = NULL;
1449 res = r_short(&rf);
1450 if (rf.buf != NULL)
1451 PyMem_FREE(rf.buf);
1452 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001453}
1454
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001455long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001456PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001459 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001461 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001463 rf.buf = NULL;
1464 res = r_long(&rf);
1465 if (rf.buf != NULL)
1466 PyMem_FREE(rf.buf);
1467 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001468}
1469
Steve Dowerf2f373f2015-02-21 08:44:05 -08001470/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001471static off_t
1472getfilesize(FILE *fp)
1473{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001474 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001475 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001477#if SIZEOF_OFF_T == 4
1478 else if (st.st_size >= INT_MAX)
1479 return (off_t)INT_MAX;
1480#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001482 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001483}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001484
Tim Peters691e0e92001-01-18 04:39:16 +00001485/* If we can get the size of the file up-front, and it's reasonably small,
1486 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1487 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001488 * CAUTION: since this may read the entire remainder of the file, don't
1489 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001490 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001491PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001492PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001493{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001494/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001495#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 off_t filesize;
1497 filesize = getfilesize(fp);
1498 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1499 char* pBuf = (char *)PyMem_MALLOC(filesize);
1500 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001501 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1502 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 PyMem_FREE(pBuf);
1504 return v;
1505 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 /* We don't have fstat, or we do but the file is larger than
1509 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1510 */
1511 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001512
Tim Peters691e0e92001-01-18 04:39:16 +00001513#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001514}
1515
Guido van Rossum79f25d91997-04-29 20:08:16 +00001516PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001517PyMarshal_ReadObjectFromFile(FILE *fp)
1518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 RFILE rf;
1520 PyObject *result;
1521 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001522 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 rf.depth = 0;
1524 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001525 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001526 rf.refs = PyList_New(0);
1527 if (rf.refs == NULL)
1528 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001530 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001531 if (rf.buf != NULL)
1532 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001534}
1535
1536PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001537PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 RFILE rf;
1540 PyObject *result;
1541 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001542 rf.readable = NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001543 rf.ptr = str;
1544 rf.end = str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001545 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001547 rf.refs = PyList_New(0);
1548 if (rf.refs == NULL)
1549 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001551 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001552 if (rf.buf != NULL)
1553 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001555}
1556
Guido van Rossum79f25d91997-04-29 20:08:16 +00001557PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001558PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001561
Serhiy Storchakace921c622015-02-11 15:53:31 +02001562 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1564 if (wf.str == NULL)
1565 return NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001566 wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
1567 wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001570 if (w_init_refs(&wf, version)) {
1571 Py_DECREF(wf.str);
1572 return NULL;
1573 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001575 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 if (wf.str != NULL) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001577 const char *base = PyBytes_AS_STRING(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1579 return NULL;
1580 }
1581 if (wf.error != WFERR_OK) {
1582 Py_XDECREF(wf.str);
1583 if (wf.error == WFERR_NOMEMORY)
1584 PyErr_NoMemory();
1585 else
1586 PyErr_SetString(PyExc_ValueError,
1587 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1588 :"object too deeply nested to marshal");
1589 return NULL;
1590 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001591 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001592}
1593
Guido van Rossum64b45521991-06-07 13:58:22 +00001594/* And an interface for Python programs... */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001595/*[clinic input]
1596marshal.dump
1597
1598 value: object
1599 Must be a supported type.
1600 file: object
1601 Must be a writeable binary file.
1602 version: int(c_default="Py_MARSHAL_VERSION") = version
1603 Indicates the data format that dump should use.
1604 /
1605
1606Write the value on the open file.
1607
1608If the value has (or contains an object that has) an unsupported type, a
1609ValueError exception is raised - but garbage data will also be written
1610to the file. The object will not be properly read back by load().
1611[clinic start generated code]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001612
Guido van Rossum79f25d91997-04-29 20:08:16 +00001613static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001614marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
1615 int version)
1616/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 /* XXX Quick hack -- need to do this differently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 PyObject *s;
1620 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001621 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001622
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001623 s = PyMarshal_WriteObjectToString(value, version);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (s == NULL)
1625 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001626 res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 Py_DECREF(s);
1628 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001629}
1630
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001631/*[clinic input]
1632marshal.load
1633
1634 file: object
1635 Must be readable binary file.
1636 /
1637
1638Read one value from the open file and return it.
1639
1640If no valid value is read (e.g. because the data has a different Python
1641version's incompatible marshal format), raise EOFError, ValueError or
1642TypeError.
1643
1644Note: If an object containing an unsupported type was marshalled with
1645dump(), load() will substitute None for the unmarshallable type.
1646[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001647
Guido van Rossum79f25d91997-04-29 20:08:16 +00001648static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001649marshal_load(PyObject *module, PyObject *file)
1650/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001653 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001655
1656 /*
1657 * Make a call to the read method, but read zero bytes.
1658 * This is to ensure that the object passed in at least
1659 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001660 * This can be removed if we guarantee good error handling
1661 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001662 */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001663 data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 if (data == NULL)
1665 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001666 if (!PyBytes_Check(data)) {
1667 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001668 "file.read() returned not bytes but %.100s",
Victor Stinnera102ed72020-02-07 02:24:48 +01001669 Py_TYPE(data)->tp_name);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001670 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 }
1672 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001673 rf.depth = 0;
1674 rf.fp = NULL;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001675 rf.readable = file;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001676 rf.ptr = rf.end = NULL;
1677 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001678 if ((rf.refs = PyList_New(0)) != NULL) {
1679 result = read_object(&rf);
1680 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001681 if (rf.buf != NULL)
1682 PyMem_FREE(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001683 } else
1684 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 Py_DECREF(data);
1687 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001688}
1689
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001690/*[clinic input]
1691marshal.dumps
R. David Murraydd226ea2009-05-13 12:27:21 +00001692
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001693 value: object
1694 Must be a supported type.
1695 version: int(c_default="Py_MARSHAL_VERSION") = version
1696 Indicates the data format that dumps should use.
1697 /
1698
1699Return the bytes object that would be written to a file by dump(value, file).
1700
1701Raise a ValueError exception if value has (or contains an object that has) an
1702unsupported type.
1703[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001704
Guido van Rossum79f25d91997-04-29 20:08:16 +00001705static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001706marshal_dumps_impl(PyObject *module, PyObject *value, int version)
1707/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001708{
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001709 return PyMarshal_WriteObjectToString(value, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001710}
1711
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001712/*[clinic input]
1713marshal.loads
R. David Murraydd226ea2009-05-13 12:27:21 +00001714
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001715 bytes: Py_buffer
1716 /
1717
1718Convert the bytes-like object to a value.
1719
1720If no valid value is found, raise EOFError, ValueError or TypeError. Extra
1721bytes in the input are ignored.
1722[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001723
Guido van Rossum79f25d91997-04-29 20:08:16 +00001724static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001725marshal_loads_impl(PyObject *module, Py_buffer *bytes)
1726/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 RFILE rf;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001729 char *s = bytes->buf;
1730 Py_ssize_t n = bytes->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 PyObject* result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001733 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 rf.ptr = s;
1735 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001737 if ((rf.refs = PyList_New(0)) == NULL)
1738 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001740 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001742}
1743
Guido van Rossum79f25d91997-04-29 20:08:16 +00001744static PyMethodDef marshal_methods[] = {
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001745 MARSHAL_DUMP_METHODDEF
1746 MARSHAL_LOAD_METHODDEF
1747 MARSHAL_DUMPS_METHODDEF
1748 MARSHAL_LOADS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001750};
1751
R. David Murraydd226ea2009-05-13 12:27:21 +00001752
1753PyDoc_STRVAR(module_doc,
1754"This module contains functions that can read and write Python values in\n\
1755a binary format. The format is specific to Python, but independent of\n\
1756machine architecture issues.\n\
1757\n\
1758Not all Python object types are supported; in general, only objects\n\
1759whose value is independent from a particular invocation of Python can be\n\
1760written and read by this module. The following types are supported:\n\
1761None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1762tuples, lists, sets, dictionaries, and code objects, where it\n\
1763should be understood that tuples, lists and dictionaries are only\n\
1764supported as long as the values contained therein are themselves\n\
1765supported; and recursive lists and dictionaries should not be written\n\
1766(they will cause infinite loops).\n\
1767\n\
1768Variables:\n\
1769\n\
1770version -- indicates the format that the module uses. Version 0 is the\n\
1771 historical format, version 1 shares interned strings and version 2\n\
1772 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001773 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001774\n\
1775Functions:\n\
1776\n\
1777dump() -- write value to a file\n\
1778load() -- read value from a file\n\
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001779dumps() -- marshal value as a bytes object\n\
1780loads() -- read value from a bytes-like object");
R. David Murraydd226ea2009-05-13 12:27:21 +00001781
1782
1783
Brett Cannon429ef652008-06-27 00:35:35 +00001784static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 PyModuleDef_HEAD_INIT,
1786 "marshal",
1787 module_doc,
1788 0,
1789 marshal_methods,
1790 NULL,
1791 NULL,
1792 NULL,
1793 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001794};
1795
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001796PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001797PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 PyObject *mod = PyModule_Create(&marshalmodule);
1800 if (mod == NULL)
1801 return NULL;
Brandt Bucher33b671e2019-11-19 16:59:32 -08001802 if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1803 Py_DECREF(mod);
1804 return NULL;
1805 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 return mod;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001807}