Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b1a03cf

Browse files
committed
Added handling of PyOS_double_to_string out-of-memory errors. Closes issue 5775.
1 parent 960dc36 commit b1a03cf

1 file changed

Lines changed: 41 additions & 27 deletions

File tree

Python/marshal.c

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@
4747
#define TYPE_SET '<'
4848
#define TYPE_FROZENSET '>'
4949

50+
#define WFERR_OK 0
51+
#define WFERR_UNMARSHALLABLE 1
52+
#define WFERR_NESTEDTOODEEP 2
53+
#define WFERR_NOMEMORY 3
54+
5055
typedef struct {
5156
FILE *fp;
52-
int error;
57+
int error; /* see WFERR_* values */
5358
int depth;
5459
/* If fp == NULL, the following are valid: */
5560
PyObject *str;
@@ -182,7 +187,7 @@ w_object(PyObject *v, WFILE *p)
182187
p->depth++;
183188

184189
if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
185-
p->error = 2;
190+
p->error = WFERR_NESTEDTOODEEP;
186191
}
187192
else if (v == NULL) {
188193
w_byte(TYPE_NULL, p);
@@ -229,7 +234,7 @@ w_object(PyObject *v, WFILE *p)
229234
unsigned char buf[8];
230235
if (_PyFloat_Pack8(PyFloat_AsDouble(v),
231236
buf, 1) < 0) {
232-
p->error = 1;
237+
p->error = WFERR_UNMARSHALLABLE;
233238
return;
234239
}
235240
w_byte(TYPE_BINARY_FLOAT, p);
@@ -238,8 +243,10 @@ w_object(PyObject *v, WFILE *p)
238243
else {
239244
char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
240245
'g', 17, 0, NULL);
241-
if (!buf)
242-
return;
246+
if (!buf) {
247+
p->error = WFERR_NOMEMORY;
248+
return;
249+
}
243250
n = strlen(buf);
244251
w_byte(TYPE_FLOAT, p);
245252
w_byte((int)n, p);
@@ -253,14 +260,14 @@ w_object(PyObject *v, WFILE *p)
253260
unsigned char buf[8];
254261
if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
255262
buf, 1) < 0) {
256-
p->error = 1;
263+
p->error = WFERR_UNMARSHALLABLE;
257264
return;
258265
}
259266
w_byte(TYPE_BINARY_COMPLEX, p);
260267
w_string((char*)buf, 8, p);
261268
if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
262269
buf, 1) < 0) {
263-
p->error = 1;
270+
p->error = WFERR_UNMARSHALLABLE;
264271
return;
265272
}
266273
w_string((char*)buf, 8, p);
@@ -270,16 +277,20 @@ w_object(PyObject *v, WFILE *p)
270277
w_byte(TYPE_COMPLEX, p);
271278
buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
272279
'g', 17, 0, NULL);
273-
if (!buf)
274-
return;
280+
if (!buf) {
281+
p->error = WFERR_NOMEMORY;
282+
return;
283+
}
275284
n = strlen(buf);
276285
w_byte((int)n, p);
277286
w_string(buf, (int)n, p);
278287
PyMem_Free(buf);
279288
buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
280289
'g', 17, 0, NULL);
281-
if (!buf)
282-
return;
290+
if (!buf) {
291+
p->error = WFERR_NOMEMORY;
292+
return;
293+
}
283294
n = strlen(buf);
284295
w_byte((int)n, p);
285296
w_string(buf, (int)n, p);
@@ -293,7 +304,7 @@ w_object(PyObject *v, WFILE *p)
293304
if (n > INT_MAX) {
294305
/* huge strings are not supported */
295306
p->depth--;
296-
p->error = 1;
307+
p->error = WFERR_UNMARSHALLABLE;
297308
return;
298309
}
299310
w_long((long)n, p);
@@ -304,14 +315,14 @@ w_object(PyObject *v, WFILE *p)
304315
utf8 = PyUnicode_AsUTF8String(v);
305316
if (utf8 == NULL) {
306317
p->depth--;
307-
p->error = 1;
318+
p->error = WFERR_UNMARSHALLABLE;
308319
return;
309320
}
310321
w_byte(TYPE_UNICODE, p);
311322
n = PyBytes_GET_SIZE(utf8);
312323
if (n > INT_MAX) {
313324
p->depth--;
314-
p->error = 1;
325+
p->error = WFERR_UNMARSHALLABLE;
315326
return;
316327
}
317328
w_long((long)n, p);
@@ -356,14 +367,14 @@ w_object(PyObject *v, WFILE *p)
356367
n = PyObject_Size(v);
357368
if (n == -1) {
358369
p->depth--;
359-
p->error = 1;
370+
p->error = WFERR_UNMARSHALLABLE;
360371
return;
361372
}
362373
w_long((long)n, p);
363374
it = PyObject_GetIter(v);
364375
if (it == NULL) {
365376
p->depth--;
366-
p->error = 1;
377+
p->error = WFERR_UNMARSHALLABLE;
367378
return;
368379
}
369380
while ((value = PyIter_Next(it)) != NULL) {
@@ -373,7 +384,7 @@ w_object(PyObject *v, WFILE *p)
373384
Py_DECREF(it);
374385
if (PyErr_Occurred()) {
375386
p->depth--;
376-
p->error = 1;
387+
p->error = WFERR_UNMARSHALLABLE;
377388
return;
378389
}
379390
}
@@ -403,14 +414,14 @@ w_object(PyObject *v, WFILE *p)
403414
Py_buffer view;
404415
if ((*pb->bf_getbuffer)(v, &view, PyBUF_SIMPLE) != 0) {
405416
w_byte(TYPE_UNKNOWN, p);
406-
p->error = 1;
417+
p->error = WFERR_UNMARSHALLABLE;
407418
}
408419
w_byte(TYPE_STRING, p);
409420
n = view.len;
410421
s = view.buf;
411422
if (n > INT_MAX) {
412423
p->depth--;
413-
p->error = 1;
424+
p->error = WFERR_UNMARSHALLABLE;
414425
return;
415426
}
416427
w_long((long)n, p);
@@ -420,7 +431,7 @@ w_object(PyObject *v, WFILE *p)
420431
}
421432
else {
422433
w_byte(TYPE_UNKNOWN, p);
423-
p->error = 1;
434+
p->error = WFERR_UNMARSHALLABLE;
424435
}
425436
p->depth--;
426437
}
@@ -431,7 +442,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
431442
{
432443
WFILE wf;
433444
wf.fp = fp;
434-
wf.error = 0;
445+
wf.error = WFERR_OK;
435446
wf.depth = 0;
436447
wf.strings = NULL;
437448
wf.version = version;
@@ -443,7 +454,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
443454
{
444455
WFILE wf;
445456
wf.fp = fp;
446-
wf.error = 0;
457+
wf.error = WFERR_OK;
447458
wf.depth = 0;
448459
wf.strings = (version > 0) ? PyDict_New() : NULL;
449460
wf.version = version;
@@ -1143,7 +1154,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
11431154
return NULL;
11441155
wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str);
11451156
wf.end = wf.ptr + PyBytes_Size(wf.str);
1146-
wf.error = 0;
1157+
wf.error = WFERR_OK;
11471158
wf.depth = 0;
11481159
wf.version = version;
11491160
wf.strings = (version > 0) ? PyDict_New() : NULL;
@@ -1160,11 +1171,14 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
11601171
if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
11611172
return NULL;
11621173
}
1163-
if (wf.error) {
1174+
if (wf.error != WFERR_OK) {
11641175
Py_XDECREF(wf.str);
1165-
PyErr_SetString(PyExc_ValueError,
1166-
(wf.error==1)?"unmarshallable object"
1167-
:"object too deeply nested to marshal");
1176+
if (wf.error == WFERR_NOMEMORY)
1177+
PyErr_NoMemory();
1178+
else
1179+
PyErr_SetString(PyExc_ValueError,
1180+
(wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1181+
:"object too deeply nested to marshal");
11681182
return NULL;
11691183
}
11701184
if (wf.str != NULL) {

0 commit comments

Comments
 (0)