From 6decccdafe5bff96a5fff0f553dfd02bb5f8a589 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 16:05:14 +0100 Subject: [PATCH 1/8] Issue #19437: Fix Array_subscript() of ctypes, handle Array_item() failure --- Modules/_ctypes/_ctypes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index daba2ba8eaf..9c81247ab87 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4280,6 +4280,10 @@ Array_subscript(PyObject *myself, PyObject *item) for (cur = start, i = 0; i < slicelen; cur += step, i++) { PyObject *v = Array_item(myself, cur); + if (v == NULL) { + Py_DECREF(np); + return NULL; + } PyList_SET_ITEM(np, i, v); } return np; From 1ce3f840be7823f6a898c31de19b200874a1b8a8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:26:11 +0100 Subject: [PATCH 2/8] Issue #19437: Fix convert_op_cmp() of decimal.Decimal rich comparator, handle PyObject_IsInstance() failure --- Modules/_decimal/_decimal.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index d3e394041f6..628b2f784f9 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3009,18 +3009,25 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, *wcmp = Py_NotImplemented; } } - else if (PyObject_IsInstance(w, Rational)) { - *wcmp = numerator_as_decimal(w, context); - if (*wcmp && !mpd_isspecial(MPD(v))) { - *vcmp = multiply_by_denominator(v, w, context); - if (*vcmp == NULL) { - Py_CLEAR(*wcmp); + else { + int is_instance = PyObject_IsInstance(w, Rational); + if (is_instance < 0) { + *wcmp = NULL; + return 0; + } + if (is_instance) { + *wcmp = numerator_as_decimal(w, context); + if (*wcmp && !mpd_isspecial(MPD(v))) { + *vcmp = multiply_by_denominator(v, w, context); + if (*vcmp == NULL) { + Py_CLEAR(*wcmp); + } } } - } - else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; + else { + Py_INCREF(Py_NotImplemented); + *wcmp = Py_NotImplemented; + } } if (*wcmp == NULL || *wcmp == Py_NotImplemented) { From f38a5c28e0f032e6eb9bab7c178f43f0bd2cad8d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:28:20 +0100 Subject: [PATCH 3/8] Cleanup locale.localeconv(): move Py_DECREF() closer to the error --- Modules/_localemodule.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index b196749aecc..400c3448bab 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -151,8 +151,10 @@ PyLocale_localeconv(PyObject* self) do { \ if (obj == NULL) \ goto failed; \ - if (PyDict_SetItemString(result, key, obj) < 0) \ + if (PyDict_SetItemString(result, key, obj) < 0) { \ + Py_DECREF(obj); \ goto failed; \ + } \ Py_DECREF(obj); \ } while (0) @@ -196,7 +198,6 @@ PyLocale_localeconv(PyObject* self) failed: Py_XDECREF(result); - Py_XDECREF(x); return NULL; } From 0b0c86717807bf86ba5d1d7d332529ad08179934 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:29:52 +0100 Subject: [PATCH 4/8] Issue #19437: Fix PyObject_CallFunction(), handle Py_VaBuildValue() and PyTuple_New() failure --- Objects/abstract.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Objects/abstract.c b/Objects/abstract.c index 6c7a6cd2269..91df5da6557 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2144,6 +2144,8 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...) } else args = PyTuple_New(0); + if (args == NULL) + return NULL; return call_function_tail(callable, args); } From 68b674c9d403906e91bb5a294449d90f2d747b8c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:31:43 +0100 Subject: [PATCH 5/8] Issue #19437: Fix _PyUnicode_New() (constructor of legacy string), set all attributes before checking for error. The destructor expects all attributes to be set. It is now safe to call Py_DECREF(unicode) in the constructor. --- Objects/unicodeobject.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a7ea9c8597a..208e5e3db34 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -896,6 +896,19 @@ _PyUnicode_New(Py_ssize_t length) if (unicode == NULL) return NULL; new_size = sizeof(Py_UNICODE) * ((size_t)length + 1); + + _PyUnicode_WSTR_LENGTH(unicode) = length; + _PyUnicode_HASH(unicode) = -1; + _PyUnicode_STATE(unicode).interned = 0; + _PyUnicode_STATE(unicode).kind = 0; + _PyUnicode_STATE(unicode).compact = 0; + _PyUnicode_STATE(unicode).ready = 0; + _PyUnicode_STATE(unicode).ascii = 0; + _PyUnicode_DATA_ANY(unicode) = NULL; + _PyUnicode_LENGTH(unicode) = 0; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_MALLOC(new_size); if (!_PyUnicode_WSTR(unicode)) { Py_DECREF(unicode); @@ -912,17 +925,7 @@ _PyUnicode_New(Py_ssize_t length) */ _PyUnicode_WSTR(unicode)[0] = 0; _PyUnicode_WSTR(unicode)[length] = 0; - _PyUnicode_WSTR_LENGTH(unicode) = length; - _PyUnicode_HASH(unicode) = -1; - _PyUnicode_STATE(unicode).interned = 0; - _PyUnicode_STATE(unicode).kind = 0; - _PyUnicode_STATE(unicode).compact = 0; - _PyUnicode_STATE(unicode).ready = 0; - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_DATA_ANY(unicode) = NULL; - _PyUnicode_LENGTH(unicode) = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; + assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0)); return unicode; } From 01076554b774ac7b1570d3953498263e3e9ad6ab Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:39:52 +0100 Subject: [PATCH 6/8] Issue #19433: test_capi: add tests on the size of some C types --- Modules/_testcapimodule.c | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 34b95c02a8d..7e27ec4779a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -64,6 +64,45 @@ test_config(PyObject *self) return Py_None; } +static PyObject* +test_sizeof_c_types(PyObject *self) +{ +#define CHECK_SIZEOF(EXPECTED, TYPE) \ + if (EXPECTED != sizeof(TYPE)) { \ + PyErr_Format(TestError, \ + "sizeof(%s) = %u instead of %u", \ + #TYPE, sizeof(TYPE), EXPECTED); \ + return (PyObject*)NULL; \ + } + + /* integer types */ + CHECK_SIZEOF(1, Py_UCS1); + CHECK_SIZEOF(2, Py_UCS2); + CHECK_SIZEOF(4, Py_UCS4); +#ifdef HAVE_INT32_T + CHECK_SIZEOF(4, PY_INT32_T); +#endif +#ifdef HAVE_UINT32_T + CHECK_SIZEOF(4, PY_UINT32_T); +#endif +#ifdef HAVE_INT64_T + CHECK_SIZEOF(8, PY_INT64_T); +#endif +#ifdef HAVE_UINT64_T + CHECK_SIZEOF(8, PY_UINT64_T); +#endif + + /* pointer/size types */ + CHECK_SIZEOF(sizeof(void *), size_t); + CHECK_SIZEOF(sizeof(void *), Py_ssize_t); + + Py_INCREF(Py_None); + return Py_None; + +#undef CHECK_SIZEOF +} + + static PyObject* test_list_api(PyObject *self) { @@ -2783,6 +2822,7 @@ static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, + {"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS}, {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS}, {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, From f866f97ca8fed17cb10c0fd06b65b75b33843ff9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:59:31 +0100 Subject: [PATCH 7/8] Issue #19433: test_capi: check signness of some C types --- Modules/_testcapimodule.c | 44 ++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7e27ec4779a..33624542ac5 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -67,38 +67,62 @@ test_config(PyObject *self) static PyObject* test_sizeof_c_types(PyObject *self) { -#define CHECK_SIZEOF(EXPECTED, TYPE) \ +#define CHECK_SIZEOF(TYPE, EXPECTED) \ if (EXPECTED != sizeof(TYPE)) { \ PyErr_Format(TestError, \ "sizeof(%s) = %u instead of %u", \ #TYPE, sizeof(TYPE), EXPECTED); \ return (PyObject*)NULL; \ } +#define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0) +#define CHECK_SIGNNESS(TYPE, SIGNED) \ + if (IS_SIGNED(TYPE) != SIGNED) { \ + PyErr_Format(TestError, \ + "%s signness is, instead of %i", \ + #TYPE, IS_SIGNED(TYPE), SIGNED); \ + return (PyObject*)NULL; \ + } /* integer types */ - CHECK_SIZEOF(1, Py_UCS1); - CHECK_SIZEOF(2, Py_UCS2); - CHECK_SIZEOF(4, Py_UCS4); + CHECK_SIZEOF(Py_UCS1, 1); + CHECK_SIZEOF(Py_UCS2, 2); + CHECK_SIZEOF(Py_UCS4, 4); + CHECK_SIGNNESS(Py_UCS1, 0); + CHECK_SIGNNESS(Py_UCS2, 0); + CHECK_SIGNNESS(Py_UCS4, 0); #ifdef HAVE_INT32_T - CHECK_SIZEOF(4, PY_INT32_T); + CHECK_SIZEOF(PY_INT32_T, 4); + CHECK_SIGNNESS(PY_INT32_T, 1); #endif #ifdef HAVE_UINT32_T - CHECK_SIZEOF(4, PY_UINT32_T); + CHECK_SIZEOF(PY_UINT32_T, 4); + CHECK_SIGNNESS(PY_UINT32_T, 0); #endif #ifdef HAVE_INT64_T - CHECK_SIZEOF(8, PY_INT64_T); + CHECK_SIZEOF(PY_INT64_T, 8); + CHECK_SIGNNESS(PY_INT64_T, 1); #endif #ifdef HAVE_UINT64_T - CHECK_SIZEOF(8, PY_UINT64_T); + CHECK_SIZEOF(PY_UINT64_T, 8); + CHECK_SIGNNESS(PY_UINT64_T, 0); #endif /* pointer/size types */ - CHECK_SIZEOF(sizeof(void *), size_t); - CHECK_SIZEOF(sizeof(void *), Py_ssize_t); + CHECK_SIZEOF(size_t, sizeof(void *)); + CHECK_SIGNNESS(size_t, 0); + CHECK_SIZEOF(Py_ssize_t, sizeof(void *)); + CHECK_SIGNNESS(Py_ssize_t, 1); + + CHECK_SIZEOF(Py_uintptr_t, sizeof(void *)); + CHECK_SIGNNESS(Py_uintptr_t, 0); + CHECK_SIZEOF(Py_intptr_t, sizeof(void *)); + CHECK_SIGNNESS(Py_intptr_t, 1); Py_INCREF(Py_None); return Py_None; +#undef IS_SIGNED +#undef CHECK_SIGNESS #undef CHECK_SIZEOF } From 34f7383d7ae1d3d040b3978680b9498c4ed150f5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 20:33:14 +0100 Subject: [PATCH 8/8] Issue #19437: Fix dec_format() of the _decimal module, handle dec_strdup() failure (memory allocation failure): raise a MemoryError exception --- Modules/_decimal/_decimal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 628b2f784f9..6f9e9def474 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3187,6 +3187,7 @@ dec_format(PyObject *dec, PyObject *args) replace_fillchar = 1; fmt = dec_strdup(fmt, size); if (fmt == NULL) { + PyErr_NoMemory(); return NULL; } fmt[0] = '_';