diff options
Diffstat (limited to 'Python/marshal.c')
-rw-r--r-- | Python/marshal.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/Python/marshal.c b/Python/marshal.c index 5b8de99..627a842 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -263,10 +263,10 @@ w_ref(PyObject *v, char *flag, WFILE *p) if (Py_REFCNT(v) == 1) return 0; - entry = _Py_hashtable_get_entry(p->hashtable, v); + entry = _Py_HASHTABLE_GET_ENTRY(p->hashtable, v); if (entry != NULL) { /* write the reference index to the stream */ - _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, &w, sizeof(w), entry); + _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, entry, w); /* we don't store "long" indices in the dict */ assert(0 <= w && w <= 0x7fffffff); w_byte(TYPE_REF, p); @@ -571,7 +571,8 @@ static int w_init_refs(WFILE *wf, int version) { if (version >= 3) { - wf->hashtable = _Py_hashtable_new(sizeof(int), _Py_hashtable_hash_ptr, + wf->hashtable = _Py_hashtable_new(sizeof(PyObject *), sizeof(int), + _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct); if (wf->hashtable == NULL) { PyErr_NoMemory(); @@ -582,9 +583,13 @@ w_init_refs(WFILE *wf, int version) } static int -w_decref_entry(_Py_hashtable_entry_t *entry, void *Py_UNUSED(data)) +w_decref_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *Py_UNUSED(data)) { - Py_XDECREF(entry->key); + PyObject *entry_key; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, entry_key); + Py_XDECREF(entry_key); return 0; } @@ -643,7 +648,7 @@ typedef struct { PyObject *refs; /* a list */ } RFILE; -static char * +static const char * r_string(Py_ssize_t n, RFILE *p) { Py_ssize_t read = -1; @@ -729,7 +734,7 @@ r_byte(RFILE *p) c = getc(p->fp); } else { - char *ptr = r_string(1, p); + const char *ptr = r_string(1, p); if (ptr != NULL) c = *(unsigned char *) ptr; } @@ -740,9 +745,9 @@ static int r_short(RFILE *p) { short x = -1; - unsigned char *buffer; + const unsigned char *buffer; - buffer = (unsigned char *) r_string(2, p); + buffer = (const unsigned char *) r_string(2, p); if (buffer != NULL) { x = buffer[0]; x |= buffer[1] << 8; @@ -756,9 +761,9 @@ static long r_long(RFILE *p) { long x = -1; - unsigned char *buffer; + const unsigned char *buffer; - buffer = (unsigned char *) r_string(4, p); + buffer = (const unsigned char *) r_string(4, p); if (buffer != NULL) { x = buffer[0]; x |= (long)buffer[1] << 8; @@ -978,7 +983,8 @@ r_object(RFILE *p) case TYPE_FLOAT: { - char buf[256], *ptr; + char buf[256]; + const char *ptr; double dx; n = r_byte(p); if (n == EOF) { @@ -1001,9 +1007,9 @@ r_object(RFILE *p) case TYPE_BINARY_FLOAT: { - unsigned char *buf; + const unsigned char *buf; double x; - buf = (unsigned char *) r_string(8, p); + buf = (const unsigned char *) r_string(8, p); if (buf == NULL) break; x = _PyFloat_Unpack8(buf, 1); @@ -1016,7 +1022,8 @@ r_object(RFILE *p) case TYPE_COMPLEX: { - char buf[256], *ptr; + char buf[256]; + const char *ptr; Py_complex c; n = r_byte(p); if (n == EOF) { @@ -1053,15 +1060,15 @@ r_object(RFILE *p) case TYPE_BINARY_COMPLEX: { - unsigned char *buf; + const unsigned char *buf; Py_complex c; - buf = (unsigned char *) r_string(8, p); + buf = (const unsigned char *) r_string(8, p); if (buf == NULL) break; c.real = _PyFloat_Unpack8(buf, 1); if (c.real == -1.0 && PyErr_Occurred()) break; - buf = (unsigned char *) r_string(8, p); + buf = (const unsigned char *) r_string(8, p); if (buf == NULL) break; c.imag = _PyFloat_Unpack8(buf, 1); @@ -1074,7 +1081,7 @@ r_object(RFILE *p) case TYPE_STRING: { - char *ptr; + const char *ptr; n = r_long(p); if (PyErr_Occurred()) break; @@ -1119,7 +1126,7 @@ r_object(RFILE *p) } _read_ascii: { - char *ptr; + const char *ptr; ptr = r_string(n, p); if (ptr == NULL) break; @@ -1137,7 +1144,7 @@ r_object(RFILE *p) is_interned = 1; case TYPE_UNICODE: { - char *buffer; + const char *buffer; n = r_long(p); if (PyErr_Occurred()) @@ -1264,41 +1271,52 @@ r_object(RFILE *p) PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); break; } - v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); - if (type == TYPE_SET) { - R_REF(v); - } else { - /* must use delayed registration of frozensets because they must - * be init with a refcount of 1 - */ - idx = r_ref_reserve(flag, p); - if (idx < 0) - Py_CLEAR(v); /* signal error */ - } - if (v == NULL) - break; - for (i = 0; i < n; i++) { - v2 = r_object(p); - if ( v2 == NULL ) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "NULL object in marshal data for set"); - Py_DECREF(v); - v = NULL; + if (n == 0 && type == TYPE_FROZENSET) { + /* call frozenset() to get the empty frozenset singleton */ + v = PyObject_CallFunction((PyObject*)&PyFrozenSet_Type, NULL); + if (v == NULL) break; + R_REF(v); + retval = v; + } + else { + v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); + if (type == TYPE_SET) { + R_REF(v); + } else { + /* must use delayed registration of frozensets because they must + * be init with a refcount of 1 + */ + idx = r_ref_reserve(flag, p); + if (idx < 0) + Py_CLEAR(v); /* signal error */ } - if (PySet_Add(v, v2) == -1) { - Py_DECREF(v); - Py_DECREF(v2); - v = NULL; + if (v == NULL) break; + + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data for set"); + Py_DECREF(v); + v = NULL; + break; + } + if (PySet_Add(v, v2) == -1) { + Py_DECREF(v); + Py_DECREF(v2); + v = NULL; + break; + } + Py_DECREF(v2); } - Py_DECREF(v2); + if (type != TYPE_SET) + v = r_ref_insert(v, idx, flag, p); + retval = v; } - if (type != TYPE_SET) - v = r_ref_insert(v, idx, flag, p); - retval = v; break; case TYPE_CODE: |