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)))
+
+ def _test_eof(self):
+ data = marshal.dumps(("hello", "dolly", None))
+ for i in range(len(data)):
+ self.assertRaises(EOFError, marshal.loads, data[0: i])
+
LARGE_SIZE = 2**31
pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
Core and Builtins
-----------------
+ - Issue #17872: Fix a segfault in marshal.load() when input stream returns
+ more bytes than requested.
+
+- Issue #18338: `python --version` now prints version string to stdout, and
+ not to stderr. Patch by Berker Peksag and Michael Dickens.
+
- Issue #18426: Fix NULL pointer dereference in C extension import when
PyModule_GetDef() returns an error.
data->ob_type->tp_name);
}
else {
- read = PyBytes_GET_SIZE(data);
+ read = (int)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);
retval = NULL;
break;
}
- buffer = PyMem_NEW(char, n);
- if (buffer == NULL) {
- retval = PyErr_NoMemory();
- break;
- }
- if (r_string(buffer, n, p) != n) {
+ if (n != 0) {
+ buffer = PyMem_NEW(char, n);
+ if (buffer == NULL) {
+ retval = PyErr_NoMemory();
+ break;
+ }
+ if (r_string(buffer, n, p) != n) {
+ PyMem_DEL(buffer);
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
PyMem_DEL(buffer);
+ }
+ else {
+ v = PyUnicode_New(0, 0);
+ }
+ if (v == NULL) {
retval = NULL;
break;
}