summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2000-06-28 18:47:56 (GMT)
committerFred Drake <fdrake@acm.org>2000-06-28 18:47:56 (GMT)
commit6da0b9148c9e733ac98d9889a79c7b93bb80b0f3 (patch)
tree48c6193afb5f728a0785da4e2d077fc9856ee72d
parent7833447f8f41d09749796cfa5e96788bccbab7a0 (diff)
downloadcpython-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.c25
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);