Commit 5127ed72 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(),

PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains()
to check for and handle errors correctly.
parent 1e95340b
......@@ -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.
......
......@@ -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;
......
......@@ -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);
......
......@@ -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))
......
......@@ -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:
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment