diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_codecsmodule.c | 4 | ||||
-rw-r--r-- | Modules/_datetimemodule.c | 7 | ||||
-rw-r--r-- | Modules/_decimal/libmpdec/typearith.h | 32 | ||||
-rw-r--r-- | Modules/_decimal/libmpdec/umodarith.h | 156 | ||||
-rw-r--r-- | Modules/_decimal/tests/bench.py | 9 | ||||
-rw-r--r-- | Modules/_elementtree.c | 273 | ||||
-rw-r--r-- | Modules/_randommodule.c | 3 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 2 | ||||
-rw-r--r-- | Modules/arraymodule.c | 12 | ||||
-rw-r--r-- | Modules/audioop.c | 4 | ||||
-rw-r--r-- | Modules/zipimport.c | 43 |
11 files changed, 293 insertions, 252 deletions
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 7818f9a..40037b1 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -177,12 +177,12 @@ escape_encode(PyObject *self, return NULL; size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + if (size > PY_SSIZE_T_MAX / 4) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); return NULL; } + newsize = 4*size; v = PyBytes_FromStringAndSize(NULL, newsize); if (v == NULL) { diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 01c85d1..873d46f 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1265,14 +1265,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, assert(ptoappend != NULL); assert(ntoappend > 0); while (usednew + ntoappend > totalnew) { - size_t bigger = totalnew << 1; - if ((bigger >> 1) != totalnew) { /* overflow */ + if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ PyErr_NoMemory(); goto Done; } - if (_PyBytes_Resize(&newfmt, bigger) < 0) + totalnew <<= 1; + if (_PyBytes_Resize(&newfmt, totalnew) < 0) goto Done; - totalnew = bigger; pnew = PyBytes_AsString(newfmt) + usednew; } memcpy(pnew, ptoappend, ntoappend); diff --git a/Modules/_decimal/libmpdec/typearith.h b/Modules/_decimal/libmpdec/typearith.h index eeba8dd..614812c 100644 --- a/Modules/_decimal/libmpdec/typearith.h +++ b/Modules/_decimal/libmpdec/typearith.h @@ -207,10 +207,10 @@ _mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) { mpd_uint_t h, l; - asm ( "mulq %3\n\t" - : "=d" (h), "=a" (l) - : "%a" (a), "rm" (b) - : "cc" + __asm__ ( "mulq %3\n\t" + : "=d" (h), "=a" (l) + : "%a" (a), "rm" (b) + : "cc" ); *hi = h; @@ -223,10 +223,10 @@ _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, { mpd_uint_t qq, rr; - asm ( "divq %4\n\t" - : "=a" (qq), "=d" (rr) - : "a" (lo), "d" (hi), "rm" (d) - : "cc" + __asm__ ( "divq %4\n\t" + : "=a" (qq), "=d" (rr) + : "a" (lo), "d" (hi), "rm" (d) + : "cc" ); *q = qq; @@ -464,10 +464,10 @@ _mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) { mpd_uint_t h, l; - asm ( "mull %3\n\t" - : "=d" (h), "=a" (l) - : "%a" (a), "rm" (b) - : "cc" + __asm__ ( "mull %3\n\t" + : "=d" (h), "=a" (l) + : "%a" (a), "rm" (b) + : "cc" ); *hi = h; @@ -480,10 +480,10 @@ _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, { mpd_uint_t qq, rr; - asm ( "divl %4\n\t" - : "=a" (qq), "=d" (rr) - : "a" (lo), "d" (hi), "rm" (d) - : "cc" + __asm__ ( "divl %4\n\t" + : "=a" (qq), "=d" (rr) + : "a" (lo), "d" (hi), "rm" (d) + : "cc" ); *q = qq; diff --git a/Modules/_decimal/libmpdec/umodarith.h b/Modules/_decimal/libmpdec/umodarith.h index 06cde0a..a6aeceb 100644 --- a/Modules/_decimal/libmpdec/umodarith.h +++ b/Modules/_decimal/libmpdec/umodarith.h @@ -402,22 +402,22 @@ ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod) { mpd_uint_t retval; - asm ( - "fildl %2\n\t" - "fildl %1\n\t" - "fmulp %%st, %%st(1)\n\t" - "fldt (%4)\n\t" - "fmul %%st(1), %%st\n\t" - "flds %5\n\t" - "fadd %%st, %%st(1)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fldl (%3)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fistpl %0\n\t" - : "=m" (retval) - : "m" (a), "m" (b), "r" (dmod), "r" (dinvmod), "m" (MPD_TWO63) - : "st", "memory" + __asm__ ( + "fildl %2\n\t" + "fildl %1\n\t" + "fmulp %%st, %%st(1)\n\t" + "fldt (%4)\n\t" + "fmul %%st(1), %%st\n\t" + "flds %5\n\t" + "fadd %%st, %%st(1)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fldl (%3)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fistpl %0\n\t" + : "=m" (retval) + : "m" (a), "m" (b), "r" (dmod), "r" (dinvmod), "m" (MPD_TWO63) + : "st", "memory" ); return retval; @@ -432,33 +432,33 @@ static inline void ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w, double *dmod, uint32_t *dinvmod) { - asm ( - "fildl %2\n\t" - "fildl (%1)\n\t" - "fmul %%st(1), %%st\n\t" - "fxch %%st(1)\n\t" - "fildl (%0)\n\t" - "fmulp %%st, %%st(1) \n\t" - "fldt (%4)\n\t" - "flds %5\n\t" - "fld %%st(2)\n\t" - "fmul %%st(2)\n\t" - "fadd %%st(1)\n\t" - "fsub %%st(1)\n\t" - "fmull (%3)\n\t" - "fsubrp %%st, %%st(3)\n\t" - "fxch %%st(2)\n\t" - "fistpl (%0)\n\t" - "fmul %%st(2)\n\t" - "fadd %%st(1)\n\t" - "fsubp %%st, %%st(1)\n\t" - "fmull (%3)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fistpl (%1)\n\t" - : : "r" (a0), "r" (a1), "m" (w), - "r" (dmod), "r" (dinvmod), - "m" (MPD_TWO63) - : "st", "memory" + __asm__ ( + "fildl %2\n\t" + "fildl (%1)\n\t" + "fmul %%st(1), %%st\n\t" + "fxch %%st(1)\n\t" + "fildl (%0)\n\t" + "fmulp %%st, %%st(1) \n\t" + "fldt (%4)\n\t" + "flds %5\n\t" + "fld %%st(2)\n\t" + "fmul %%st(2)\n\t" + "fadd %%st(1)\n\t" + "fsub %%st(1)\n\t" + "fmull (%3)\n\t" + "fsubrp %%st, %%st(3)\n\t" + "fxch %%st(2)\n\t" + "fistpl (%0)\n\t" + "fmul %%st(2)\n\t" + "fadd %%st(1)\n\t" + "fsubp %%st, %%st(1)\n\t" + "fmull (%3)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fistpl (%1)\n\t" + : : "r" (a0), "r" (a1), "m" (w), + "r" (dmod), "r" (dinvmod), + "m" (MPD_TWO63) + : "st", "memory" ); } @@ -471,41 +471,41 @@ static inline void ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, double *dmod, uint32_t *dinvmod) { - asm ( - "fildl %3\n\t" - "fildl (%2)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fildl %1\n\t" - "fildl (%0)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fldt (%5)\n\t" - "fld %%st(2)\n\t" - "fmul %%st(1), %%st\n\t" - "fxch %%st(1)\n\t" - "fmul %%st(2), %%st\n\t" - "flds %6\n\t" - "fldl (%4)\n\t" - "fxch %%st(3)\n\t" - "fadd %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fadd %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fsub %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fsubp %%st, %%st(1)\n\t" - "fxch %%st(1)\n\t" - "fmul %%st(2), %%st\n\t" - "fxch %%st(1)\n\t" - "fmulp %%st, %%st(2)\n\t" - "fsubrp %%st, %%st(3)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fxch %%st(1)\n\t" - "fistpl (%2)\n\t" - "fistpl (%0)\n\t" - : : "r" (a0), "m" (b0), "r" (a1), "m" (b1), - "r" (dmod), "r" (dinvmod), - "m" (MPD_TWO63) - : "st", "memory" + __asm__ ( + "fildl %3\n\t" + "fildl (%2)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fildl %1\n\t" + "fildl (%0)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fldt (%5)\n\t" + "fld %%st(2)\n\t" + "fmul %%st(1), %%st\n\t" + "fxch %%st(1)\n\t" + "fmul %%st(2), %%st\n\t" + "flds %6\n\t" + "fldl (%4)\n\t" + "fxch %%st(3)\n\t" + "fadd %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fadd %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fsub %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fsubp %%st, %%st(1)\n\t" + "fxch %%st(1)\n\t" + "fmul %%st(2), %%st\n\t" + "fxch %%st(1)\n\t" + "fmulp %%st, %%st(2)\n\t" + "fsubrp %%st, %%st(3)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fxch %%st(1)\n\t" + "fistpl (%2)\n\t" + "fistpl (%0)\n\t" + : : "r" (a0), "m" (b0), "r" (a1), "m" (b1), + "r" (dmod), "r" (dinvmod), + "m" (MPD_TWO63) + : "st", "memory" ); } /* END PPRO GCC ASM */ diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 7ab6b44..7e4a210 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -18,8 +18,13 @@ except ImportError: C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) - -# Pi function from the decimal.py documentation +# +# NOTE: This is the pi function from the decimal documentation, modified +# for benchmarking purposes. Since floats do not have a context, the higher +# intermediate precision from the original is NOT used, so the modified +# algorithm only gives an approximation to the correctly rounded result. +# For serious use, refer to the documentation or the appropriate literature. +# def pi_float(): """native float""" lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24 diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 43f9d9b..0c8abcf 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -123,17 +123,11 @@ deepcopy(PyObject* object, PyObject* memo) return NULL; } - args = PyTuple_New(2); + args = PyTuple_Pack(2, object, memo); if (!args) return NULL; - - Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object); - Py_INCREF(memo); PyTuple_SET_ITEM(args, 1, (PyObject*) memo); - result = PyObject_CallObject(elementtree_deepcopy_obj, args); - Py_DECREF(args); - return result; } @@ -141,48 +135,16 @@ LOCAL(PyObject*) list_join(PyObject* list) { /* join list elements (destroying the list in the process) */ - PyObject* joiner; - PyObject* function; - PyObject* args; PyObject* result; - switch (PyList_GET_SIZE(list)) { - case 0: - Py_DECREF(list); - return PyBytes_FromString(""); - case 1: - result = PyList_GET_ITEM(list, 0); - Py_INCREF(result); - Py_DECREF(list); - return result; - } - - /* two or more elements: slice out a suitable separator from the - first member, and use that to join the entire list */ - - joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0); + joiner = PyUnicode_FromStringAndSize("", 0); if (!joiner) return NULL; - - function = PyObject_GetAttrString(joiner, "join"); - if (!function) { - Py_DECREF(joiner); - return NULL; - } - - args = PyTuple_New(1); - if (!args) - return NULL; - - PyTuple_SET_ITEM(args, 0, list); - - result = PyObject_CallObject(function, args); - - Py_DECREF(args); /* also removes list */ - Py_DECREF(function); + result = PyUnicode_Join(joiner, list); Py_DECREF(joiner); - + if (result) + Py_DECREF(list); return result; } @@ -399,6 +361,7 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (kwds) { if (PyDict_Update(attrib, kwds) < 0) { + Py_DECREF(attrib); return -1; } } @@ -407,38 +370,34 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) attrib = get_attrib_from_keywords(kwds); if (!attrib) return -1; - } else { - /* no attrib arg, no kwds, so no attributes */ - Py_INCREF(Py_None); - attrib = Py_None; } self_elem = (ElementObject *)self; - if (attrib != Py_None && !is_empty_dict(attrib)) { + if (attrib != NULL && !is_empty_dict(attrib)) { if (create_extra(self_elem, attrib) < 0) { - PyObject_Del(self_elem); + Py_DECREF(attrib); return -1; } } /* We own a reference to attrib here and it's no longer needed. */ - Py_DECREF(attrib); + Py_XDECREF(attrib); /* Replace the objects already pointed to by tag, text and tail. */ tmp = self_elem->tag; - self_elem->tag = tag; Py_INCREF(tag); + self_elem->tag = tag; Py_DECREF(tmp); tmp = self_elem->text; - self_elem->text = Py_None; Py_INCREF(Py_None); + self_elem->text = Py_None; Py_DECREF(JOIN_OBJ(tmp)); tmp = self_elem->tail; - self_elem->tail = Py_None; Py_INCREF(Py_None); + self_elem->tail = Py_None; Py_DECREF(JOIN_OBJ(tmp)); return 0; @@ -520,11 +479,11 @@ element_get_attrib(ElementObject* self) PyObject* res = self->extra->attrib; if (res == Py_None) { - Py_DECREF(res); /* create missing dictionary */ res = PyDict_New(); if (!res) return NULL; + Py_DECREF(Py_None); self->extra->attrib = res; } @@ -824,7 +783,7 @@ element_deepcopy(ElementObject* self, PyObject* args) } /* add object to memo dictionary (so deepcopy won't visit it again) */ - id = PyLong_FromLong((Py_uintptr_t) self); + id = PyLong_FromSsize_t((Py_uintptr_t) self); if (!id) goto error; @@ -2038,8 +1997,8 @@ typedef struct { PyObject *root; /* root node (first created node) */ - ElementObject *this; /* current node */ - ElementObject *last; /* most recently created node */ + PyObject *this; /* current node */ + PyObject *last; /* most recently created node */ PyObject *data; /* data collector (string or list), or NULL */ @@ -2071,9 +2030,9 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->root = NULL; Py_INCREF(Py_None); - t->this = (ElementObject *)Py_None; + t->this = Py_None; Py_INCREF(Py_None); - t->last = (ElementObject *)Py_None; + t->last = Py_None; t->data = NULL; t->element_factory = NULL; @@ -2081,6 +2040,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!t->stack) { Py_DECREF(t->this); Py_DECREF(t->last); + Py_DECREF((PyObject *) t); return NULL; } t->index = 0; @@ -2098,6 +2058,7 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = {"element_factory", 0}; PyObject *element_factory = NULL; TreeBuilderObject *self_tb = (TreeBuilderObject *)self; + PyObject *tmp; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:TreeBuilder", kwlist, &element_factory)) { @@ -2106,8 +2067,9 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds) if (element_factory) { Py_INCREF(element_factory); - Py_XDECREF(self_tb->element_factory); + tmp = self_tb->element_factory; self_tb->element_factory = element_factory; + Py_XDECREF(tmp); } return 0; @@ -2128,17 +2090,17 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) static int treebuilder_gc_clear(TreeBuilderObject *self) { - Py_XDECREF(self->end_ns_event_obj); - Py_XDECREF(self->start_ns_event_obj); - Py_XDECREF(self->end_event_obj); - Py_XDECREF(self->start_event_obj); - Py_XDECREF(self->events); - Py_DECREF(self->stack); - Py_XDECREF(self->data); - Py_DECREF(self->last); - Py_DECREF(self->this); + Py_CLEAR(self->end_ns_event_obj); + Py_CLEAR(self->start_ns_event_obj); + Py_CLEAR(self->end_event_obj); + Py_CLEAR(self->start_event_obj); + Py_CLEAR(self->events); + Py_CLEAR(self->stack); + Py_CLEAR(self->data); + Py_CLEAR(self->last); + Py_CLEAR(self->this); Py_CLEAR(self->element_factory); - Py_XDECREF(self->root); + Py_CLEAR(self->root); return 0; } @@ -2151,6 +2113,64 @@ treebuilder_dealloc(TreeBuilderObject *self) } /* -------------------------------------------------------------------- */ +/* helpers for handling of arbitrary element-like objects */ + +static int +treebuilder_set_element_text_or_tail(PyObject *element, PyObject *data, + PyObject **dest, _Py_Identifier *name) +{ + if (Element_CheckExact(element)) { + Py_DECREF(JOIN_OBJ(*dest)); + *dest = JOIN_SET(data, PyList_CheckExact(data)); + return 0; + } + else { + PyObject *joined = list_join(data); + int r; + if (joined == NULL) + return -1; + r = _PyObject_SetAttrId(element, name, joined); + Py_DECREF(joined); + return r; + } +} + +/* These two functions steal a reference to data */ +static int +treebuilder_set_element_text(PyObject *element, PyObject *data) +{ + _Py_IDENTIFIER(text); + return treebuilder_set_element_text_or_tail( + element, data, &((ElementObject *) element)->text, &PyId_text); +} + +static int +treebuilder_set_element_tail(PyObject *element, PyObject *data) +{ + _Py_IDENTIFIER(tail); + return treebuilder_set_element_text_or_tail( + element, data, &((ElementObject *) element)->tail, &PyId_tail); +} + +static int +treebuilder_add_subelement(PyObject *element, PyObject *child) +{ + _Py_IDENTIFIER(append); + if (Element_CheckExact(element)) { + ElementObject *elem = (ElementObject *) element; + return element_add_subelement(elem, child); + } + else { + PyObject *res; + res = _PyObject_CallMethodId(element, &PyId_append, "O", child); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; + } +} + +/* -------------------------------------------------------------------- */ /* handlers */ LOCAL(PyObject*) @@ -2162,15 +2182,12 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, if (self->data) { if (self->this == self->last) { - Py_DECREF(JOIN_OBJ(self->last->text)); - self->last->text = JOIN_SET( - self->data, PyList_CheckExact(self->data) - ); - } else { - Py_DECREF(JOIN_OBJ(self->last->tail)); - self->last->tail = JOIN_SET( - self->data, PyList_CheckExact(self->data) - ); + if (treebuilder_set_element_text(self->last, self->data)) + return NULL; + } + else { + if (treebuilder_set_element_tail(self->last, self->data)) + return NULL; } self->data = NULL; } @@ -2184,10 +2201,10 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, return NULL; } - this = (PyObject*) self->this; + this = self->this; if (this != Py_None) { - if (element_add_subelement((ElementObject*) this, node) < 0) + if (treebuilder_add_subelement(this, node) < 0) goto error; } else { if (self->root) { @@ -2213,19 +2230,17 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, Py_DECREF(this); Py_INCREF(node); - self->this = (ElementObject*) node; + self->this = node; Py_DECREF(self->last); Py_INCREF(node); - self->last = (ElementObject*) node; + self->last = node; if (self->start_event_obj) { PyObject* res; PyObject* action = self->start_event_obj; - res = PyTuple_New(2); + res = PyTuple_Pack(2, action, node); if (res) { - Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action); - Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node); PyList_Append(self->events, res); Py_DECREF(res); } else @@ -2243,7 +2258,7 @@ LOCAL(PyObject*) treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) { if (!self->data) { - if (self->last == (ElementObject*) Py_None) { + if (self->last == Py_None) { /* ignore calls to data before the first call to start */ Py_RETURN_NONE; } @@ -2253,6 +2268,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) /* more than one item; use a list to collect items */ if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { + /* XXX this code path unused in Python 3? */ /* expat often generates single character data sections; handle the most common case by resizing the existing string... */ Py_ssize_t size = PyBytes_GET_SIZE(self->data); @@ -2282,15 +2298,11 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) if (self->data) { if (self->this == self->last) { - Py_DECREF(JOIN_OBJ(self->last->text)); - self->last->text = JOIN_SET( - self->data, PyList_CheckExact(self->data) - ); + if (treebuilder_set_element_text(self->last, self->data)) + return NULL; } else { - Py_DECREF(JOIN_OBJ(self->last->tail)); - self->last->tail = JOIN_SET( - self->data, PyList_CheckExact(self->data) - ); + if (treebuilder_set_element_tail(self->last, self->data)) + return NULL; } self->data = NULL; } @@ -2310,17 +2322,15 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) Py_DECREF(self->last); - self->last = (ElementObject*) self->this; - self->this = (ElementObject*) item; + self->last = self->this; + self->this = item; if (self->end_event_obj) { PyObject* res; PyObject* action = self->end_event_obj; PyObject* node = (PyObject*) self->last; - res = PyTuple_New(2); + res = PyTuple_Pack(2, action, node); if (res) { - Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action); - Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node); PyList_Append(self->events, res); Py_DECREF(res); } else @@ -2366,8 +2376,12 @@ treebuilder_handle_namespace(TreeBuilderObject* self, int start, PyTuple_SET_ITEM(res, 1, parcel); PyList_Append(self->events, res); Py_DECREF(res); - } else + } + else { + Py_DECREF(action); + Py_DECREF(parcel); PyErr_Clear(); /* FIXME: propagate error */ + } } /* -------------------------------------------------------------------- */ @@ -2526,7 +2540,7 @@ makeuniversal(XMLParserObject* self, const char* string) /* convert a UTF-8 tag/attribute name from the expat parser to a universal name string */ - int size = strlen(string); + Py_ssize_t size = (Py_ssize_t) strlen(string); PyObject* key; PyObject* value; @@ -2545,7 +2559,7 @@ makeuniversal(XMLParserObject* self, const char* string) PyObject* tag; char* p; - int i; + Py_ssize_t i; /* look for namespace separator */ for (i = 0; i < size; i++) @@ -2717,13 +2731,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, attrib_in += 2; } } else { - Py_INCREF(Py_None); - attrib = Py_None; - } - - /* If we get None, pass an empty dictionary on */ - if (attrib == Py_None) { - Py_DECREF(attrib); + /* Pass an empty dictionary on */ attrib = PyDict_New(); if (!attrib) return; @@ -3015,14 +3023,14 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds) self_xp->names = PyDict_New(); if (!self_xp->names) { - Py_XDECREF(self_xp->entity); + Py_CLEAR(self_xp->entity); return -1; } self_xp->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); if (!self_xp->parser) { - Py_XDECREF(self_xp->entity); - Py_XDECREF(self_xp->names); + Py_CLEAR(self_xp->entity); + Py_CLEAR(self_xp->names); PyErr_NoMemory(); return -1; } @@ -3032,8 +3040,8 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds) } else { target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); if (!target) { - Py_XDECREF(self_xp->entity); - Py_XDECREF(self_xp->names); + Py_CLEAR(self_xp->entity); + Py_CLEAR(self_xp->names); EXPAT(ParserFree)(self_xp->parser); return -1; } @@ -3109,17 +3117,17 @@ xmlparser_gc_clear(XMLParserObject *self) { EXPAT(ParserFree)(self->parser); - Py_XDECREF(self->handle_close); - Py_XDECREF(self->handle_pi); - Py_XDECREF(self->handle_comment); - Py_XDECREF(self->handle_end); - Py_XDECREF(self->handle_data); - Py_XDECREF(self->handle_start); - Py_XDECREF(self->handle_doctype); + Py_CLEAR(self->handle_close); + Py_CLEAR(self->handle_pi); + Py_CLEAR(self->handle_comment); + Py_CLEAR(self->handle_end); + Py_CLEAR(self->handle_data); + Py_CLEAR(self->handle_start); + Py_CLEAR(self->handle_doctype); - Py_XDECREF(self->target); - Py_XDECREF(self->entity); - Py_XDECREF(self->names); + Py_CLEAR(self->target); + Py_CLEAR(self->entity); + Py_CLEAR(self->names); return 0; } @@ -3227,17 +3235,12 @@ xmlparser_parse(XMLParserObject* self, PyObject* args) break; } temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); + Py_DECREF(buffer); if (!temp) { /* Propagate exception from PyUnicode_AsEncodedString */ - Py_DECREF(buffer); Py_DECREF(reader); return NULL; } - - /* Here we no longer need the original buffer since it contains - * unicode. Make it point to the encoded bytes object. - */ - Py_DECREF(buffer); buffer = temp; } else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { @@ -3307,10 +3310,10 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args) target->events = events; /* clear out existing events */ - Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL; - Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL; - Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL; - Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL; + Py_CLEAR(target->start_event_obj); + Py_CLEAR(target->end_event_obj); + Py_CLEAR(target->start_ns_event_obj); + Py_CLEAR(target->end_ns_event_obj); if (event_set == Py_None) { /* default is "end" only */ diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 421a0d8..6540ab9 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -284,7 +284,8 @@ random_seed(RandomObject *self, PyObject *args) n = newn; if (keyused >= keymax) { unsigned long bigger = keymax << 1; - if ((bigger >> 1) != keymax) { + if ((bigger >> 1) != keymax || + bigger > PY_SSIZE_T_MAX / sizeof(*key)) { PyErr_NoMemory(); goto Done; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ce58651..ab11f51 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1238,7 +1238,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) o = PySequence_Fast_GET_ITEM(sub_keywords, i); if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { PyErr_Format(PyExc_ValueError, - "parse_tuple_and_keywords: could not convert keywords[%s] to narrow string", i); + "parse_tuple_and_keywords: could not convert keywords[%zd] to narrow string", i); goto exit; } keywords[i] = PyBytes_AS_STRING(converted[i]); diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 04eb67c..3f5aa8b 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -483,11 +483,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) return NULL; } - nbytes = size * descr->itemsize; /* Check for overflow */ - if (nbytes / descr->itemsize != (size_t)size) { + if (size > PY_SSIZE_T_MAX / descr->itemsize) { return PyErr_NoMemory(); } + nbytes = size * descr->itemsize; op = (arrayobject *) type->tp_alloc(type, 0); if (op == NULL) { return NULL; @@ -1251,11 +1251,15 @@ array_fromfile(arrayobject *self, PyObject *args) if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n)) return NULL; - nbytes = n * itemsize; - if (nbytes < 0 || nbytes/itemsize != n) { + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + if (n > PY_SSIZE_T_MAX / itemsize) { PyErr_NoMemory(); return NULL; } + nbytes = n * itemsize; b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes); if (b == NULL) diff --git a/Modules/audioop.c b/Modules/audioop.c index 0375e4e..2bca391 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1108,8 +1108,7 @@ audioop_ratecv(PyObject *self, PyObject *args) PyErr_SetString(AudioopError, "# of channels should be >= 1"); return NULL; } - bytes_per_frame = size * nchannels; - if (bytes_per_frame / nchannels != size) { + if (size > INT_MAX / nchannels) { /* This overflow test is rigorously correct because both multiplicands are >= 1. Use the argument names from the docs for the error msg. */ @@ -1117,6 +1116,7 @@ audioop_ratecv(PyObject *self, PyObject *args) "width * nchannels too big for a C int"); return NULL; } + bytes_per_frame = size * nchannels; if (weightA < 1 || weightB < 0) { PyErr_SetString(AudioopError, "weightA should be >= 1, weightB should be >= 0"); diff --git a/Modules/zipimport.c b/Modules/zipimport.c index ccbc784..2feb2a8 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -875,7 +875,12 @@ read_directory(PyObject *archive) PyErr_Format(ZipImportError, "can't open Zip file: %R", archive); return NULL; } - fseek(fp, -22, SEEK_END); + + if (fseek(fp, -22, SEEK_END) == -1) { + fclose(fp); + PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); + return NULL; + } header_position = ftell(fp); if (fread(endof_central_dir, 1, 22, fp) != 22) { fclose(fp); @@ -904,11 +909,13 @@ read_directory(PyObject *archive) PyObject *t; int err; - fseek(fp, header_offset, 0); /* Start of file header */ + if (fseek(fp, header_offset, 0) == -1) /* Start of file header */ + goto fseek_error; l = PyMarshal_ReadLongFromFile(fp); if (l != 0x02014B50) break; /* Bad: Central Dir File Header */ - fseek(fp, header_offset + 8, 0); + if (fseek(fp, header_offset + 8, 0) == -1) + goto fseek_error; flags = (unsigned short)PyMarshal_ReadShortFromFile(fp); compress = PyMarshal_ReadShortFromFile(fp); time = PyMarshal_ReadShortFromFile(fp); @@ -920,7 +927,8 @@ read_directory(PyObject *archive) header_size = 46 + name_size + PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp); - fseek(fp, header_offset + 42, 0); + if (fseek(fp, header_offset + 42, 0) == -1) + goto fseek_error; file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset; if (name_size > MAXPATHLEN) name_size = MAXPATHLEN; @@ -980,6 +988,12 @@ read_directory(PyObject *archive) PySys_FormatStderr("# zipimport: found %ld names in %R\n", count, archive); return files; +fseek_error: + fclose(fp); + Py_XDECREF(files); + Py_XDECREF(nameobj); + PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); + return NULL; error: fclose(fp); Py_XDECREF(files); @@ -1050,7 +1064,12 @@ get_data(PyObject *archive, PyObject *toc_entry) } /* Check to make sure the local file header is correct */ - fseek(fp, file_offset, 0); + if (fseek(fp, file_offset, 0) == -1) { + fclose(fp); + PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); + return NULL; + } + l = PyMarshal_ReadLongFromFile(fp); if (l != 0x04034B50) { /* Bad: Local File Header */ @@ -1060,7 +1079,12 @@ get_data(PyObject *archive, PyObject *toc_entry) fclose(fp); return NULL; } - fseek(fp, file_offset + 26, 0); + if (fseek(fp, file_offset + 26, 0) == -1) { + fclose(fp); + PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); + return NULL; + } + l = 30 + PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp); /* local header size */ file_offset += l; /* Start of file data */ @@ -1077,8 +1101,13 @@ get_data(PyObject *archive, PyObject *toc_entry) buf = PyBytes_AsString(raw_data); err = fseek(fp, file_offset, 0); - if (err == 0) + if (err == 0) { bytes_read = fread(buf, 1, data_size, fp); + } else { + fclose(fp); + PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); + return NULL; + } fclose(fp); if (err || bytes_read != data_size) { PyErr_SetString(PyExc_IOError, |