diff options
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/_json.c | 35 | ||||
-rw-r--r-- | Modules/threadmodule.c | 18 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 10 | ||||
-rw-r--r-- | Objects/setobject.c | 17 | ||||
-rw-r--r-- | Python/pythonrun.c | 43 |
6 files changed, 83 insertions, 44 deletions
@@ -10,6 +10,10 @@ What's New in Python 2.7.11? Core and Builtins ----------------- +- Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(), + PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains() + to check for and handle errors correctly. + - Issue #4753: On compilers where it is supported, use "computed gotos" for bytecode dispatch in the interpreter. This improves interpretation performance. diff --git a/Modules/_json.c b/Modules/_json.c index c913409..3349b0c 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -874,6 +874,9 @@ _parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ int strict = PyObject_IsTrue(s->strict); Py_ssize_t next_idx; + if (strict < 0) + return NULL; + pairs = PyList_New(0); if (pairs == NULL) return NULL; @@ -997,6 +1000,9 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss int strict = PyObject_IsTrue(s->strict); Py_ssize_t next_idx; + if (strict < 0) + return NULL; + pairs = PyList_New(0); if (pairs == NULL) return NULL; @@ -1466,6 +1472,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n Returns a new PyObject representation of the term. */ PyObject *res; + int strict; char *str = PyString_AS_STRING(pystr); Py_ssize_t length = PyString_GET_SIZE(pystr); if (idx < 0) { @@ -1479,10 +1486,11 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n switch (str[idx]) { case '"': /* string */ + strict = PyObject_IsTrue(s->strict); + if (strict < 0) + return NULL; return scanstring_str(pystr, idx + 1, - PyString_AS_STRING(s->encoding), - PyObject_IsTrue(s->strict), - next_idx_ptr); + PyString_AS_STRING(s->encoding), strict, next_idx_ptr); case '{': /* object */ if (Py_EnterRecursiveCall(" while decoding a JSON object " @@ -1557,6 +1565,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ Returns a new PyObject representation of the term. */ PyObject *res; + int strict; Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); Py_ssize_t length = PyUnicode_GET_SIZE(pystr); if (idx < 0) { @@ -1570,9 +1579,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ switch (str[idx]) { case '"': /* string */ - return scanstring_unicode(pystr, idx + 1, - PyObject_IsTrue(s->strict), - next_idx_ptr); + strict = PyObject_IsTrue(s->strict); + if (strict < 0) + return NULL; + return scanstring_unicode(pystr, idx + 1, strict, next_idx_ptr); case '{': /* object */ if (Py_EnterRecursiveCall(" while decoding a JSON object " @@ -1825,14 +1835,19 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) PyEncoderObject *s; PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; - PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; + PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan_obj; + int allow_nan; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, - &sort_keys, &skipkeys, &allow_nan)) + &sort_keys, &skipkeys, &allow_nan_obj)) + return -1; + + allow_nan = PyObject_IsTrue(allow_nan_obj); + if (allow_nan < 0) return -1; s->markers = markers; @@ -1844,7 +1859,7 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) s->sort_keys = sort_keys; s->skipkeys = skipkeys; s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); - s->allow_nan = PyObject_IsTrue(allow_nan); + s->allow_nan = allow_nan; Py_INCREF(s->markers); Py_INCREF(s->defaultfn); @@ -2110,6 +2125,8 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss if (it == NULL) goto bail; skipkeys = PyObject_IsTrue(s->skipkeys); + if (skipkeys < 0) + goto bail; idx = 0; while ((key = PyIter_Next(it)) != NULL) { PyObject *encoded; diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c index efc5d7f..82eff00 100644 --- a/Modules/threadmodule.c +++ b/Modules/threadmodule.c @@ -333,12 +333,18 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O }; - if (type->tp_init == PyBaseObject_Type.tp_init - && ((args && PyObject_IsTrue(args)) - || (kw && PyObject_IsTrue(kw)))) { - PyErr_SetString(PyExc_TypeError, - "Initialization arguments are not supported"); - return NULL; + if (type->tp_init == PyBaseObject_Type.tp_init) { + int rc = 0; + if (args != NULL) + rc = PyObject_IsTrue(args); + if (rc == 0 && kw != NULL) + rc = PyObject_IsTrue(kw); + if (rc != 0) { + if (rc > 0) + PyErr_SetString(PyExc_TypeError, + "Initialization arguments are not supported"); + return NULL; + } } self = (localobject *)type->tp_alloc(type, 0); diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index fd0ce7c..fd201ca 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1021,14 +1021,18 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) Py_buffer self_bytes, other_bytes; PyObject *res; Py_ssize_t minsize; - int cmp; + int cmp, rc; /* Bytes can be compared to anything that supports the (binary) buffer API. Except that a comparison with Unicode is always an error, even if the comparison is for equality. */ #ifdef Py_USING_UNICODE - if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || - PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) { + rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); + if (!rc) + rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); + if (rc < 0) + return NULL; + if (rc) { if (Py_BytesWarningFlag && op == Py_EQ) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytearray and string", 1)) diff --git a/Objects/setobject.c b/Objects/setobject.c index b4b1178..8a58d65 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1548,9 +1548,15 @@ set_difference(PySetObject *so, PyObject *other) if (PyDict_CheckExact(other)) { while (set_next(so, &pos, &entry)) { setentry entrycopy; + int rv; entrycopy.hash = entry->hash; entrycopy.key = entry->key; - if (!_PyDict_Contains(other, entry->key, entry->hash)) { + rv = _PyDict_Contains(other, entry->key, entry->hash); + if (rv < 0) { + Py_DECREF(result); + return NULL; + } + if (!rv) { if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { Py_DECREF(result); return NULL; @@ -1793,7 +1799,8 @@ PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); static PyObject * set_richcompare(PySetObject *v, PyObject *w, int op) { - PyObject *r1, *r2; + PyObject *r1; + int r2; if(!PyAnySet_Check(w)) { Py_INCREF(Py_NotImplemented); @@ -1812,9 +1819,11 @@ set_richcompare(PySetObject *v, PyObject *w, int op) r1 = set_richcompare(v, w, Py_EQ); if (r1 == NULL) return NULL; - r2 = PyBool_FromLong(PyObject_Not(r1)); + r2 = PyObject_IsTrue(r1); Py_DECREF(r1); - return r2; + if (r2 < 0) + return NULL; + return PyBool_FromLong(!r2); case Py_LE: return set_issubset(v, w); case Py_GE: diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ade5efe..ece709c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -137,6 +137,20 @@ add_flag(int flag, const char *envs) return flag; } +static int +isatty_no_error(PyObject *sys_stream) +{ + PyObject *sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); + if (sys_isatty) { + int isatty = PyObject_IsTrue(sys_isatty); + Py_DECREF(sys_isatty); + if (isatty >= 0) + return isatty; + } + PyErr_Clear(); + return 0; +} + void Py_InitializeEx(int install_sigs) { @@ -150,7 +164,7 @@ Py_InitializeEx(int install_sigs) char *errors = NULL; int free_codeset = 0; int overridden = 0; - PyObject *sys_stream, *sys_isatty; + PyObject *sys_stream; #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) char *saved_locale, *loc_codeset; #endif @@ -336,40 +350,25 @@ Py_InitializeEx(int install_sigs) if (codeset) { sys_stream = PySys_GetObject("stdin"); - sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); - if (!sys_isatty) - PyErr_Clear(); - if ((overridden || - (sys_isatty && PyObject_IsTrue(sys_isatty))) && - PyFile_Check(sys_stream)) { + if ((overridden || isatty_no_error(sys_stream)) && + PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, icodeset, errors)) Py_FatalError("Cannot set codeset of stdin"); } - Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stdout"); - sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); - if (!sys_isatty) - PyErr_Clear(); - if ((overridden || - (sys_isatty && PyObject_IsTrue(sys_isatty))) && - PyFile_Check(sys_stream)) { + if ((overridden || isatty_no_error(sys_stream)) && + PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stdout"); } - Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stderr"); - sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); - if (!sys_isatty) - PyErr_Clear(); - if((overridden || - (sys_isatty && PyObject_IsTrue(sys_isatty))) && - PyFile_Check(sys_stream)) { + if ((overridden || isatty_no_error(sys_stream)) && + PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stderr"); } - Py_XDECREF(sys_isatty); if (free_codeset) free(codeset); |