From a992e11fe36b8461d3064a7cc37552a44c7dd022 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 19:26:11 +0100 Subject: [PATCH 1/5] 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 ac470854b8121ce4b5dc9388c9ad084f5359b2aa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 20:33:14 +0100 Subject: [PATCH 2/5] 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] = '_'; From a0fd1f5a187a001650ade75fbfe97418705beff8 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 8 Nov 2013 17:48:58 +0100 Subject: [PATCH 3/5] Change style to match the surrounding code (no early returns). --- Modules/_decimal/_decimal.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 6f9e9def474..aec3949c790 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3010,12 +3010,11 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - int is_instance = PyObject_IsInstance(w, Rational); - if (is_instance < 0) { + int is_rational = PyObject_IsInstance(w, Rational); + if (is_rational < 0) { *wcmp = NULL; - return 0; } - if (is_instance) { + else if (is_rational > 0) { *wcmp = numerator_as_decimal(w, context); if (*wcmp && !mpd_isspecial(MPD(v))) { *vcmp = multiply_by_denominator(v, w, context); From 2fdf4e7b9b30e2e7cae87a01334fca8e6b49eff2 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 8 Nov 2013 18:05:02 +0100 Subject: [PATCH 4/5] Move PyErr_NoMemory() closer to the failure. --- Modules/_decimal/_decimal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index aec3949c790..06c2c395b87 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3108,6 +3108,7 @@ dec_strdup(const char *src, Py_ssize_t size) { char *dest = PyMem_Malloc(size+1); if (dest == NULL) { + PyErr_NoMemory(); return NULL; } @@ -3186,7 +3187,6 @@ dec_format(PyObject *dec, PyObject *args) replace_fillchar = 1; fmt = dec_strdup(fmt, size); if (fmt == NULL) { - PyErr_NoMemory(); return NULL; } fmt[0] = '_'; From 2915933f4f95f2c3fe12074031585e15e9285d52 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 8 Nov 2013 20:18:09 +0100 Subject: [PATCH 5/5] Valgrind: suppress false positive in _PyOS_GetOpt (getopt.c:84) (Invalid read of size 8: wcscmp (wcscmp.S:464)) --- Misc/valgrind-python.supp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Misc/valgrind-python.supp b/Misc/valgrind-python.supp index 81a07c9f45a..e612555b6d3 100644 --- a/Misc/valgrind-python.supp +++ b/Misc/valgrind-python.supp @@ -456,6 +456,15 @@ fun:PyUnicode_FSConverter } +{ + wcscmp_false_positive + Memcheck:Addr8 + fun:wcscmp + fun:_PyOS_GetOpt + fun:Py_Main + fun:main +} + # Additional suppressions for the unified decimal tests: { test_decimal