mirror of https://github.com/python/cpython
Michael Hudson <mwh21@cam.ac.uk>:
As I really do not have anything better to do at the moment, I have written a patch to Python/marshal.c that prevents Python dumping core when trying to marshal stack bustingly deep (or recursive) data structure. It just throws an exception; even slightly clever handling of recursive data is what pickle is for... [Fred Drake:] Moved magic constant 5000 to a #define. This closes SourceForge patch #100645.
This commit is contained in:
parent
7833447f8f
commit
6da0b9148c
|
@ -39,6 +39,12 @@ PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#include "marshal.h"
|
#include "marshal.h"
|
||||||
|
|
||||||
|
/* High water mark to determine when the marshalled object is dangerously deep
|
||||||
|
* and risks coring the interpreter. When the object stack gets this deep,
|
||||||
|
* raise an exception instead of continuing.
|
||||||
|
*/
|
||||||
|
#define MAX_MARSHAL_STACK_DEPTH 5000
|
||||||
|
|
||||||
#define TYPE_NULL '0'
|
#define TYPE_NULL '0'
|
||||||
#define TYPE_NONE 'N'
|
#define TYPE_NONE 'N'
|
||||||
#define TYPE_ELLIPSIS '.'
|
#define TYPE_ELLIPSIS '.'
|
||||||
|
@ -58,6 +64,7 @@ PERFORMANCE OF THIS SOFTWARE.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int error;
|
int error;
|
||||||
|
int depth;
|
||||||
/* If fp == NULL, the following are valid: */
|
/* If fp == NULL, the following are valid: */
|
||||||
PyObject *str;
|
PyObject *str;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -145,7 +152,12 @@ w_object(v, p)
|
||||||
int i, n;
|
int i, n;
|
||||||
PyBufferProcs *pb;
|
PyBufferProcs *pb;
|
||||||
|
|
||||||
if (v == NULL) {
|
p->depth++;
|
||||||
|
|
||||||
|
if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
|
||||||
|
p->error = 2;
|
||||||
|
}
|
||||||
|
else if (v == NULL) {
|
||||||
w_byte(TYPE_NULL, p);
|
w_byte(TYPE_NULL, p);
|
||||||
}
|
}
|
||||||
else if (v == Py_None) {
|
else if (v == Py_None) {
|
||||||
|
@ -301,6 +313,7 @@ PyMarshal_WriteLongToFile(x, fp)
|
||||||
WFILE wf;
|
WFILE wf;
|
||||||
wf.fp = fp;
|
wf.fp = fp;
|
||||||
wf.error = 0;
|
wf.error = 0;
|
||||||
|
wf.depth = 0;
|
||||||
w_long(x, &wf);
|
w_long(x, &wf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,6 +703,7 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */
|
||||||
wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
|
wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
|
||||||
wf.end = wf.ptr + PyString_Size(wf.str);
|
wf.end = wf.ptr + PyString_Size(wf.str);
|
||||||
wf.error = 0;
|
wf.error = 0;
|
||||||
|
wf.depth = 0;
|
||||||
w_object(x, &wf);
|
w_object(x, &wf);
|
||||||
if (wf.str != NULL)
|
if (wf.str != NULL)
|
||||||
_PyString_Resize(&wf.str,
|
_PyString_Resize(&wf.str,
|
||||||
|
@ -697,7 +711,9 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */
|
||||||
PyString_AS_STRING((PyStringObject *)wf.str)));
|
PyString_AS_STRING((PyStringObject *)wf.str)));
|
||||||
if (wf.error) {
|
if (wf.error) {
|
||||||
Py_XDECREF(wf.str);
|
Py_XDECREF(wf.str);
|
||||||
PyErr_SetString(PyExc_ValueError, "unmarshallable object");
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
(wf.error==1)?"unmarshallable object"
|
||||||
|
:"object too deeply nested to marshal");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return wf.str;
|
return wf.str;
|
||||||
|
@ -724,9 +740,12 @@ marshal_dump(self, args)
|
||||||
wf.str = NULL;
|
wf.str = NULL;
|
||||||
wf.ptr = wf.end = NULL;
|
wf.ptr = wf.end = NULL;
|
||||||
wf.error = 0;
|
wf.error = 0;
|
||||||
|
wf.depth = 0;
|
||||||
w_object(x, &wf);
|
w_object(x, &wf);
|
||||||
if (wf.error) {
|
if (wf.error) {
|
||||||
PyErr_SetString(PyExc_ValueError, "unmarshallable object");
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
(wf.error==1)?"unmarshallable object"
|
||||||
|
:"object too deeply nested to marshal");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
|
|
Loading…
Reference in New Issue