blob: 14f71346c86b167173c31c9b4c858068cfa7ab80 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001
2/* Write Python objects to files and read them back.
3 This is intended for writing and reading compiled Python code only;
4 a true persistent storage facility would be much harder, since
5 it would have to take circular links and sharing into account. */
6
Thomas Wouters695934a2006-03-01 23:49:13 +00007#define PY_SSIZE_T_CLEAN
8
Guido van Rossum79f25d91997-04-29 20:08:16 +00009#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000010#include "longintrepr.h"
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000011#include "code.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000012#include "marshal.h"
13
Mark Dickinsonefc82f72009-03-20 15:51:55 +000014#define ABS(x) ((x) < 0 ? -(x) : (x))
15
Fred Drake6da0b912000-06-28 18:47:56 +000016/* High water mark to determine when the marshalled object is dangerously deep
17 * and risks coring the interpreter. When the object stack gets this deep,
18 * raise an exception instead of continuing.
19 */
Neal Norwitzf6b0e4d2007-05-17 07:04:46 +000020#define MAX_MARSHAL_STACK_DEPTH 2000
Fred Drake6da0b912000-06-28 18:47:56 +000021
Michael W. Hudsondf888462005-06-03 14:41:55 +000022#define TYPE_NULL '0'
23#define TYPE_NONE 'N'
24#define TYPE_FALSE 'F'
25#define TYPE_TRUE 'T'
26#define TYPE_STOPITER 'S'
27#define TYPE_ELLIPSIS '.'
28#define TYPE_INT 'i'
29#define TYPE_INT64 'I'
30#define TYPE_FLOAT 'f'
31#define TYPE_BINARY_FLOAT 'g'
32#define TYPE_COMPLEX 'x'
33#define TYPE_BINARY_COMPLEX 'y'
34#define TYPE_LONG 'l'
35#define TYPE_STRING 's'
36#define TYPE_INTERNED 't'
37#define TYPE_STRINGREF 'R'
38#define TYPE_TUPLE '('
39#define TYPE_LIST '['
40#define TYPE_DICT '{'
41#define TYPE_CODE 'c'
42#define TYPE_UNICODE 'u'
43#define TYPE_UNKNOWN '?'
44#define TYPE_SET '<'
45#define TYPE_FROZENSET '>'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000046
Eric Smith15669272009-10-19 00:34:12 +000047#define WFERR_OK 0
48#define WFERR_UNMARSHALLABLE 1
49#define WFERR_NESTEDTOODEEP 2
50#define WFERR_NOMEMORY 3
51
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000052typedef struct {
53 FILE *fp;
Eric Smith15669272009-10-19 00:34:12 +000054 int error; /* see WFERR_* values */
Fred Drake6da0b912000-06-28 18:47:56 +000055 int depth;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000056 /* If fp == NULL, the following are valid: */
Guido van Rossum79f25d91997-04-29 20:08:16 +000057 PyObject *str;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000058 char *ptr;
59 char *end;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +000060 PyObject *strings; /* dict on marshal, list on unmarshal */
Michael W. Hudsondf888462005-06-03 14:41:55 +000061 int version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000062} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000063
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000064#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
65 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
66 else w_more(c, p)
67
68static void
Fredrik Lundh11534382000-07-23 18:24:06 +000069w_more(int c, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000070{
Martin v. Löwis18e16552006-02-15 17:27:45 +000071 Py_ssize_t size, newsize;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000072 if (p->str == NULL)
73 return; /* An error already occurred */
Gregory P. Smithdd96db62008-06-09 04:58:54 +000074 size = PyString_Size(p->str);
Andrew M. Kuchling6c029162008-05-11 13:33:56 +000075 newsize = size + size + 1024;
76 if (newsize > 32*1024*1024) {
Raymond Hettinger305480c2008-06-16 01:42:40 +000077 newsize = size + (size >> 3); /* 12.5% overallocation */
Andrew M. Kuchling6c029162008-05-11 13:33:56 +000078 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +000079 if (_PyString_Resize(&p->str, newsize) != 0) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000080 p->ptr = p->end = NULL;
81 }
82 else {
Gregory P. Smithdd96db62008-06-09 04:58:54 +000083 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
Guido van Rossum79f25d91997-04-29 20:08:16 +000084 p->end =
Gregory P. Smithdd96db62008-06-09 04:58:54 +000085 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
Tim Peters8315ea52000-07-23 19:28:35 +000086 *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000087 }
88}
89
90static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000091w_string(char *s, int n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000092{
93 if (p->fp != NULL) {
94 fwrite(s, 1, n, p->fp);
95 }
96 else {
97 while (--n >= 0) {
98 w_byte(*s, p);
99 s++;
100 }
101 }
102}
103
104static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000105w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000106{
Thomas Heller3e1c18a2002-07-30 11:40:57 +0000107 w_byte((char)( x & 0xff), p);
108 w_byte((char)((x>> 8) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000109}
110
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000112w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000113{
Thomas Heller37d5a152002-07-30 11:44:44 +0000114 w_byte((char)( x & 0xff), p);
115 w_byte((char)((x>> 8) & 0xff), p);
116 w_byte((char)((x>>16) & 0xff), p);
117 w_byte((char)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000118}
119
Guido van Rossumc1547d91996-12-10 15:39:04 +0000120#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000121static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000122w_long64(long x, WFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000123{
124 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000125 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000126}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000127#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000128
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000129/* We assume that Python longs are stored internally in base some power of
130 2**15; for the sake of portability we'll always read and write them in base
131 exactly 2**15. */
132
133#define PyLong_MARSHAL_SHIFT 15
134#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
135#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
136#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
137#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
138#endif
139#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
140
141static void
142w_PyLong(const PyLongObject *ob, WFILE *p)
143{
144 Py_ssize_t i, j, n, l;
145 digit d;
146
147 w_byte(TYPE_LONG, p);
148 if (Py_SIZE(ob) == 0) {
149 w_long((long)0, p);
150 return;
151 }
152
153 /* set l to number of base PyLong_MARSHAL_BASE digits */
154 n = ABS(Py_SIZE(ob));
155 l = (n-1) * PyLong_MARSHAL_RATIO;
156 d = ob->ob_digit[n-1];
157 assert(d != 0); /* a PyLong is always normalized */
158 do {
159 d >>= PyLong_MARSHAL_SHIFT;
160 l++;
161 } while (d != 0);
162 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
163
164 for (i=0; i < n-1; i++) {
165 d = ob->ob_digit[i];
166 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
167 w_short(d & PyLong_MARSHAL_MASK, p);
168 d >>= PyLong_MARSHAL_SHIFT;
169 }
170 assert (d == 0);
171 }
172 d = ob->ob_digit[n-1];
173 do {
174 w_short(d & PyLong_MARSHAL_MASK, p);
175 d >>= PyLong_MARSHAL_SHIFT;
176 } while (d != 0);
177}
178
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000179static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000180w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000181{
Martin v. Löwis18e16552006-02-15 17:27:45 +0000182 Py_ssize_t i, n;
Fred Drake6da0b912000-06-28 18:47:56 +0000183
184 p->depth++;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000185
Fred Drake6da0b912000-06-28 18:47:56 +0000186 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
Eric Smith15669272009-10-19 00:34:12 +0000187 p->error = WFERR_NESTEDTOODEEP;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000188 }
Fred Drake6da0b912000-06-28 18:47:56 +0000189 else if (v == NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000190 w_byte(TYPE_NULL, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000191 }
192 else if (v == Py_None) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000193 w_byte(TYPE_NONE, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000194 }
Tim Peters5ca576e2001-06-18 22:08:13 +0000195 else if (v == PyExc_StopIteration) {
196 w_byte(TYPE_STOPITER, p);
197 }
Guido van Rossum730806d1998-04-10 22:27:42 +0000198 else if (v == Py_Ellipsis) {
199 w_byte(TYPE_ELLIPSIS, p);
200 }
Guido van Rossum77f6a652002-04-03 22:41:51 +0000201 else if (v == Py_False) {
202 w_byte(TYPE_FALSE, p);
203 }
204 else if (v == Py_True) {
205 w_byte(TYPE_TRUE, p);
206 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000207 else if (PyInt_CheckExact(v)) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000208 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000209#if SIZEOF_LONG > 4
Tim Peters44714002001-04-10 05:02:52 +0000210 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000211 if (y && y != -1) {
212 w_byte(TYPE_INT64, p);
213 w_long64(x, p);
214 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000215 else
216#endif
217 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000218 w_byte(TYPE_INT, p);
219 w_long(x, p);
220 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000221 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000222 else if (PyLong_CheckExact(v)) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000223 PyLongObject *ob = (PyLongObject *)v;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000224 w_PyLong(ob, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000225 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000226 else if (PyFloat_CheckExact(v)) {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000227 if (p->version > 1) {
Brett Cannonc9371d42005-06-25 08:23:41 +0000228 unsigned char buf[8];
Michael W. Hudsondf888462005-06-03 14:41:55 +0000229 if (_PyFloat_Pack8(PyFloat_AsDouble(v),
230 buf, 1) < 0) {
Eric Smith15669272009-10-19 00:34:12 +0000231 p->error = WFERR_UNMARSHALLABLE;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000232 return;
233 }
234 w_byte(TYPE_BINARY_FLOAT, p);
Brett Cannonc9371d42005-06-25 08:23:41 +0000235 w_string((char*)buf, 8, p);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000236 }
237 else {
Eric Smith15669272009-10-19 00:34:12 +0000238 char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
239 'g', 17, 0, NULL);
240 if (!buf) {
241 p->error = WFERR_NOMEMORY;
242 return;
243 }
Martin v. Löwis67baee62006-02-16 14:37:48 +0000244 n = strlen(buf);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000245 w_byte(TYPE_FLOAT, p);
Martin v. Löwis67baee62006-02-16 14:37:48 +0000246 w_byte((int)n, p);
Martin v. Löwis725507b2006-03-07 12:08:51 +0000247 w_string(buf, (int)n, p);
Eric Smith15669272009-10-19 00:34:12 +0000248 PyMem_Free(buf);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000249 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000250 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000251#ifndef WITHOUT_COMPLEX
Raymond Hettinger12e94202007-11-07 01:13:09 +0000252 else if (PyComplex_CheckExact(v)) {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000253 if (p->version > 1) {
Brett Cannonc9371d42005-06-25 08:23:41 +0000254 unsigned char buf[8];
Michael W. Hudsondf888462005-06-03 14:41:55 +0000255 if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
256 buf, 1) < 0) {
Eric Smith15669272009-10-19 00:34:12 +0000257 p->error = WFERR_UNMARSHALLABLE;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000258 return;
259 }
260 w_byte(TYPE_BINARY_COMPLEX, p);
Brett Cannonc9371d42005-06-25 08:23:41 +0000261 w_string((char*)buf, 8, p);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000262 if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
263 buf, 1) < 0) {
Eric Smith15669272009-10-19 00:34:12 +0000264 p->error = WFERR_UNMARSHALLABLE;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000265 return;
266 }
Brett Cannonc9371d42005-06-25 08:23:41 +0000267 w_string((char*)buf, 8, p);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000268 }
269 else {
Eric Smith15669272009-10-19 00:34:12 +0000270 char *buf;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000271 w_byte(TYPE_COMPLEX, p);
Eric Smith15669272009-10-19 00:34:12 +0000272 buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
273 'g', 17, 0, NULL);
274 if (!buf) {
275 p->error = WFERR_NOMEMORY;
Neal Norwitzedb21682006-08-12 01:47:59 +0000276 return;
277 }
Martin v. Löwis725507b2006-03-07 12:08:51 +0000278 n = strlen(buf);
279 w_byte((int)n, p);
280 w_string(buf, (int)n, p);
Eric Smith15669272009-10-19 00:34:12 +0000281 PyMem_Free(buf);
282 buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
283 'g', 17, 0, NULL);
284 if (!buf) {
285 p->error = WFERR_NOMEMORY;
Neal Norwitzedb21682006-08-12 01:47:59 +0000286 return;
287 }
Martin v. Löwis725507b2006-03-07 12:08:51 +0000288 n = strlen(buf);
289 w_byte((int)n, p);
290 w_string(buf, (int)n, p);
Eric Smith15669272009-10-19 00:34:12 +0000291 PyMem_Free(buf);
Michael W. Hudsondf888462005-06-03 14:41:55 +0000292 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000293 }
294#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000295 else if (PyString_CheckExact(v)) {
296 if (p->strings && PyString_CHECK_INTERNED(v)) {
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000297 PyObject *o = PyDict_GetItem(p->strings, v);
298 if (o) {
299 long w = PyInt_AsLong(o);
300 w_byte(TYPE_STRINGREF, p);
301 w_long(w, p);
302 goto exit;
303 }
304 else {
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000305 int ok;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000306 o = PyInt_FromSsize_t(PyDict_Size(p->strings));
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000307 ok = o &&
308 PyDict_SetItem(p->strings, v, o) >= 0;
309 Py_XDECREF(o);
310 if (!ok) {
311 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000312 p->error = WFERR_UNMARSHALLABLE;
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000313 return;
314 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000315 w_byte(TYPE_INTERNED, p);
316 }
317 }
318 else {
319 w_byte(TYPE_STRING, p);
320 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000321 n = PyString_GET_SIZE(v);
Martin v. Löwis725507b2006-03-07 12:08:51 +0000322 if (n > INT_MAX) {
323 /* huge strings are not supported */
324 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000325 p->error = WFERR_UNMARSHALLABLE;
Martin v. Löwis725507b2006-03-07 12:08:51 +0000326 return;
327 }
Guido van Rossum3a205f71995-02-17 15:10:07 +0000328 w_long((long)n, p);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000329 w_string(PyString_AS_STRING(v), (int)n, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000330 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000331#ifdef Py_USING_UNICODE
Raymond Hettinger12e94202007-11-07 01:13:09 +0000332 else if (PyUnicode_CheckExact(v)) {
Guido van Rossumc279b532000-03-10 23:03:02 +0000333 PyObject *utf8;
334 utf8 = PyUnicode_AsUTF8String(v);
335 if (utf8 == NULL) {
Guido van Rossum98626cd2000-06-28 23:24:19 +0000336 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000337 p->error = WFERR_UNMARSHALLABLE;
Guido van Rossum98626cd2000-06-28 23:24:19 +0000338 return;
Guido van Rossumc279b532000-03-10 23:03:02 +0000339 }
340 w_byte(TYPE_UNICODE, p);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000341 n = PyString_GET_SIZE(utf8);
Martin v. Löwis725507b2006-03-07 12:08:51 +0000342 if (n > INT_MAX) {
343 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000344 p->error = WFERR_UNMARSHALLABLE;
Martin v. Löwis725507b2006-03-07 12:08:51 +0000345 return;
346 }
Guido van Rossumc279b532000-03-10 23:03:02 +0000347 w_long((long)n, p);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000348 w_string(PyString_AS_STRING(utf8), (int)n, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000349 Py_DECREF(utf8);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000350 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000351#endif
Raymond Hettinger12e94202007-11-07 01:13:09 +0000352 else if (PyTuple_CheckExact(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000353 w_byte(TYPE_TUPLE, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000354 n = PyTuple_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000355 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000356 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000357 w_object(PyTuple_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000358 }
359 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000360 else if (PyList_CheckExact(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000361 w_byte(TYPE_LIST, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000362 n = PyList_GET_SIZE(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000363 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000364 for (i = 0; i < n; i++) {
Guido van Rossumc279b532000-03-10 23:03:02 +0000365 w_object(PyList_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000366 }
367 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000368 else if (PyDict_CheckExact(v)) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000369 Py_ssize_t pos;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000370 PyObject *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000371 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000372 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000373 pos = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000374 while (PyDict_Next(v, &pos, &key, &value)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000375 w_object(key, p);
376 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000377 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000378 w_object((PyObject *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000379 }
Raymond Hettinger12e94202007-11-07 01:13:09 +0000380 else if (PyAnySet_CheckExact(v)) {
Raymond Hettingera422c342005-01-11 03:03:27 +0000381 PyObject *value, *it;
382
383 if (PyObject_TypeCheck(v, &PySet_Type))
384 w_byte(TYPE_SET, p);
385 else
386 w_byte(TYPE_FROZENSET, p);
387 n = PyObject_Size(v);
388 if (n == -1) {
389 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000390 p->error = WFERR_UNMARSHALLABLE;
Raymond Hettingera422c342005-01-11 03:03:27 +0000391 return;
392 }
393 w_long((long)n, p);
394 it = PyObject_GetIter(v);
395 if (it == NULL) {
396 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000397 p->error = WFERR_UNMARSHALLABLE;
Raymond Hettingera422c342005-01-11 03:03:27 +0000398 return;
399 }
400 while ((value = PyIter_Next(it)) != NULL) {
401 w_object(value, p);
402 Py_DECREF(value);
403 }
404 Py_DECREF(it);
405 if (PyErr_Occurred()) {
406 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000407 p->error = WFERR_UNMARSHALLABLE;
Raymond Hettingera422c342005-01-11 03:03:27 +0000408 return;
409 }
410 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000411 else if (PyCode_Check(v)) {
412 PyCodeObject *co = (PyCodeObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000413 w_byte(TYPE_CODE, p);
Neal Norwitz7fdcb412002-06-14 01:07:39 +0000414 w_long(co->co_argcount, p);
415 w_long(co->co_nlocals, p);
416 w_long(co->co_stacksize, p);
417 w_long(co->co_flags, p);
Guido van Rossumd076c731998-10-07 19:42:25 +0000418 w_object(co->co_code, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000419 w_object(co->co_consts, p);
420 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000421 w_object(co->co_varnames, p);
Jeremy Hylton64949cb2001-01-25 20:06:59 +0000422 w_object(co->co_freevars, p);
423 w_object(co->co_cellvars, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000424 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000425 w_object(co->co_name, p);
Neal Norwitz7fdcb412002-06-14 01:07:39 +0000426 w_long(co->co_firstlineno, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000427 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000428 }
Jeremy Hylton9f64caa2001-11-09 22:02:48 +0000429 else if (PyObject_CheckReadBuffer(v)) {
Guido van Rossumd076c731998-10-07 19:42:25 +0000430 /* Write unknown buffer-style objects as a string */
431 char *s;
Jeremy Hylton9f64caa2001-11-09 22:02:48 +0000432 PyBufferProcs *pb = v->ob_type->tp_as_buffer;
Guido van Rossumd076c731998-10-07 19:42:25 +0000433 w_byte(TYPE_STRING, p);
434 n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
Martin v. Löwis725507b2006-03-07 12:08:51 +0000435 if (n > INT_MAX) {
436 p->depth--;
Eric Smith15669272009-10-19 00:34:12 +0000437 p->error = WFERR_UNMARSHALLABLE;
Martin v. Löwis725507b2006-03-07 12:08:51 +0000438 return;
439 }
Guido van Rossumd076c731998-10-07 19:42:25 +0000440 w_long((long)n, p);
Martin v. Löwis725507b2006-03-07 12:08:51 +0000441 w_string(s, (int)n, p);
Guido van Rossumd076c731998-10-07 19:42:25 +0000442 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000443 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000444 w_byte(TYPE_UNKNOWN, p);
Eric Smith15669272009-10-19 00:34:12 +0000445 p->error = WFERR_UNMARSHALLABLE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000446 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000447 exit:
Guido van Rossum98626cd2000-06-28 23:24:19 +0000448 p->depth--;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000449}
450
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000451/* version currently has no effect for writing longs. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000452void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000453PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000454{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000455 WFILE wf;
456 wf.fp = fp;
Eric Smith15669272009-10-19 00:34:12 +0000457 wf.error = WFERR_OK;
Fred Drake6da0b912000-06-28 18:47:56 +0000458 wf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000459 wf.strings = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000460 wf.version = version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000461 w_long(x, &wf);
462}
463
464void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000465PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000466{
467 WFILE wf;
468 wf.fp = fp;
Eric Smith15669272009-10-19 00:34:12 +0000469 wf.error = WFERR_OK;
Guido van Rossum98626cd2000-06-28 23:24:19 +0000470 wf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000471 wf.strings = (version > 0) ? PyDict_New() : NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000472 wf.version = version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000473 w_object(x, &wf);
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000474 Py_XDECREF(wf.strings);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000475}
476
477typedef WFILE RFILE; /* Same struct with different invariants */
478
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000479#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
Guido van Rossum8d617a61995-03-09 12:12:11 +0000480
481#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000482
483static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000484r_string(char *s, int n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000485{
486 if (p->fp != NULL)
Martin v. Löwis18e16552006-02-15 17:27:45 +0000487 /* The result fits into int because it must be <=n. */
488 return (int)fread(s, 1, n, p->fp);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000489 if (p->end - p->ptr < n)
Martin v. Löwis18e16552006-02-15 17:27:45 +0000490 n = (int)(p->end - p->ptr);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000491 memcpy(s, p->ptr, n);
492 p->ptr += n;
493 return n;
494}
495
496static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000497r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000498{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000499 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000500 x = r_byte(p);
501 x |= r_byte(p) << 8;
Tim Peterse84b7402000-09-19 08:54:13 +0000502 /* Sign-extension, in case short greater than 16 bits */
503 x |= -(x & 0x8000);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000504 return x;
505}
506
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000507static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000508r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000509{
510 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000511 register FILE *fp = p->fp;
512 if (fp) {
513 x = getc(fp);
514 x |= (long)getc(fp) << 8;
515 x |= (long)getc(fp) << 16;
516 x |= (long)getc(fp) << 24;
517 }
518 else {
519 x = rs_byte(p);
520 x |= (long)rs_byte(p) << 8;
521 x |= (long)rs_byte(p) << 16;
522 x |= (long)rs_byte(p) << 24;
523 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000524#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000525 /* Sign extension for 64-bit machines */
Tim Peterse84b7402000-09-19 08:54:13 +0000526 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000527#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000528 return x;
529}
530
Tim Peters82112372001-08-29 02:28:42 +0000531/* r_long64 deals with the TYPE_INT64 code. On a machine with
532 sizeof(long) > 4, it returns a Python int object, else a Python long
533 object. Note that w_long64 writes out TYPE_INT if 32 bits is enough,
534 so there's no inefficiency here in returning a PyLong on 32-bit boxes
535 for everything written via TYPE_INT64 (i.e., if an int is written via
536 TYPE_INT64, it *needs* more than 32 bits).
537*/
538static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000539r_long64(RFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000540{
Tim Peters82112372001-08-29 02:28:42 +0000541 long lo4 = r_long(p);
542 long hi4 = r_long(p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000543#if SIZEOF_LONG > 4
Tim Peters82112372001-08-29 02:28:42 +0000544 long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
545 return PyInt_FromLong(x);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000546#else
Tim Peters82112372001-08-29 02:28:42 +0000547 unsigned char buf[8];
548 int one = 1;
549 int is_little_endian = (int)*(char*)&one;
550 if (is_little_endian) {
551 memcpy(buf, &lo4, 4);
552 memcpy(buf+4, &hi4, 4);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000553 }
Tim Peters82112372001-08-29 02:28:42 +0000554 else {
555 memcpy(buf, &hi4, 4);
556 memcpy(buf+4, &lo4, 4);
557 }
558 return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000559#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000560}
561
Guido van Rossum79f25d91997-04-29 20:08:16 +0000562static PyObject *
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000563r_PyLong(RFILE *p)
564{
565 PyLongObject *ob;
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000566 int size, i, j, md, shorts_in_top_digit;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000567 long n;
568 digit d;
569
570 n = r_long(p);
571 if (n == 0)
572 return (PyObject *)_PyLong_New(0);
573 if (n < -INT_MAX || n > INT_MAX) {
574 PyErr_SetString(PyExc_ValueError,
575 "bad marshal data (long size out of range)");
576 return NULL;
577 }
578
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000579 size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
580 shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000581 ob = _PyLong_New(size);
582 if (ob == NULL)
583 return NULL;
584 Py_SIZE(ob) = n > 0 ? size : -size;
585
586 for (i = 0; i < size-1; i++) {
587 d = 0;
588 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
589 md = r_short(p);
590 if (md < 0 || md > PyLong_MARSHAL_BASE)
591 goto bad_digit;
592 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
593 }
594 ob->ob_digit[i] = d;
595 }
596 d = 0;
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000597 for (j=0; j < shorts_in_top_digit; j++) {
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000598 md = r_short(p);
599 if (md < 0 || md > PyLong_MARSHAL_BASE)
600 goto bad_digit;
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000601 /* topmost marshal digit should be nonzero */
602 if (md == 0 && j == shorts_in_top_digit - 1) {
603 Py_DECREF(ob);
604 PyErr_SetString(PyExc_ValueError,
605 "bad marshal data (unnormalized long data)");
606 return NULL;
607 }
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000608 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
609 }
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000610 /* top digit should be nonzero, else the resulting PyLong won't be
611 normalized */
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000612 ob->ob_digit[size-1] = d;
613 return (PyObject *)ob;
614 bad_digit:
615 Py_DECREF(ob);
616 PyErr_SetString(PyExc_ValueError,
617 "bad marshal data (digit out of range in long)");
618 return NULL;
619}
620
621
622static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000623r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000624{
Armin Rigo01ab2792004-03-26 15:09:27 +0000625 /* NULL is a valid return value, it does not necessarily means that
626 an exception is set. */
Christian Heimes67ac0662008-01-30 11:46:00 +0000627 PyObject *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000628 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629 int type = r_byte(p);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000630 PyObject *retval;
631
632 p->depth++;
633
634 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
635 p->depth--;
636 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
637 return NULL;
638 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000639
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000640 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000641
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000642 case EOF:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000643 PyErr_SetString(PyExc_EOFError,
644 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000645 retval = NULL;
646 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000647
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000648 case TYPE_NULL:
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000649 retval = NULL;
650 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000651
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000652 case TYPE_NONE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000653 Py_INCREF(Py_None);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000654 retval = Py_None;
655 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000656
Tim Peters5ca576e2001-06-18 22:08:13 +0000657 case TYPE_STOPITER:
658 Py_INCREF(PyExc_StopIteration);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000659 retval = PyExc_StopIteration;
660 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000661
Guido van Rossume449af71996-10-11 16:25:41 +0000662 case TYPE_ELLIPSIS:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000663 Py_INCREF(Py_Ellipsis);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000664 retval = Py_Ellipsis;
665 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000666
Guido van Rossum77f6a652002-04-03 22:41:51 +0000667 case TYPE_FALSE:
668 Py_INCREF(Py_False);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000669 retval = Py_False;
670 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000671
672 case TYPE_TRUE:
673 Py_INCREF(Py_True);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000674 retval = Py_True;
675 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000676
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000677 case TYPE_INT:
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000678 retval = PyInt_FromLong(r_long(p));
679 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000680
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000681 case TYPE_INT64:
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000682 retval = r_long64(p);
683 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000684
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000685 case TYPE_LONG:
Mark Dickinsonefc82f72009-03-20 15:51:55 +0000686 retval = r_PyLong(p);
687 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000688
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000689 case TYPE_FLOAT:
690 {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000691 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000692 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000693 n = r_byte(p);
Armin Rigo01ab2792004-03-26 15:09:27 +0000694 if (n == EOF || r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000695 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000696 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000697 retval = NULL;
698 break;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000699 }
700 buf[n] = '\0';
Eric Smithb218d282009-10-27 19:42:57 +0000701 dx = PyOS_string_to_double(buf, NULL, NULL);
Mark Dickinson51ae4922009-10-31 12:47:47 +0000702 if (dx == -1.0 && PyErr_Occurred()) {
703 retval = NULL;
Eric Smithb218d282009-10-27 19:42:57 +0000704 break;
Mark Dickinson51ae4922009-10-31 12:47:47 +0000705 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000706 retval = PyFloat_FromDouble(dx);
707 break;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000708 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000709
Michael W. Hudsondf888462005-06-03 14:41:55 +0000710 case TYPE_BINARY_FLOAT:
711 {
Brett Cannonc9371d42005-06-25 08:23:41 +0000712 unsigned char buf[8];
Michael W. Hudsondf888462005-06-03 14:41:55 +0000713 double x;
Brett Cannonc9371d42005-06-25 08:23:41 +0000714 if (r_string((char*)buf, 8, p) != 8) {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000715 PyErr_SetString(PyExc_EOFError,
716 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000717 retval = NULL;
718 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000719 }
720 x = _PyFloat_Unpack8(buf, 1);
721 if (x == -1.0 && PyErr_Occurred()) {
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000722 retval = NULL;
723 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000724 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000725 retval = PyFloat_FromDouble(x);
726 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000727 }
728
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000729#ifndef WITHOUT_COMPLEX
730 case TYPE_COMPLEX:
731 {
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000732 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000733 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000734 n = r_byte(p);
Armin Rigo01ab2792004-03-26 15:09:27 +0000735 if (n == EOF || r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000736 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000737 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000738 retval = NULL;
739 break;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000740 }
741 buf[n] = '\0';
Eric Smithb218d282009-10-27 19:42:57 +0000742 c.real = PyOS_string_to_double(buf, NULL, NULL);
Mark Dickinson51ae4922009-10-31 12:47:47 +0000743 if (c.real == -1.0 && PyErr_Occurred()) {
744 retval = NULL;
Eric Smithb218d282009-10-27 19:42:57 +0000745 break;
Mark Dickinson51ae4922009-10-31 12:47:47 +0000746 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000747 n = r_byte(p);
Armin Rigo01ab2792004-03-26 15:09:27 +0000748 if (n == EOF || r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000749 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000750 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000751 retval = NULL;
752 break;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000753 }
754 buf[n] = '\0';
Eric Smithb218d282009-10-27 19:42:57 +0000755 c.imag = PyOS_string_to_double(buf, NULL, NULL);
Mark Dickinson51ae4922009-10-31 12:47:47 +0000756 if (c.imag == -1.0 && PyErr_Occurred()) {
757 retval = NULL;
Eric Smithb218d282009-10-27 19:42:57 +0000758 break;
Mark Dickinson51ae4922009-10-31 12:47:47 +0000759 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000760 retval = PyComplex_FromCComplex(c);
761 break;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000762 }
Michael W. Hudsondf888462005-06-03 14:41:55 +0000763
764 case TYPE_BINARY_COMPLEX:
765 {
Brett Cannonc9371d42005-06-25 08:23:41 +0000766 unsigned char buf[8];
Michael W. Hudsondf888462005-06-03 14:41:55 +0000767 Py_complex c;
Brett Cannonc9371d42005-06-25 08:23:41 +0000768 if (r_string((char*)buf, 8, p) != 8) {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000769 PyErr_SetString(PyExc_EOFError,
770 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000771 retval = NULL;
772 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000773 }
774 c.real = _PyFloat_Unpack8(buf, 1);
775 if (c.real == -1.0 && PyErr_Occurred()) {
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000776 retval = NULL;
777 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000778 }
Brett Cannonc9371d42005-06-25 08:23:41 +0000779 if (r_string((char*)buf, 8, p) != 8) {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000780 PyErr_SetString(PyExc_EOFError,
781 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000782 retval = NULL;
783 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000784 }
785 c.imag = _PyFloat_Unpack8(buf, 1);
786 if (c.imag == -1.0 && PyErr_Occurred()) {
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000787 retval = NULL;
788 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000789 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000790 retval = PyComplex_FromCComplex(c);
791 break;
Michael W. Hudsondf888462005-06-03 14:41:55 +0000792 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000793#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +0000794
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000795 case TYPE_INTERNED:
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000796 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000797 n = r_long(p);
Armin Rigo7ccbca92006-10-04 12:17:45 +0000798 if (n < 0 || n > INT_MAX) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000799 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000800 retval = NULL;
801 break;
Guido van Rossuma45cb451998-06-08 20:27:29 +0000802 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000803 v = PyString_FromStringAndSize((char *)NULL, n);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000804 if (v == NULL) {
805 retval = NULL;
806 break;
807 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000808 if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
Michael W. Hudson6d6917b2005-06-03 15:17:16 +0000809 Py_DECREF(v);
810 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000811 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000812 retval = NULL;
813 break;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000814 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000815 if (type == TYPE_INTERNED) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000816 PyString_InternInPlace(&v);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000817 if (PyList_Append(p->strings, v) < 0) {
818 retval = NULL;
819 break;
820 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000821 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000822 retval = v;
823 break;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000824
825 case TYPE_STRINGREF:
826 n = r_long(p);
Michael W. Hudsonf2ca5af2005-06-13 18:28:46 +0000827 if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000828 PyErr_SetString(PyExc_ValueError, "bad marshal data (string ref out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000829 retval = NULL;
830 break;
Michael W. Hudsonf2ca5af2005-06-13 18:28:46 +0000831 }
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000832 v = PyList_GET_ITEM(p->strings, n);
833 Py_INCREF(v);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000834 retval = v;
835 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000836
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000837#ifdef Py_USING_UNICODE
Guido van Rossumc279b532000-03-10 23:03:02 +0000838 case TYPE_UNICODE:
839 {
840 char *buffer;
841
842 n = r_long(p);
Armin Rigo7ccbca92006-10-04 12:17:45 +0000843 if (n < 0 || n > INT_MAX) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000844 PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000845 retval = NULL;
846 break;
Guido van Rossumc279b532000-03-10 23:03:02 +0000847 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000848 buffer = PyMem_NEW(char, n);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000849 if (buffer == NULL) {
850 retval = PyErr_NoMemory();
851 break;
852 }
Guido van Rossumc279b532000-03-10 23:03:02 +0000853 if (r_string(buffer, (int)n, p) != n) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000854 PyMem_DEL(buffer);
Guido van Rossumc279b532000-03-10 23:03:02 +0000855 PyErr_SetString(PyExc_EOFError,
856 "EOF read where object expected");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000857 retval = NULL;
858 break;
Guido van Rossumc279b532000-03-10 23:03:02 +0000859 }
860 v = PyUnicode_DecodeUTF8(buffer, n, NULL);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000861 PyMem_DEL(buffer);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000862 retval = v;
863 break;
Guido van Rossumc279b532000-03-10 23:03:02 +0000864 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000865#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +0000866
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000867 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000868 n = r_long(p);
Armin Rigo7ccbca92006-10-04 12:17:45 +0000869 if (n < 0 || n > INT_MAX) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000870 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000871 retval = NULL;
872 break;
Guido van Rossuma45cb451998-06-08 20:27:29 +0000873 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000874 v = PyTuple_New((int)n);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000875 if (v == NULL) {
876 retval = NULL;
877 break;
878 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000879 for (i = 0; i < n; i++) {
880 v2 = r_object(p);
881 if ( v2 == NULL ) {
Armin Rigo01ab2792004-03-26 15:09:27 +0000882 if (!PyErr_Occurred())
883 PyErr_SetString(PyExc_TypeError,
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000884 "NULL object in marshal data for tuple");
Guido van Rossum79f25d91997-04-29 20:08:16 +0000885 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000886 v = NULL;
887 break;
888 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000889 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000890 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000891 retval = v;
892 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000893
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000894 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000895 n = r_long(p);
Armin Rigo7ccbca92006-10-04 12:17:45 +0000896 if (n < 0 || n > INT_MAX) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000897 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000898 retval = NULL;
899 break;
Guido van Rossuma45cb451998-06-08 20:27:29 +0000900 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000901 v = PyList_New((int)n);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000902 if (v == NULL) {
903 retval = NULL;
904 break;
905 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000906 for (i = 0; i < n; i++) {
907 v2 = r_object(p);
908 if ( v2 == NULL ) {
Armin Rigo01ab2792004-03-26 15:09:27 +0000909 if (!PyErr_Occurred())
910 PyErr_SetString(PyExc_TypeError,
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000911 "NULL object in marshal data for list");
Guido van Rossum79f25d91997-04-29 20:08:16 +0000912 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000913 v = NULL;
914 break;
915 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000916 PyList_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000917 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000918 retval = v;
919 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000920
Guido van Rossum64b45521991-06-07 13:58:22 +0000921 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000922 v = PyDict_New();
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000923 if (v == NULL) {
924 retval = NULL;
925 break;
926 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000927 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000928 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000929 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000930 if (key == NULL)
Armin Rigo01ab2792004-03-26 15:09:27 +0000931 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000932 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000933 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000934 PyDict_SetItem(v, key, val);
935 Py_DECREF(key);
936 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000937 }
Armin Rigo01ab2792004-03-26 15:09:27 +0000938 if (PyErr_Occurred()) {
939 Py_DECREF(v);
940 v = NULL;
941 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000942 retval = v;
943 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000944
Raymond Hettingera422c342005-01-11 03:03:27 +0000945 case TYPE_SET:
946 case TYPE_FROZENSET:
947 n = r_long(p);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000948 if (n < 0 || n > INT_MAX) {
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000949 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000950 retval = NULL;
951 break;
Raymond Hettingera422c342005-01-11 03:03:27 +0000952 }
Raymond Hettinger52716c92008-01-28 21:34:30 +0000953 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000954 if (v == NULL) {
955 retval = NULL;
956 break;
957 }
Raymond Hettingera422c342005-01-11 03:03:27 +0000958 for (i = 0; i < n; i++) {
959 v2 = r_object(p);
960 if ( v2 == NULL ) {
961 if (!PyErr_Occurred())
962 PyErr_SetString(PyExc_TypeError,
Nick Coghlan8eba5ed2009-03-15 03:24:46 +0000963 "NULL object in marshal data for set");
Raymond Hettingera422c342005-01-11 03:03:27 +0000964 Py_DECREF(v);
965 v = NULL;
966 break;
967 }
Raymond Hettinger52716c92008-01-28 21:34:30 +0000968 if (PySet_Add(v, v2) == -1) {
969 Py_DECREF(v);
970 Py_DECREF(v2);
971 v = NULL;
972 break;
973 }
Neal Norwitzfb43d1e2008-02-01 07:22:59 +0000974 Py_DECREF(v2);
Raymond Hettingera422c342005-01-11 03:03:27 +0000975 }
Raymond Hettingerbf3d1d52008-01-28 21:51:25 +0000976 retval = v;
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000977 break;
Raymond Hettingera422c342005-01-11 03:03:27 +0000978
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000979 case TYPE_CODE:
Michael W. Hudson80199132001-08-30 14:50:20 +0000980 if (PyEval_GetRestricted()) {
981 PyErr_SetString(PyExc_RuntimeError,
982 "cannot unmarshal code objects in "
983 "restricted execution mode");
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000984 retval = NULL;
985 break;
Michael W. Hudson80199132001-08-30 14:50:20 +0000986 }
987 else {
Michael W. Hudsondf888462005-06-03 14:41:55 +0000988 int argcount;
989 int nlocals;
990 int stacksize;
991 int flags;
992 PyObject *code = NULL;
993 PyObject *consts = NULL;
994 PyObject *names = NULL;
995 PyObject *varnames = NULL;
996 PyObject *freevars = NULL;
997 PyObject *cellvars = NULL;
998 PyObject *filename = NULL;
999 PyObject *name = NULL;
1000 int firstlineno;
1001 PyObject *lnotab = NULL;
1002
1003 v = NULL;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001004
Armin Rigo7ccbca92006-10-04 12:17:45 +00001005 /* XXX ignore long->int overflows for now */
1006 argcount = (int)r_long(p);
1007 nlocals = (int)r_long(p);
1008 stacksize = (int)r_long(p);
1009 flags = (int)r_long(p);
Michael W. Hudsondf888462005-06-03 14:41:55 +00001010 code = r_object(p);
1011 if (code == NULL)
1012 goto code_error;
1013 consts = r_object(p);
1014 if (consts == NULL)
1015 goto code_error;
1016 names = r_object(p);
1017 if (names == NULL)
1018 goto code_error;
1019 varnames = r_object(p);
1020 if (varnames == NULL)
1021 goto code_error;
1022 freevars = r_object(p);
1023 if (freevars == NULL)
1024 goto code_error;
1025 cellvars = r_object(p);
1026 if (cellvars == NULL)
1027 goto code_error;
1028 filename = r_object(p);
1029 if (filename == NULL)
1030 goto code_error;
1031 name = r_object(p);
1032 if (name == NULL)
1033 goto code_error;
Armin Rigo7ccbca92006-10-04 12:17:45 +00001034 firstlineno = (int)r_long(p);
Michael W. Hudsondf888462005-06-03 14:41:55 +00001035 lnotab = r_object(p);
1036 if (lnotab == NULL)
1037 goto code_error;
1038
1039 v = (PyObject *) PyCode_New(
Tim Petersd9b9ac82001-01-28 00:27:39 +00001040 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +00001041 code, consts, names, varnames,
Tim Petersd9b9ac82001-01-28 00:27:39 +00001042 freevars, cellvars, filename, name,
1043 firstlineno, lnotab);
Michael W. Hudsondf888462005-06-03 14:41:55 +00001044
1045 code_error:
Guido van Rossum79f25d91997-04-29 20:08:16 +00001046 Py_XDECREF(code);
1047 Py_XDECREF(consts);
1048 Py_XDECREF(names);
1049 Py_XDECREF(varnames);
Jeremy Hylton64949cb2001-01-25 20:06:59 +00001050 Py_XDECREF(freevars);
1051 Py_XDECREF(cellvars);
Guido van Rossum79f25d91997-04-29 20:08:16 +00001052 Py_XDECREF(filename);
1053 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +00001054 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001055
1056 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001057 retval = v;
1058 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001059
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001060 default:
Guido van Rossumf2150601996-06-26 20:41:23 +00001061 /* Bogus data got written, which isn't ideal.
1062 This will let you keep working and recover. */
Nick Coghlan8eba5ed2009-03-15 03:24:46 +00001063 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001064 retval = NULL;
1065 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001066
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001067 }
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001068 p->depth--;
1069 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001070}
1071
Neal Norwitzd85c4522004-06-13 20:31:49 +00001072static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001073read_object(RFILE *p)
1074{
1075 PyObject *v;
1076 if (PyErr_Occurred()) {
1077 fprintf(stderr, "XXX readobject called with exception set\n");
1078 return NULL;
1079 }
1080 v = r_object(p);
1081 if (v == NULL && !PyErr_Occurred())
Nick Coghlan8eba5ed2009-03-15 03:24:46 +00001082 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
Armin Rigo01ab2792004-03-26 15:09:27 +00001083 return v;
1084}
1085
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001086int
1087PyMarshal_ReadShortFromFile(FILE *fp)
1088{
1089 RFILE rf;
Thomas Wouters7f401ef2006-03-01 22:30:47 +00001090 assert(fp);
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001091 rf.fp = fp;
Thomas Wouters7464b432006-03-01 22:34:09 +00001092 rf.strings = NULL;
1093 rf.end = rf.ptr = NULL;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001094 return r_short(&rf);
1095}
1096
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001097long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001098PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001099{
1100 RFILE rf;
1101 rf.fp = fp;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001102 rf.strings = NULL;
Neal Norwitz15f26612007-10-12 03:05:19 +00001103 rf.ptr = rf.end = NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001104 return r_long(&rf);
1105}
1106
Tim Peters691e0e92001-01-18 04:39:16 +00001107#ifdef HAVE_FSTAT
1108/* Return size of file in bytes; < 0 if unknown. */
1109static off_t
1110getfilesize(FILE *fp)
1111{
1112 struct stat st;
1113 if (fstat(fileno(fp), &st) != 0)
1114 return -1;
1115 else
1116 return st.st_size;
1117}
1118#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +00001119
Tim Peters691e0e92001-01-18 04:39:16 +00001120/* If we can get the size of the file up-front, and it's reasonably small,
1121 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1122 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001123 * CAUTION: since this may read the entire remainder of the file, don't
1124 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001125 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001126PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001127PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001128{
Antoine Pitrou18e63fb2010-04-21 22:53:29 +00001129/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001130#define REASONABLE_FILE_LIMIT (1L << 18)
Tim Peters691e0e92001-01-18 04:39:16 +00001131#ifdef HAVE_FSTAT
1132 off_t filesize;
Tim Peters691e0e92001-01-18 04:39:16 +00001133 filesize = getfilesize(fp);
Antoine Pitrou18e63fb2010-04-21 22:53:29 +00001134 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1135 char* pBuf = (char *)PyMem_MALLOC(filesize);
Tim Peters691e0e92001-01-18 04:39:16 +00001136 if (pBuf != NULL) {
1137 PyObject* v;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001138 size_t n;
1139 /* filesize must fit into an int, because it
1140 is smaller than REASONABLE_FILE_LIMIT */
1141 n = fread(pBuf, 1, (int)filesize, fp);
Tim Peters691e0e92001-01-18 04:39:16 +00001142 v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrou18e63fb2010-04-21 22:53:29 +00001143 PyMem_FREE(pBuf);
Tim Peters691e0e92001-01-18 04:39:16 +00001144 return v;
1145 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001146
Tim Peters691e0e92001-01-18 04:39:16 +00001147 }
1148#endif
Tim Petersd9b9ac82001-01-28 00:27:39 +00001149 /* We don't have fstat, or we do but the file is larger than
1150 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1151 */
1152 return PyMarshal_ReadObjectFromFile(fp);
1153
Tim Peters691e0e92001-01-18 04:39:16 +00001154#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001155}
1156
Guido van Rossum79f25d91997-04-29 20:08:16 +00001157PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001158PyMarshal_ReadObjectFromFile(FILE *fp)
1159{
1160 RFILE rf;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001161 PyObject *result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001162 rf.fp = fp;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001163 rf.strings = PyList_New(0);
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001164 rf.depth = 0;
Neal Norwitz15f26612007-10-12 03:05:19 +00001165 rf.ptr = rf.end = NULL;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001166 result = r_object(&rf);
1167 Py_DECREF(rf.strings);
1168 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001169}
1170
1171PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +00001172PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001173{
1174 RFILE rf;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001175 PyObject *result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001176 rf.fp = NULL;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001177 rf.ptr = str;
1178 rf.end = str + len;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001179 rf.strings = PyList_New(0);
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001180 rf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001181 result = r_object(&rf);
1182 Py_DECREF(rf.strings);
1183 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001184}
1185
Eric Smith15669272009-10-19 00:34:12 +00001186static void
1187set_error(int error)
1188{
1189 switch (error) {
1190 case WFERR_NOMEMORY:
1191 PyErr_NoMemory();
1192 break;
1193 case WFERR_UNMARSHALLABLE:
1194 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
1195 break;
1196 case WFERR_NESTEDTOODEEP:
1197 default:
1198 PyErr_SetString(PyExc_ValueError,
1199 "object too deeply nested to marshal");
1200 break;
1201 }
1202}
1203
Guido van Rossum79f25d91997-04-29 20:08:16 +00001204PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001205PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001206{
1207 WFILE wf;
1208 wf.fp = NULL;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001209 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001210 if (wf.str == NULL)
1211 return NULL;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001212 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
1213 wf.end = wf.ptr + PyString_Size(wf.str);
Eric Smith15669272009-10-19 00:34:12 +00001214 wf.error = WFERR_OK;
Fred Drake6da0b912000-06-28 18:47:56 +00001215 wf.depth = 0;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001216 wf.version = version;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001217 wf.strings = (version > 0) ? PyDict_New() : NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001218 w_object(x, &wf);
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001219 Py_XDECREF(wf.strings);
Armin Rigo7ccbca92006-10-04 12:17:45 +00001220 if (wf.str != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001221 char *base = PyString_AS_STRING((PyStringObject *)wf.str);
Armin Rigo7ccbca92006-10-04 12:17:45 +00001222 if (wf.ptr - base > PY_SSIZE_T_MAX) {
1223 Py_DECREF(wf.str);
1224 PyErr_SetString(PyExc_OverflowError,
1225 "too much marshall data for a string");
1226 return NULL;
1227 }
Benjamin Petersonbea424a2010-04-03 00:57:33 +00001228 if (_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)))
1229 return NULL;
Armin Rigo7ccbca92006-10-04 12:17:45 +00001230 }
Eric Smith15669272009-10-19 00:34:12 +00001231 if (wf.error != WFERR_OK) {
Guido van Rossum79f25d91997-04-29 20:08:16 +00001232 Py_XDECREF(wf.str);
Eric Smith15669272009-10-19 00:34:12 +00001233 set_error(wf.error);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001234 return NULL;
1235 }
1236 return wf.str;
1237}
1238
Guido van Rossum64b45521991-06-07 13:58:22 +00001239/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001240
Guido van Rossum79f25d91997-04-29 20:08:16 +00001241static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001242marshal_dump(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001243{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001244 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +00001245 PyObject *x;
1246 PyObject *f;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001247 int version = Py_MARSHAL_VERSION;
1248 if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001249 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +00001250 if (!PyFile_Check(f)) {
1251 PyErr_SetString(PyExc_TypeError,
1252 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001253 return NULL;
1254 }
Guido van Rossum79f25d91997-04-29 20:08:16 +00001255 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001256 wf.str = NULL;
1257 wf.ptr = wf.end = NULL;
Eric Smith15669272009-10-19 00:34:12 +00001258 wf.error = WFERR_OK;
Fred Drake6da0b912000-06-28 18:47:56 +00001259 wf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001260 wf.strings = (version > 0) ? PyDict_New() : 0;
Neal Norwitzef785292005-11-16 05:04:51 +00001261 wf.version = version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001262 w_object(x, &wf);
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001263 Py_XDECREF(wf.strings);
Eric Smith15669272009-10-19 00:34:12 +00001264 if (wf.error != WFERR_OK) {
1265 set_error(wf.error);
Guido van Rossumf2150601996-06-26 20:41:23 +00001266 return NULL;
1267 }
Guido van Rossum79f25d91997-04-29 20:08:16 +00001268 Py_INCREF(Py_None);
1269 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001270}
1271
R. David Murraya3ec6972009-05-13 00:30:29 +00001272PyDoc_STRVAR(dump_doc,
1273"dump(value, file[, version])\n\
1274\n\
1275Write the value on the open file. The value must be a supported type.\n\
1276The file must be an open file object such as sys.stdout or returned by\n\
1277open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
1278\n\
1279If the value has (or contains an object that has) an unsupported type, a\n\
1280ValueError exception is raised but garbage data will also be written\n\
1281to the file. The object will not be properly read back by load()\n\
1282\n\
1283New in version 2.4: The version argument indicates the data format that\n\
1284dump should use.");
1285
Guido van Rossum79f25d91997-04-29 20:08:16 +00001286static PyObject *
Georg Brandlbf92f462006-05-29 21:58:42 +00001287marshal_load(PyObject *self, PyObject *f)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001288{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001289 RFILE rf;
Georg Brandlbf92f462006-05-29 21:58:42 +00001290 PyObject *result;
Guido van Rossum79f25d91997-04-29 20:08:16 +00001291 if (!PyFile_Check(f)) {
1292 PyErr_SetString(PyExc_TypeError,
1293 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001294 return NULL;
1295 }
Guido van Rossum79f25d91997-04-29 20:08:16 +00001296 rf.fp = PyFile_AsFile(f);
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001297 rf.strings = PyList_New(0);
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001298 rf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001299 result = read_object(&rf);
1300 Py_DECREF(rf.strings);
1301 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001302}
1303
R. David Murraya3ec6972009-05-13 00:30:29 +00001304PyDoc_STRVAR(load_doc,
1305"load(file)\n\
1306\n\
1307Read one value from the open file and return it. If no valid value is\n\
1308read (e.g. because the data has a different Python versions\n\
1309incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
1310The file must be an open file object opened in binary mode ('rb' or\n\
1311'r+b').\n\
1312\n\
1313Note: If an object containing an unsupported type was marshalled with\n\
1314dump(), load() will substitute None for the unmarshallable type.");
1315
1316
Guido van Rossum79f25d91997-04-29 20:08:16 +00001317static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001318marshal_dumps(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001319{
Guido van Rossum79f25d91997-04-29 20:08:16 +00001320 PyObject *x;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001321 int version = Py_MARSHAL_VERSION;
Armin Rigo2ccea172004-12-20 12:25:57 +00001322 if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001323 return NULL;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001324 return PyMarshal_WriteObjectToString(x, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001325}
1326
R. David Murraya3ec6972009-05-13 00:30:29 +00001327PyDoc_STRVAR(dumps_doc,
1328"dumps(value[, version])\n\
1329\n\
1330Return the string that would be written to a file by dump(value, file).\n\
1331The value must be a supported type. Raise a ValueError exception if\n\
1332value has (or contains an object that has) an unsupported type.\n\
1333\n\
1334New in version 2.4: The version argument indicates the data format that\n\
R. David Murray525cffc2009-05-13 13:07:14 +00001335dumps should use.");
R. David Murraya3ec6972009-05-13 00:30:29 +00001336
1337
Guido van Rossum79f25d91997-04-29 20:08:16 +00001338static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001339marshal_loads(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001340{
1341 RFILE rf;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001342 char *s;
Thomas Wouters695934a2006-03-01 23:49:13 +00001343 Py_ssize_t n;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001344 PyObject* result;
Michael W. Hudson01fca112005-06-13 17:50:18 +00001345 if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001346 return NULL;
1347 rf.fp = NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001348 rf.ptr = s;
1349 rf.end = s + n;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001350 rf.strings = PyList_New(0);
Neal Norwitzb1a9b372007-05-16 20:05:11 +00001351 rf.depth = 0;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001352 result = read_object(&rf);
1353 Py_DECREF(rf.strings);
1354 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001355}
1356
R. David Murraya3ec6972009-05-13 00:30:29 +00001357PyDoc_STRVAR(loads_doc,
1358"loads(string)\n\
1359\n\
1360Convert the string to a value. If no valid value is found, raise\n\
1361EOFError, ValueError or TypeError. Extra characters in the string are\n\
1362ignored.");
1363
Guido van Rossum79f25d91997-04-29 20:08:16 +00001364static PyMethodDef marshal_methods[] = {
R. David Murraya3ec6972009-05-13 00:30:29 +00001365 {"dump", marshal_dump, METH_VARARGS, dump_doc},
1366 {"load", marshal_load, METH_O, load_doc},
1367 {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
1368 {"loads", marshal_loads, METH_VARARGS, loads_doc},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001369 {NULL, NULL} /* sentinel */
1370};
1371
R. David Murraya3ec6972009-05-13 00:30:29 +00001372PyDoc_STRVAR(marshal_doc,
1373"This module contains functions that can read and write Python values in\n\
1374a binary format. The format is specific to Python, but independent of\n\
1375machine architecture issues.\n\
1376\n\
1377Not all Python object types are supported; in general, only objects\n\
1378whose value is independent from a particular invocation of Python can be\n\
1379written and read by this module. The following types are supported:\n\
1380None, integers, long integers, floating point numbers, strings, Unicode\n\
1381objects, tuples, lists, sets, dictionaries, and code objects, where it\n\
1382should be understood that tuples, lists and dictionaries are only\n\
1383supported as long as the values contained therein are themselves\n\
1384supported; and recursive lists and dictionaries should not be written\n\
1385(they will cause infinite loops).\n\
1386\n\
1387Variables:\n\
1388\n\
1389version -- indicates the format that the module uses. Version 0 is the\n\
1390 historical format, version 1 (added in Python 2.4) shares interned\n\
1391 strings and version 2 (added in Python 2.5) uses a binary format for\n\
1392 floating point numbers. (New in version 2.4)\n\
1393\n\
1394Functions:\n\
1395\n\
1396dump() -- write value to a file\n\
1397load() -- read value from a file\n\
1398dumps() -- write value to a string\n\
1399loads() -- read value from a string");
1400
1401
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001402PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001403PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001404{
R. David Murraya3ec6972009-05-13 00:30:29 +00001405 PyObject *mod = Py_InitModule3("marshal", marshal_methods,
1406 marshal_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001407 if (mod == NULL)
1408 return;
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001409 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001410}