summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_codecsmodule.c4
-rw-r--r--Modules/_datetimemodule.c7
-rw-r--r--Modules/_decimal/libmpdec/typearith.h32
-rw-r--r--Modules/_decimal/libmpdec/umodarith.h156
-rw-r--r--Modules/_decimal/tests/bench.py9
-rw-r--r--Modules/_elementtree.c273
-rw-r--r--Modules/_randommodule.c3
-rw-r--r--Modules/_testcapimodule.c2
-rw-r--r--Modules/arraymodule.c12
-rw-r--r--Modules/audioop.c4
-rw-r--r--Modules/zipimport.c43
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,