diff options
author | Fred Drake <fdrake@acm.org> | 2000-06-28 18:47:56 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2000-06-28 18:47:56 (GMT) |
commit | 6da0b9148c9e733ac98d9889a79c7b93bb80b0f3 (patch) | |
tree | 48c6193afb5f728a0785da4e2d077fc9856ee72d | |
parent | 7833447f8f41d09749796cfa5e96788bccbab7a0 (diff) | |
download | cpython-6da0b9148c9e733ac98d9889a79c7b93bb80b0f3.zip cpython-6da0b9148c9e733ac98d9889a79c7b93bb80b0f3.tar.gz cpython-6da0b9148c9e733ac98d9889a79c7b93bb80b0f3.tar.bz2 |
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.
-rw-r--r-- | Python/marshal.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/Python/marshal.c b/Python/marshal.c index fe9e000..a316d18 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -39,6 +39,12 @@ PERFORMANCE OF THIS SOFTWARE. #include "compile.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_NONE 'N' #define TYPE_ELLIPSIS '.' @@ -58,6 +64,7 @@ PERFORMANCE OF THIS SOFTWARE. typedef struct { FILE *fp; int error; + int depth; /* If fp == NULL, the following are valid: */ PyObject *str; char *ptr; @@ -144,8 +151,13 @@ w_object(v, p) { int i, n; PyBufferProcs *pb; + + p->depth++; - if (v == NULL) { + if (p->depth > MAX_MARSHAL_STACK_DEPTH) { + p->error = 2; + } + else if (v == NULL) { w_byte(TYPE_NULL, p); } else if (v == Py_None) { @@ -301,6 +313,7 @@ PyMarshal_WriteLongToFile(x, fp) WFILE wf; wf.fp = fp; wf.error = 0; + wf.depth = 0; w_long(x, &wf); } @@ -690,6 +703,7 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */ wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str); wf.end = wf.ptr + PyString_Size(wf.str); wf.error = 0; + wf.depth = 0; w_object(x, &wf); if (wf.str != NULL) _PyString_Resize(&wf.str, @@ -697,7 +711,9 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */ PyString_AS_STRING((PyStringObject *)wf.str))); if (wf.error) { 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 wf.str; @@ -724,9 +740,12 @@ marshal_dump(self, args) wf.str = NULL; wf.ptr = wf.end = NULL; wf.error = 0; + wf.depth = 0; w_object(x, &wf); 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; } Py_INCREF(Py_None); |