Kaydet (Commit) 1164dfcb authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #19219: Speed up marshal.loads(), and make pyc files slightly (5% to 10%) smaller.

üst 4c6ed25b
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
extern "C" { extern "C" {
#endif #endif
#define Py_MARSHAL_VERSION 3 #define Py_MARSHAL_VERSION 4
PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int);
PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int);
......
...@@ -262,11 +262,11 @@ class BugsTestCase(unittest.TestCase): ...@@ -262,11 +262,11 @@ class BugsTestCase(unittest.TestCase):
def test_bad_reader(self): def test_bad_reader(self):
class BadReader(io.BytesIO): class BadReader(io.BytesIO):
def read(self, n=-1): def readinto(self, buf):
b = super().read(n) n = super().readinto(buf)
if n is not None and n > 4: if n is not None and n > 4:
b += b' ' * 10**6 n += 10**6
return b return n
for value in (1.0, 1j, b'0123456789', '0123456789'): for value in (1.0, 1j, b'0123456789', '0123456789'):
self.assertRaises(ValueError, marshal.load, self.assertRaises(ValueError, marshal.load,
BadReader(marshal.dumps(value))) BadReader(marshal.dumps(value)))
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -51,6 +51,12 @@ ...@@ -51,6 +51,12 @@
#define TYPE_FROZENSET '>' #define TYPE_FROZENSET '>'
#define FLAG_REF '\x80' /* with a type, add obj to index */ #define FLAG_REF '\x80' /* with a type, add obj to index */
#define TYPE_ASCII 'a'
#define TYPE_ASCII_INTERNED 'A'
#define TYPE_SMALL_TUPLE ')'
#define TYPE_SHORT_ASCII 'z'
#define TYPE_SHORT_ASCII_INTERNED 'Z'
#define WFERR_OK 0 #define WFERR_OK 0
#define WFERR_UNMARSHALLABLE 1 #define WFERR_UNMARSHALLABLE 1
#define WFERR_NESTEDTOODEEP 2 #define WFERR_NESTEDTOODEEP 2
...@@ -66,6 +72,8 @@ typedef struct { ...@@ -66,6 +72,8 @@ typedef struct {
PyObject *current_filename; PyObject *current_filename;
char *ptr; char *ptr;
char *end; char *end;
char *buf;
Py_ssize_t buf_size;
PyObject *refs; /* dict on marshal, list on unmarshal */ PyObject *refs; /* dict on marshal, list on unmarshal */
int version; int version;
} WFILE; } WFILE;
...@@ -148,6 +156,13 @@ w_pstring(const char *s, Py_ssize_t n, WFILE *p) ...@@ -148,6 +156,13 @@ w_pstring(const char *s, Py_ssize_t n, WFILE *p)
w_string(s, n, p); w_string(s, n, p);
} }
static void
w_short_pstring(const char *s, Py_ssize_t n, WFILE *p)
{
w_byte(n, p);
w_string(s, n, p);
}
/* We assume that Python ints are stored internally in base some power of /* We assume that Python ints are stored internally in base some power of
2**15; for the sake of portability we'll always read and write them in base 2**15; for the sake of portability we'll always read and write them in base
exactly 2**15. */ exactly 2**15. */
...@@ -394,24 +409,51 @@ w_complex_object(PyObject *v, char flag, WFILE *p) ...@@ -394,24 +409,51 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p); w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
} }
else if (PyUnicode_CheckExact(v)) { else if (PyUnicode_CheckExact(v)) {
PyObject *utf8; if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass"); int is_short = PyUnicode_GET_LENGTH(v) < 256;
if (utf8 == NULL) { if (is_short) {
p->depth--; if (PyUnicode_CHECK_INTERNED(v))
p->error = WFERR_UNMARSHALLABLE; W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
return; else
W_TYPE(TYPE_SHORT_ASCII, p);
w_short_pstring((char *) PyUnicode_1BYTE_DATA(v),
PyUnicode_GET_LENGTH(v), p);
}
else {
if (PyUnicode_CHECK_INTERNED(v))
W_TYPE(TYPE_ASCII_INTERNED, p);
else
W_TYPE(TYPE_ASCII, p);
w_pstring((char *) PyUnicode_1BYTE_DATA(v),
PyUnicode_GET_LENGTH(v), p);
}
}
else {
PyObject *utf8;
utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
if (utf8 == NULL) {
p->depth--;
p->error = WFERR_UNMARSHALLABLE;
return;
}
if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
W_TYPE(TYPE_INTERNED, p);
else
W_TYPE(TYPE_UNICODE, p);
w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
Py_DECREF(utf8);
} }
if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
W_TYPE(TYPE_INTERNED, p);
else
W_TYPE(TYPE_UNICODE, p);
w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
Py_DECREF(utf8);
} }
else if (PyTuple_CheckExact(v)) { else if (PyTuple_CheckExact(v)) {
W_TYPE(TYPE_TUPLE, p);
n = PyTuple_Size(v); n = PyTuple_Size(v);
W_SIZE(n, p); if (p->version >= 4 && n < 256) {
W_TYPE(TYPE_SMALL_TUPLE, p);
w_byte(n, p);
}
else {
W_TYPE(TYPE_TUPLE, p);
W_SIZE(n, p);
}
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
w_object(PyTuple_GET_ITEM(v, i), p); w_object(PyTuple_GET_ITEM(v, i), p);
} }
...@@ -537,59 +579,75 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) ...@@ -537,59 +579,75 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
typedef WFILE RFILE; /* Same struct with different invariants */ typedef WFILE RFILE; /* Same struct with different invariants */
#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF) static char *
r_string(Py_ssize_t n, RFILE *p)
static Py_ssize_t
r_string(char *s, Py_ssize_t n, RFILE *p)
{ {
char *ptr; Py_ssize_t read = -1;
Py_ssize_t read, left;
if (p->ptr != NULL) {
if (!p->readable) { /* Fast path for loads() */
if (p->fp != NULL) char *res = p->ptr;
/* The result fits into int because it must be <=n. */ Py_ssize_t left = p->end - p->ptr;
read = fread(s, 1, n, p->fp); if (left < n) {
else { PyErr_SetString(PyExc_EOFError,
left = p->end - p->ptr; "marshal data too short");
read = (left < n) ? left : n; return NULL;
memcpy(s, p->ptr, read);
p->ptr += read;
} }
p->ptr += n;
return res;
}
if (p->buf == NULL) {
p->buf = PyMem_MALLOC(n);
if (p->buf == NULL) {
PyErr_NoMemory();
return NULL;
}
p->buf_size = n;
}
else if (p->buf_size < n) {
p->buf = PyMem_REALLOC(p->buf, n);
if (p->buf == NULL) {
PyErr_NoMemory();
return NULL;
}
p->buf_size = n;
}
if (!p->readable) {
assert(p->fp != NULL);
/* The result fits into int because it must be <=n. */
read = fread(p->buf, 1, n, p->fp);
} }
else { else {
_Py_IDENTIFIER(read); _Py_IDENTIFIER(readinto);
PyObject *res, *mview;
PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "n", n); Py_buffer buf;
read = 0;
if (data != NULL) { if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
if (!PyBytes_Check(data)) { return NULL;
PyErr_Format(PyExc_TypeError, mview = PyMemoryView_FromBuffer(&buf);
"f.read() returned not bytes but %.100s", if (mview == NULL)
data->ob_type->tp_name); return NULL;
}
else { res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
read = (int)PyBytes_GET_SIZE(data); if (res != NULL) {
if (read > 0) { read = PyNumber_AsSsize_t(res, PyExc_ValueError);
if (read > n) { Py_DECREF(res);
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);
} }
} }
if (!PyErr_Occurred() && (read < n)) { if (read != n) {
PyErr_SetString(PyExc_EOFError, "EOF read where not expected"); if (!PyErr_Occurred()) {
if (read > n)
PyErr_Format(PyExc_ValueError,
"read() returned too much data: "
"%zd bytes requested, %zd returned",
n, read);
else
PyErr_SetString(PyExc_EOFError,
"EOF read where not expected");
}
return NULL;
} }
return read; return p->buf;
} }
...@@ -597,15 +655,20 @@ static int ...@@ -597,15 +655,20 @@ static int
r_byte(RFILE *p) r_byte(RFILE *p)
{ {
int c = EOF; int c = EOF;
unsigned char ch;
Py_ssize_t n;
if (!p->readable) if (p->ptr != NULL) {
c = p->fp ? getc(p->fp) : rs_byte(p); if (p->ptr < p->end)
c = (unsigned char) *p->ptr++;
return c;
}
if (!p->readable) {
assert(p->fp);
c = getc(p->fp);
}
else { else {
n = r_string((char *) &ch, 1, p); char *ptr = r_string(1, p);
if (n > 0) if (ptr != NULL)
c = ch; c = *(unsigned char *) ptr;
} }
return c; return c;
} }
...@@ -613,32 +676,36 @@ r_byte(RFILE *p) ...@@ -613,32 +676,36 @@ r_byte(RFILE *p)
static int static int
r_short(RFILE *p) r_short(RFILE *p)
{ {
short x; short x = -1;
unsigned char buffer[2]; unsigned char *buffer;
r_string((char *) buffer, 2, p); buffer = (unsigned char *) r_string(2, p);
x = buffer[0]; if (buffer != NULL) {
x |= buffer[1] << 8; x = buffer[0];
/* Sign-extension, in case short greater than 16 bits */ x |= buffer[1] << 8;
x |= -(x & 0x8000); /* Sign-extension, in case short greater than 16 bits */
x |= -(x & 0x8000);
}
return x; return x;
} }
static long static long
r_long(RFILE *p) r_long(RFILE *p)
{ {
long x; long x = -1;
unsigned char buffer[4]; unsigned char *buffer;
r_string((char *) buffer, 4, p); buffer = (unsigned char *) r_string(4, p);
x = buffer[0]; if (buffer != NULL) {
x |= (long)buffer[1] << 8; x = buffer[0];
x |= (long)buffer[2] << 16; x |= (long)buffer[1] << 8;
x |= (long)buffer[3] << 24; x |= (long)buffer[2] << 16;
x |= (long)buffer[3] << 24;
#if SIZEOF_LONG > 4 #if SIZEOF_LONG > 4
/* Sign extension for 64-bit machines */ /* Sign extension for 64-bit machines */
x |= -(x & 0x80000000L); x |= -(x & 0x80000000L);
#endif #endif
}
return x; return x;
} }
...@@ -716,9 +783,7 @@ static Py_ssize_t ...@@ -716,9 +783,7 @@ static Py_ssize_t
r_ref_reserve(int flag, RFILE *p) r_ref_reserve(int flag, RFILE *p)
{ {
if (flag) { /* currently only FLAG_REF is defined */ if (flag) { /* currently only FLAG_REF is defined */
Py_ssize_t idx = PyList_Size(p->refs); Py_ssize_t idx = PyList_GET_SIZE(p->refs);
if (idx < 0)
return -1;
if (idx >= 0x7ffffffe) { if (idx >= 0x7ffffffe) {
PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)"); PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
return -1; return -1;
...@@ -742,12 +807,10 @@ static PyObject * ...@@ -742,12 +807,10 @@ static PyObject *
r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p) r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
{ {
if (o != NULL && flag) { /* currently only FLAG_REF is defined */ if (o != NULL && flag) { /* currently only FLAG_REF is defined */
if (PyList_SetItem(p->refs, idx, o) < 0) { PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
Py_DECREF(o); /* release the new object */ Py_INCREF(o);
return NULL; PyList_SET_ITEM(p->refs, idx, o);
} else { Py_DECREF(tmp);
Py_INCREF(o); /* a reference for the list */
}
} }
return o; return o;
} }
...@@ -777,7 +840,7 @@ r_object(RFILE *p) ...@@ -777,7 +840,7 @@ r_object(RFILE *p)
Py_ssize_t idx = 0; Py_ssize_t idx = 0;
long i, n; long i, n;
int type, code = r_byte(p); int type, code = r_byte(p);
int flag; int flag, is_interned = 0;
PyObject *retval; PyObject *retval;
if (code == EOF) { if (code == EOF) {
...@@ -846,7 +909,7 @@ r_object(RFILE *p) ...@@ -846,7 +909,7 @@ r_object(RFILE *p)
case TYPE_FLOAT: case TYPE_FLOAT:
{ {
char buf[256]; char buf[256], *ptr;
double dx; double dx;
retval = NULL; retval = NULL;
n = r_byte(p); n = r_byte(p);
...@@ -855,8 +918,10 @@ r_object(RFILE *p) ...@@ -855,8 +918,10 @@ r_object(RFILE *p)
"EOF read where object expected"); "EOF read where object expected");
break; break;
} }
if (r_string(buf, n, p) != n) ptr = r_string(n, p);
if (ptr == NULL)
break; break;
memcpy(buf, ptr, n);
buf[n] = '\0'; buf[n] = '\0';
dx = PyOS_string_to_double(buf, NULL, NULL); dx = PyOS_string_to_double(buf, NULL, NULL);
if (dx == -1.0 && PyErr_Occurred()) if (dx == -1.0 && PyErr_Occurred())
...@@ -868,9 +933,10 @@ r_object(RFILE *p) ...@@ -868,9 +933,10 @@ r_object(RFILE *p)
case TYPE_BINARY_FLOAT: case TYPE_BINARY_FLOAT:
{ {
unsigned char buf[8]; unsigned char *buf;
double x; double x;
if (r_string((char*)buf, 8, p) != 8) { buf = (unsigned char *) r_string(8, p);
if (buf == NULL) {
retval = NULL; retval = NULL;
break; break;
} }
...@@ -886,7 +952,7 @@ r_object(RFILE *p) ...@@ -886,7 +952,7 @@ r_object(RFILE *p)
case TYPE_COMPLEX: case TYPE_COMPLEX:
{ {
char buf[256]; char buf[256], *ptr;
Py_complex c; Py_complex c;
retval = NULL; retval = NULL;
n = r_byte(p); n = r_byte(p);
...@@ -895,8 +961,10 @@ r_object(RFILE *p) ...@@ -895,8 +961,10 @@ r_object(RFILE *p)
"EOF read where object expected"); "EOF read where object expected");
break; break;
} }
if (r_string(buf, n, p) != n) ptr = r_string(n, p);
if (ptr == NULL)
break; break;
memcpy(buf, ptr, n);
buf[n] = '\0'; buf[n] = '\0';
c.real = PyOS_string_to_double(buf, NULL, NULL); c.real = PyOS_string_to_double(buf, NULL, NULL);
if (c.real == -1.0 && PyErr_Occurred()) if (c.real == -1.0 && PyErr_Occurred())
...@@ -907,8 +975,10 @@ r_object(RFILE *p) ...@@ -907,8 +975,10 @@ r_object(RFILE *p)
"EOF read where object expected"); "EOF read where object expected");
break; break;
} }
if (r_string(buf, n, p) != n) ptr = r_string(n, p);
if (ptr == NULL)
break; break;
memcpy(buf, ptr, n);
buf[n] = '\0'; buf[n] = '\0';
c.imag = PyOS_string_to_double(buf, NULL, NULL); c.imag = PyOS_string_to_double(buf, NULL, NULL);
if (c.imag == -1.0 && PyErr_Occurred()) if (c.imag == -1.0 && PyErr_Occurred())
...@@ -920,9 +990,10 @@ r_object(RFILE *p) ...@@ -920,9 +990,10 @@ r_object(RFILE *p)
case TYPE_BINARY_COMPLEX: case TYPE_BINARY_COMPLEX:
{ {
unsigned char buf[8]; unsigned char *buf;
Py_complex c; Py_complex c;
if (r_string((char*)buf, 8, p) != 8) { buf = (unsigned char *) r_string(8, p);
if (buf == NULL) {
retval = NULL; retval = NULL;
break; break;
} }
...@@ -931,7 +1002,8 @@ r_object(RFILE *p) ...@@ -931,7 +1002,8 @@ r_object(RFILE *p)
retval = NULL; retval = NULL;
break; break;
} }
if (r_string((char*)buf, 8, p) != 8) { buf = (unsigned char *) r_string(8, p);
if (buf == NULL) {
retval = NULL; retval = NULL;
break; break;
} }
...@@ -946,32 +1018,82 @@ r_object(RFILE *p) ...@@ -946,32 +1018,82 @@ r_object(RFILE *p)
} }
case TYPE_STRING: case TYPE_STRING:
{
char *ptr;
n = r_long(p);
if (PyErr_Occurred()) {
retval = NULL;
break;
}
if (n < 0 || n > SIZE32_MAX) {
PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
retval = NULL;
break;
}
v = PyBytes_FromStringAndSize((char *)NULL, n);
if (v == NULL) {
retval = NULL;
break;
}
ptr = r_string(n, p);
if (ptr == NULL) {
Py_DECREF(v);
retval = NULL;
break;
}
memcpy(PyBytes_AS_STRING(v), ptr, n);
retval = v;
R_REF(retval);
break;
}
case TYPE_ASCII_INTERNED:
is_interned = 1;
case TYPE_ASCII:
n = r_long(p); n = r_long(p);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
retval = NULL; retval = NULL;
break; break;
} }
if (n < 0 || n > SIZE32_MAX) { if (n < 0 || n > SIZE32_MAX) {
PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
retval = NULL; retval = NULL;
break; break;
} }
v = PyBytes_FromStringAndSize((char *)NULL, n); goto _read_ascii;
if (v == NULL) {
retval = NULL; case TYPE_SHORT_ASCII_INTERNED:
is_interned = 1;
case TYPE_SHORT_ASCII:
n = r_byte(p);
if (n == EOF) {
PyErr_SetString(PyExc_EOFError,
"EOF read where object expected");
break; break;
} }
if (r_string(PyBytes_AS_STRING(v), n, p) != n) { _read_ascii:
Py_DECREF(v); {
retval = NULL; char *ptr;
ptr = r_string(n, p);
if (ptr == NULL) {
retval = NULL;
break;
}
v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
if (v == NULL) {
retval = NULL;
break;
}
if (is_interned)
PyUnicode_InternInPlace(&v);
retval = v;
R_REF(retval);
break; break;
} }
retval = v;
R_REF(retval);
break;
case TYPE_UNICODE:
case TYPE_INTERNED: case TYPE_INTERNED:
is_interned = 1;
case TYPE_UNICODE:
{ {
char *buffer; char *buffer;
...@@ -986,18 +1108,12 @@ r_object(RFILE *p) ...@@ -986,18 +1108,12 @@ r_object(RFILE *p)
break; break;
} }
if (n != 0) { if (n != 0) {
buffer = PyMem_NEW(char, n); buffer = r_string(n, p);
if (buffer == NULL) { if (buffer == NULL) {
retval = PyErr_NoMemory();
break;
}
if (r_string(buffer, n, p) != n) {
PyMem_DEL(buffer);
retval = NULL; retval = NULL;
break; break;
} }
v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass"); v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
PyMem_DEL(buffer);
} }
else { else {
v = PyUnicode_New(0, 0); v = PyUnicode_New(0, 0);
...@@ -1006,13 +1122,16 @@ r_object(RFILE *p) ...@@ -1006,13 +1122,16 @@ r_object(RFILE *p)
retval = NULL; retval = NULL;
break; break;
} }
if (type == TYPE_INTERNED) if (is_interned)
PyUnicode_InternInPlace(&v); PyUnicode_InternInPlace(&v);
retval = v; retval = v;
R_REF(retval); R_REF(retval);
break; break;
} }
case TYPE_SMALL_TUPLE:
n = (unsigned char) r_byte(p);
goto _read_tuple;
case TYPE_TUPLE: case TYPE_TUPLE:
n = r_long(p); n = r_long(p);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
...@@ -1024,6 +1143,7 @@ r_object(RFILE *p) ...@@ -1024,6 +1143,7 @@ r_object(RFILE *p)
retval = NULL; retval = NULL;
break; break;
} }
_read_tuple:
v = PyTuple_New(n); v = PyTuple_New(n);
R_REF(v); R_REF(v);
if (v == NULL) { if (v == NULL) {
...@@ -1304,23 +1424,33 @@ int ...@@ -1304,23 +1424,33 @@ int
PyMarshal_ReadShortFromFile(FILE *fp) PyMarshal_ReadShortFromFile(FILE *fp)
{ {
RFILE rf; RFILE rf;
int res;
assert(fp); assert(fp);
rf.readable = NULL; rf.readable = NULL;
rf.fp = fp; rf.fp = fp;
rf.current_filename = NULL; rf.current_filename = NULL;
rf.end = rf.ptr = NULL; rf.end = rf.ptr = NULL;
return r_short(&rf); rf.buf = NULL;
res = r_short(&rf);
if (rf.buf != NULL)
PyMem_FREE(rf.buf);
return res;
} }
long long
PyMarshal_ReadLongFromFile(FILE *fp) PyMarshal_ReadLongFromFile(FILE *fp)
{ {
RFILE rf; RFILE rf;
long res;
rf.fp = fp; rf.fp = fp;
rf.readable = NULL; rf.readable = NULL;
rf.current_filename = NULL; rf.current_filename = NULL;
rf.ptr = rf.end = NULL; rf.ptr = rf.end = NULL;
return r_long(&rf); rf.buf = NULL;
res = r_long(&rf);
if (rf.buf != NULL)
PyMem_FREE(rf.buf);
return res;
} }
#ifdef HAVE_FSTAT #ifdef HAVE_FSTAT
...@@ -1379,11 +1509,14 @@ PyMarshal_ReadObjectFromFile(FILE *fp) ...@@ -1379,11 +1509,14 @@ PyMarshal_ReadObjectFromFile(FILE *fp)
rf.current_filename = NULL; rf.current_filename = NULL;
rf.depth = 0; rf.depth = 0;
rf.ptr = rf.end = NULL; rf.ptr = rf.end = NULL;
rf.buf = NULL;
rf.refs = PyList_New(0); rf.refs = PyList_New(0);
if (rf.refs == NULL) if (rf.refs == NULL)
return NULL; return NULL;
result = r_object(&rf); result = r_object(&rf);
Py_DECREF(rf.refs); Py_DECREF(rf.refs);
if (rf.buf != NULL)
PyMem_FREE(rf.buf);
return result; return result;
} }
...@@ -1397,12 +1530,15 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len) ...@@ -1397,12 +1530,15 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
rf.current_filename = NULL; rf.current_filename = NULL;
rf.ptr = str; rf.ptr = str;
rf.end = str + len; rf.end = str + len;
rf.buf = NULL;
rf.depth = 0; rf.depth = 0;
rf.refs = PyList_New(0); rf.refs = PyList_New(0);
if (rf.refs == NULL) if (rf.refs == NULL)
return NULL; return NULL;
result = r_object(&rf); result = r_object(&rf);
Py_DECREF(rf.refs); Py_DECREF(rf.refs);
if (rf.buf != NULL)
PyMem_FREE(rf.buf);
return result; return result;
} }
...@@ -1516,9 +1652,13 @@ marshal_load(PyObject *self, PyObject *f) ...@@ -1516,9 +1652,13 @@ marshal_load(PyObject *self, PyObject *f)
rf.fp = NULL; rf.fp = NULL;
rf.readable = f; rf.readable = f;
rf.current_filename = NULL; rf.current_filename = NULL;
rf.ptr = rf.end = NULL;
rf.buf = NULL;
if ((rf.refs = PyList_New(0)) != NULL) { if ((rf.refs = PyList_New(0)) != NULL) {
result = read_object(&rf); result = read_object(&rf);
Py_DECREF(rf.refs); Py_DECREF(rf.refs);
if (rf.buf != NULL)
PyMem_FREE(rf.buf);
} else } else
result = NULL; result = NULL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment