[Python-checkins] cpython (merge 3.5 -> default): Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(),
serhiy.storchaka
python-checkins at python.org
Sat May 30 16:49:27 CEST 2015
https://hg.python.org/cpython/rev/f5d1bb0c4192
changeset: 96378:f5d1bb0c4192
parent: 96374:ab5aaeaee5ac
parent: 96377:7d1b81224c3b
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sat May 30 17:48:54 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 | 24 +++++++++++++-----
Modules/_threadmodule.c | 18 +++++++++----
Modules/faulthandler.c | 4 +-
Objects/bytearrayobject.c | 10 +++++--
Objects/bytesobject.c | 33 ++++++++++++++++++---------
Objects/rangeobject.c | 5 +++-
Objects/setobject.c | 17 ++++++++++---
Python/codecs.c | 11 ++++----
Python/import.c | 6 ++++-
10 files changed, 92 insertions(+), 40 deletions(-)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,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 #24328: Fix importing one character extension modules.
- Issue #11205: In dictionary displays, evaluate the key before the value.
diff --git a/Modules/_json.c b/Modules/_json.c
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -710,6 +710,9 @@
int has_pairs_hook = (s->object_pairs_hook != Py_None);
Py_ssize_t next_idx;
+ if (strict < 0)
+ return NULL;
+
if (PyUnicode_READY(pystr) == -1)
return NULL;
@@ -1055,6 +1058,7 @@
void *str;
int kind;
Py_ssize_t length;
+ int strict;
if (PyUnicode_READY(pystr) == -1)
return NULL;
@@ -1075,9 +1079,10 @@
switch (PyUnicode_READ(kind, 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 "
@@ -1327,12 +1332,13 @@
PyEncoderObject *s;
PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
- PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan;
+ PyObject *item_separator, *sort_keys, *skipkeys;
+ int allow_nan;
assert(PyEncoder_Check(self));
s = (PyEncoderObject *)self;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOp:make_encoder", kwlist,
&markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator,
&sort_keys, &skipkeys, &allow_nan))
return -1;
@@ -1353,7 +1359,7 @@
s->fast_encode = f;
}
}
- s->allow_nan = PyObject_IsTrue(allow_nan);
+ s->allow_nan = allow_nan;
Py_INCREF(s->markers);
Py_INCREF(s->defaultfn);
@@ -1622,6 +1628,7 @@
PyObject *items;
PyObject *item = NULL;
int skipkeys;
+ int sortkeys;
Py_ssize_t idx;
if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
@@ -1666,13 +1673,16 @@
items = PyMapping_Items(dct);
if (items == NULL)
goto bail;
- if (PyObject_IsTrue(s->sort_keys) && PyList_Sort(items) < 0)
+ sortkeys = PyObject_IsTrue(s->sort_keys);
+ if (sortkeys < 0 || (sortkeys && PyList_Sort(items) < 0))
goto bail;
it = PyObject_GetIter(items);
Py_DECREF(items);
if (it == NULL)
goto bail;
skipkeys = PyObject_IsTrue(s->skipkeys);
+ if (skipkeys < 0)
+ goto bail;
idx = 0;
while ((item = PyIter_Next(it)) != NULL) {
PyObject *encoded, *key, *value;
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -711,12 +711,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/Modules/faulthandler.c b/Modules/faulthandler.c
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -1115,8 +1115,8 @@
has_key = PyDict_Contains(xoptions, key);
Py_DECREF(key);
- if (!has_key)
- return 0;
+ if (has_key <= 0)
+ return has_key;
}
module = PyImport_ImportModule("faulthandler");
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1011,13 +1011,17 @@
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. */
- 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 || op == Py_NE)) {
if (PyErr_WarnEx(PyExc_BytesWarning,
"Comparison between bytearray and string", 1))
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1419,25 +1419,36 @@
Py_ssize_t len_a, len_b;
Py_ssize_t min_len;
PyObject *result;
+ int rc;
/* Make sure both arguments are strings. */
if (!(PyBytes_Check(a) && PyBytes_Check(b))) {
if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
- if (PyObject_IsInstance((PyObject*)a,
- (PyObject*)&PyUnicode_Type) ||
- PyObject_IsInstance((PyObject*)b,
- (PyObject*)&PyUnicode_Type)) {
+ rc = PyObject_IsInstance((PyObject*)a,
+ (PyObject*)&PyUnicode_Type);
+ if (!rc)
+ rc = PyObject_IsInstance((PyObject*)b,
+ (PyObject*)&PyUnicode_Type);
+ if (rc < 0)
+ return NULL;
+ if (rc) {
if (PyErr_WarnEx(PyExc_BytesWarning,
- "Comparison between bytes and string", 1))
+ "Comparison between bytes and string", 1))
return NULL;
}
- else if (PyObject_IsInstance((PyObject*)a,
- (PyObject*)&PyLong_Type) ||
- PyObject_IsInstance((PyObject*)b,
- (PyObject*)&PyLong_Type)) {
- if (PyErr_WarnEx(PyExc_BytesWarning,
- "Comparison between bytes and int", 1))
+ else {
+ rc = PyObject_IsInstance((PyObject*)a,
+ (PyObject*)&PyLong_Type);
+ if (!rc)
+ rc = PyObject_IsInstance((PyObject*)b,
+ (PyObject*)&PyLong_Type);
+ if (rc < 0)
return NULL;
+ if (rc) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "Comparison between bytes and int", 1))
+ return NULL;
+ }
}
}
result = Py_NotImplemented;
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -194,8 +194,11 @@
}
/* if (lo >= hi), return length of 0. */
- if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) {
+ cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
+ if (cmp_result != 0) {
Py_XDECREF(step);
+ if (cmp_result < 0)
+ return NULL;
return PyLong_FromLong(0);
}
diff --git a/Objects/setobject.c b/Objects/setobject.c
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1582,9 +1582,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)) {
Py_DECREF(result);
return NULL;
@@ -1820,7 +1826,8 @@
static PyObject *
set_richcompare(PySetObject *v, PyObject *w, int op)
{
- PyObject *r1, *r2;
+ PyObject *r1;
+ int r2;
if(!PyAnySet_Check(w))
Py_RETURN_NOTIMPLEMENTED;
@@ -1838,9 +1845,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/codecs.c b/Python/codecs.c
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -550,12 +550,13 @@
} else {
is_text_codec = PyObject_IsTrue(attr);
Py_DECREF(attr);
- if (!is_text_codec) {
+ if (is_text_codec <= 0) {
Py_DECREF(codec);
- PyErr_Format(PyExc_LookupError,
- "'%.400s' is not a text encoding; "
- "use %s to handle arbitrary codecs",
- encoding, alternate_command);
+ if (!is_text_codec)
+ PyErr_Format(PyExc_LookupError,
+ "'%.400s' is not a text encoding; "
+ "use %s to handle arbitrary codecs",
+ encoding, alternate_command);
return NULL;
}
}
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -1366,6 +1366,7 @@
PyObject *globals = NULL;
PyObject *fromlist = NULL;
PyInterpreterState *interp = PyThreadState_GET()->interp;
+ int has_from;
/* Make sure to use default values so as to not have
PyObject_CallMethodObjArgs() truncate the parameter list because of a
@@ -1596,7 +1597,10 @@
}
/* From now on we don't hold the import lock anymore. */
- if (PyObject_Not(fromlist)) {
+ has_from = PyObject_IsTrue(fromlist);
+ if (has_from < 0)
+ goto error;
+ if (!has_from) {
if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) {
PyObject *front = NULL;
PyObject *partition = NULL;
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list