mirror of
https://github.com/python/cpython.git
synced 2025-01-19 15:05:15 +08:00
Issue #17872: Fix a segfault in marshal.load() when input stream returns
more bytes than requested.
This commit is contained in:
parent
244d6252f2
commit
3641a74e1c
@ -2,6 +2,7 @@
|
||||
|
||||
from test import support
|
||||
import array
|
||||
import io
|
||||
import marshal
|
||||
import sys
|
||||
import unittest
|
||||
@ -279,6 +280,17 @@ class BugsTestCase(unittest.TestCase):
|
||||
unicode_string = 'T'
|
||||
self.assertRaises(TypeError, marshal.loads, unicode_string)
|
||||
|
||||
def test_bad_reader(self):
|
||||
class BadReader(io.BytesIO):
|
||||
def read(self, n=-1):
|
||||
b = super().read(n)
|
||||
if n is not None and n > 4:
|
||||
b += b' ' * 10**6
|
||||
return b
|
||||
for value in (1.0, 1j, b'0123456789', '0123456789'):
|
||||
self.assertRaises(ValueError, marshal.load,
|
||||
BadReader(marshal.dumps(value)))
|
||||
|
||||
LARGE_SIZE = 2**31
|
||||
pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
|
||||
|
||||
|
@ -12,6 +12,9 @@ What's New in Python 3.3.3 release candidate 1?
|
||||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #17872: Fix a segfault in marshal.load() when input stream returns
|
||||
more bytes than requested.
|
||||
|
||||
- Issue #18426: Fix NULL pointer dereference in C extension import when
|
||||
PyModule_GetDef() returns an error.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user