mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(),
PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains() to check for and handle errors correctly.
This commit is contained in:
		
							parent
							
								
									50451eb912
								
							
						
					
					
						commit
						fa494fd883
					
				
					 10 changed files with 83 additions and 36 deletions
				
			
		|  | @ -10,6 +10,10 @@ Release date: tba | ||||||
| Core and Builtins | 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 #24257: Fixed system error in the comparison of faked | - Issue #24257: Fixed system error in the comparison of faked | ||||||
|   types.SimpleNamespace. |   types.SimpleNamespace. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -595,6 +595,9 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss | ||||||
|     int has_pairs_hook = (s->object_pairs_hook != Py_None); |     int has_pairs_hook = (s->object_pairs_hook != Py_None); | ||||||
|     Py_ssize_t next_idx; |     Py_ssize_t next_idx; | ||||||
| 
 | 
 | ||||||
|  |     if (strict < 0) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|     if (PyUnicode_READY(pystr) == -1) |     if (PyUnicode_READY(pystr) == -1) | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|  | @ -940,6 +943,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ | ||||||
|     void *str; |     void *str; | ||||||
|     int kind; |     int kind; | ||||||
|     Py_ssize_t length; |     Py_ssize_t length; | ||||||
|  |     int strict; | ||||||
| 
 | 
 | ||||||
|     if (PyUnicode_READY(pystr) == -1) |     if (PyUnicode_READY(pystr) == -1) | ||||||
|         return NULL; |         return NULL; | ||||||
|  | @ -960,9 +964,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ | ||||||
|     switch (PyUnicode_READ(kind, str, idx)) { |     switch (PyUnicode_READ(kind, str, idx)) { | ||||||
|         case '"': |         case '"': | ||||||
|             /* string */ |             /* string */ | ||||||
|             return scanstring_unicode(pystr, idx + 1, |             strict = PyObject_IsTrue(s->strict); | ||||||
|                 PyObject_IsTrue(s->strict), |             if (strict < 0) | ||||||
|                 next_idx_ptr); |                 return NULL; | ||||||
|  |             return scanstring_unicode(pystr, idx + 1, strict, next_idx_ptr); | ||||||
|         case '{': |         case '{': | ||||||
|             /* object */ |             /* object */ | ||||||
|             if (Py_EnterRecursiveCall(" while decoding a JSON object " |             if (Py_EnterRecursiveCall(" while decoding a JSON object " | ||||||
|  | @ -1212,12 +1217,13 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) | ||||||
| 
 | 
 | ||||||
|     PyEncoderObject *s; |     PyEncoderObject *s; | ||||||
|     PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; |     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)); |     assert(PyEncoder_Check(self)); | ||||||
|     s = (PyEncoderObject *)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, |         &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, | ||||||
|         &sort_keys, &skipkeys, &allow_nan)) |         &sort_keys, &skipkeys, &allow_nan)) | ||||||
|         return -1; |         return -1; | ||||||
|  | @ -1231,7 +1237,7 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) | ||||||
|     s->sort_keys = sort_keys; |     s->sort_keys = sort_keys; | ||||||
|     s->skipkeys = skipkeys; |     s->skipkeys = skipkeys; | ||||||
|     s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); |     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->markers); | ||||||
|     Py_INCREF(s->defaultfn); |     Py_INCREF(s->defaultfn); | ||||||
|  | @ -1500,6 +1506,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, | ||||||
|     PyObject *items; |     PyObject *items; | ||||||
|     PyObject *item = NULL; |     PyObject *item = NULL; | ||||||
|     int skipkeys; |     int skipkeys; | ||||||
|  |     int sortkeys; | ||||||
|     Py_ssize_t idx; |     Py_ssize_t idx; | ||||||
| 
 | 
 | ||||||
|     if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { |     if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { | ||||||
|  | @ -1544,13 +1551,16 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, | ||||||
|     items = PyMapping_Items(dct); |     items = PyMapping_Items(dct); | ||||||
|     if (items == NULL) |     if (items == NULL) | ||||||
|         goto bail; |         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; |         goto bail; | ||||||
|     it = PyObject_GetIter(items); |     it = PyObject_GetIter(items); | ||||||
|     Py_DECREF(items); |     Py_DECREF(items); | ||||||
|     if (it == NULL) |     if (it == NULL) | ||||||
|         goto bail; |         goto bail; | ||||||
|     skipkeys = PyObject_IsTrue(s->skipkeys); |     skipkeys = PyObject_IsTrue(s->skipkeys); | ||||||
|  |     if (skipkeys < 0) | ||||||
|  |         goto bail; | ||||||
|     idx = 0; |     idx = 0; | ||||||
|     while ((item = PyIter_Next(it)) != NULL) { |     while ((item = PyIter_Next(it)) != NULL) { | ||||||
|         PyObject *encoded, *key, *value; |         PyObject *encoded, *key, *value; | ||||||
|  |  | ||||||
|  | @ -718,12 +718,18 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) | ||||||
|         "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O |         "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if (type->tp_init == PyBaseObject_Type.tp_init |     if (type->tp_init == PyBaseObject_Type.tp_init) { | ||||||
|         && ((args && PyObject_IsTrue(args)) |         int rc = 0; | ||||||
|         || (kw && PyObject_IsTrue(kw)))) { |         if (args != NULL) | ||||||
|         PyErr_SetString(PyExc_TypeError, |             rc = PyObject_IsTrue(args); | ||||||
|                   "Initialization arguments are not supported"); |         if (rc == 0 && kw != NULL) | ||||||
|         return 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); |     self = (localobject *)type->tp_alloc(type, 0); | ||||||
|  |  | ||||||
|  | @ -1087,8 +1087,8 @@ faulthandler_env_options(void) | ||||||
| 
 | 
 | ||||||
|         has_key = PyDict_Contains(xoptions, key); |         has_key = PyDict_Contains(xoptions, key); | ||||||
|         Py_DECREF(key); |         Py_DECREF(key); | ||||||
|         if (!has_key) |         if (has_key <= 0) | ||||||
|             return 0; |             return has_key; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     module = PyImport_ImportModule("faulthandler"); |     module = PyImport_ImportModule("faulthandler"); | ||||||
|  |  | ||||||
|  | @ -974,13 +974,17 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) | ||||||
|     Py_buffer self_bytes, other_bytes; |     Py_buffer self_bytes, other_bytes; | ||||||
|     PyObject *res; |     PyObject *res; | ||||||
|     Py_ssize_t minsize; |     Py_ssize_t minsize; | ||||||
|     int cmp; |     int cmp, rc; | ||||||
| 
 | 
 | ||||||
|     /* Bytes can be compared to anything that supports the (binary)
 |     /* Bytes can be compared to anything that supports the (binary)
 | ||||||
|        buffer API.  Except that a comparison with Unicode is always an |        buffer API.  Except that a comparison with Unicode is always an | ||||||
|        error, even if the comparison is for equality. */ |        error, even if the comparison is for equality. */ | ||||||
|     if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || |     rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); | ||||||
|         PyObject_IsInstance(other, (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 (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) { | ||||||
|             if (PyErr_WarnEx(PyExc_BytesWarning, |             if (PyErr_WarnEx(PyExc_BytesWarning, | ||||||
|                             "Comparison between bytearray and string", 1)) |                             "Comparison between bytearray and string", 1)) | ||||||
|  |  | ||||||
|  | @ -816,17 +816,23 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) | ||||||
|     Py_ssize_t len_a, len_b; |     Py_ssize_t len_a, len_b; | ||||||
|     Py_ssize_t min_len; |     Py_ssize_t min_len; | ||||||
|     PyObject *result; |     PyObject *result; | ||||||
|  |     int rc; | ||||||
| 
 | 
 | ||||||
|     /* Make sure both arguments are strings. */ |     /* Make sure both arguments are strings. */ | ||||||
|     if (!(PyBytes_Check(a) && PyBytes_Check(b))) { |     if (!(PyBytes_Check(a) && PyBytes_Check(b))) { | ||||||
|         if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && |         if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) { | ||||||
|             (PyObject_IsInstance((PyObject*)a, |             rc = PyObject_IsInstance((PyObject*)a, | ||||||
|                                  (PyObject*)&PyUnicode_Type) || |                                      (PyObject*)&PyUnicode_Type); | ||||||
|             PyObject_IsInstance((PyObject*)b, |             if (!rc) | ||||||
|                                  (PyObject*)&PyUnicode_Type))) { |                 rc = PyObject_IsInstance((PyObject*)b, | ||||||
|             if (PyErr_WarnEx(PyExc_BytesWarning, |                                          (PyObject*)&PyUnicode_Type); | ||||||
|                         "Comparison between bytes and string", 1)) |             if (rc < 0) | ||||||
|                 return NULL; |                 return NULL; | ||||||
|  |             if (rc) { | ||||||
|  |                 if (PyErr_WarnEx(PyExc_BytesWarning, | ||||||
|  |                                  "Comparison between bytes and string", 1)) | ||||||
|  |                     return NULL; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         result = Py_NotImplemented; |         result = Py_NotImplemented; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -194,8 +194,11 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* if (lo >= hi), return length of 0. */ |     /* 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); |         Py_XDECREF(step); | ||||||
|  |         if (cmp_result < 0) | ||||||
|  |             return NULL; | ||||||
|         return PyLong_FromLong(0); |         return PyLong_FromLong(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1569,9 +1569,15 @@ set_difference(PySetObject *so, PyObject *other) | ||||||
|     if (PyDict_CheckExact(other)) { |     if (PyDict_CheckExact(other)) { | ||||||
|         while (set_next(so, &pos, &entry)) { |         while (set_next(so, &pos, &entry)) { | ||||||
|             setentry entrycopy; |             setentry entrycopy; | ||||||
|  |             int rv; | ||||||
|             entrycopy.hash = entry->hash; |             entrycopy.hash = entry->hash; | ||||||
|             entrycopy.key = entry->key; |             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) { |                 if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { | ||||||
|                     Py_DECREF(result); |                     Py_DECREF(result); | ||||||
|                     return NULL; |                     return NULL; | ||||||
|  | @ -1807,7 +1813,8 @@ PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); | ||||||
| static PyObject * | static PyObject * | ||||||
| set_richcompare(PySetObject *v, PyObject *w, int op) | set_richcompare(PySetObject *v, PyObject *w, int op) | ||||||
| { | { | ||||||
|     PyObject *r1, *r2; |     PyObject *r1; | ||||||
|  |     int r2; | ||||||
| 
 | 
 | ||||||
|     if(!PyAnySet_Check(w)) |     if(!PyAnySet_Check(w)) | ||||||
|         Py_RETURN_NOTIMPLEMENTED; |         Py_RETURN_NOTIMPLEMENTED; | ||||||
|  | @ -1825,9 +1832,11 @@ set_richcompare(PySetObject *v, PyObject *w, int op) | ||||||
|         r1 = set_richcompare(v, w, Py_EQ); |         r1 = set_richcompare(v, w, Py_EQ); | ||||||
|         if (r1 == NULL) |         if (r1 == NULL) | ||||||
|             return NULL; |             return NULL; | ||||||
|         r2 = PyBool_FromLong(PyObject_Not(r1)); |         r2 = PyObject_IsTrue(r1); | ||||||
|         Py_DECREF(r1); |         Py_DECREF(r1); | ||||||
|         return r2; |         if (r2 < 0) | ||||||
|  |             return NULL; | ||||||
|  |         return PyBool_FromLong(!r2); | ||||||
|     case Py_LE: |     case Py_LE: | ||||||
|         return set_issubset(v, w); |         return set_issubset(v, w); | ||||||
|     case Py_GE: |     case Py_GE: | ||||||
|  |  | ||||||
|  | @ -549,12 +549,13 @@ PyObject * _PyCodec_LookupTextEncoding(const char *encoding, | ||||||
|         } else { |         } else { | ||||||
|             is_text_codec = PyObject_IsTrue(attr); |             is_text_codec = PyObject_IsTrue(attr); | ||||||
|             Py_DECREF(attr); |             Py_DECREF(attr); | ||||||
|             if (!is_text_codec) { |             if (is_text_codec <= 0) { | ||||||
|                 Py_DECREF(codec); |                 Py_DECREF(codec); | ||||||
|                 PyErr_Format(PyExc_LookupError, |                 if (!is_text_codec) | ||||||
|                              "'%.400s' is not a text encoding; " |                     PyErr_Format(PyExc_LookupError, | ||||||
|                              "use %s to handle arbitrary codecs", |                                  "'%.400s' is not a text encoding; " | ||||||
|                              encoding, alternate_command); |                                  "use %s to handle arbitrary codecs", | ||||||
|  |                                  encoding, alternate_command); | ||||||
|                 return NULL; |                 return NULL; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1416,6 +1416,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, | ||||||
|     PyObject *globals = NULL; |     PyObject *globals = NULL; | ||||||
|     PyObject *fromlist = NULL; |     PyObject *fromlist = NULL; | ||||||
|     PyInterpreterState *interp = PyThreadState_GET()->interp; |     PyInterpreterState *interp = PyThreadState_GET()->interp; | ||||||
|  |     int has_from; | ||||||
| 
 | 
 | ||||||
|     /* Make sure to use default values so as to not have
 |     /* Make sure to use default values so as to not have
 | ||||||
|        PyObject_CallMethodObjArgs() truncate the parameter list because of a |        PyObject_CallMethodObjArgs() truncate the parameter list because of a | ||||||
|  | @ -1646,7 +1647,10 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, | ||||||
|     } |     } | ||||||
|     /* From now on we don't hold the import lock anymore. */ |     /* 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) { |         if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) { | ||||||
|             PyObject *front = NULL; |             PyObject *front = NULL; | ||||||
|             PyObject *partition = NULL; |             PyObject *partition = NULL; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka