[Python-checkins] cpython (2.7): Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(),

serhiy.storchaka python-checkins at python.org
Sat May 30 16:49:26 CEST 2015


https://hg.python.org/cpython/rev/82490d05f3b0
changeset:   96375:82490d05f3b0
branch:      2.7
parent:      96355:418ab34fd1ce
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat May 30 17:45:12 2015 +0300
summary:
  Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(),
PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains()
to check for and handle errors correctly.

files:
  Misc/NEWS                 |   4 ++
  Modules/_json.c           |  35 ++++++++++++++++-----
  Modules/threadmodule.c    |  18 +++++++---
  Objects/bytearrayobject.c |  10 ++++-
  Objects/setobject.c       |  17 ++++++++--
  Python/pythonrun.c        |  43 +++++++++++++-------------
  6 files changed, 83 insertions(+), 44 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
 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
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -874,6 +874,9 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
 
     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 @@
     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 @@
     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
--- a/Modules/threadmodule.c
+++ b/Modules/threadmodule.c
@@ -333,12 +333,18 @@
         "_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
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1021,14 +1021,18 @@
     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
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1548,9 +1548,15 @@
     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 @@
 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 @@
         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
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -137,6 +137,20 @@
     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 @@
     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 @@
 
     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);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list