summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-07-11 19:20:47 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-07-11 19:20:47 (GMT)
commit3641a74e1c03ce153042d2c21639e5b6b9604f3b (patch)
tree2548c42f980acdb590551e8f6209322c34f07572 /Python
parent244d6252f2ed17b61c476926faf5c15ba5328ff0 (diff)
downloadcpython-3641a74e1c03ce153042d2c21639e5b6b9604f3b.zip
cpython-3641a74e1c03ce153042d2c21639e5b6b9604f3b.tar.gz
cpython-3641a74e1c03ce153042d2c21639e5b6b9604f3b.tar.bz2
Issue #17872: Fix a segfault in marshal.load() when input stream returns
more bytes than requested.
Diffstat (limited to 'Python')
-rw-r--r--Python/marshal.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/Python/marshal.c b/Python/marshal.c
index 23764cc..a0e527f 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -490,8 +490,17 @@ r_string(char *s, Py_ssize_t n, RFILE *p)
else {
read = PyBytes_GET_SIZE(data);
if (read > 0) {
- ptr = PyBytes_AS_STRING(data);
- memcpy(s, ptr, read);
+ if (read > n) {
+ PyErr_Format(PyExc_ValueError,
+ "read() returned too much data: "
+ "%zd bytes requested, %zd returned",
+ n, read);
+ read = -1;
+ }
+ else {
+ ptr = PyBytes_AS_STRING(data);
+ memcpy(s, ptr, read);
+ }
}
}
Py_DECREF(data);
@@ -733,11 +742,13 @@ r_object(RFILE *p)
double dx;
retval = NULL;
n = r_byte(p);
- if (n == EOF || r_string(buf, n, p) != n) {
+ if (n == EOF) {
PyErr_SetString(PyExc_EOFError,
"EOF read where object expected");
break;
}
+ if (r_string(buf, n, p) != n)
+ break;
buf[n] = '\0';
dx = PyOS_string_to_double(buf, NULL, NULL);
if (dx == -1.0 && PyErr_Occurred())
@@ -751,8 +762,6 @@ r_object(RFILE *p)
unsigned char buf[8];
double x;
if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
retval = NULL;
break;
}
@@ -771,21 +780,25 @@ r_object(RFILE *p)
Py_complex c;
retval = NULL;
n = r_byte(p);
- if (n == EOF || r_string(buf, n, p) != n) {
+ if (n == EOF) {
PyErr_SetString(PyExc_EOFError,
"EOF read where object expected");
break;
}
+ if (r_string(buf, n, p) != n)
+ break;
buf[n] = '\0';
c.real = PyOS_string_to_double(buf, NULL, NULL);
if (c.real == -1.0 && PyErr_Occurred())
break;
n = r_byte(p);
- if (n == EOF || r_string(buf, n, p) != n) {
+ if (n == EOF) {
PyErr_SetString(PyExc_EOFError,
"EOF read where object expected");
break;
}
+ if (r_string(buf, n, p) != n)
+ break;
buf[n] = '\0';
c.imag = PyOS_string_to_double(buf, NULL, NULL);
if (c.imag == -1.0 && PyErr_Occurred())
@@ -799,8 +812,6 @@ r_object(RFILE *p)
unsigned char buf[8];
Py_complex c;
if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
retval = NULL;
break;
}
@@ -810,8 +821,6 @@ r_object(RFILE *p)
break;
}
if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
retval = NULL;
break;
}
@@ -842,8 +851,6 @@ r_object(RFILE *p)
}
if (r_string(PyBytes_AS_STRING(v), n, p) != n) {
Py_DECREF(v);
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
retval = NULL;
break;
}
@@ -871,8 +878,6 @@ r_object(RFILE *p)
}
if (r_string(buffer, n, p) != n) {
PyMem_DEL(buffer);
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
retval = NULL;
break;
}