summaryrefslogtreecommitdiffstats
path: root/Objects/unionobject.c
diff options
context:
space:
mode:
authorKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>2021-06-22 13:54:44 (GMT)
committerGitHub <noreply@github.com>2021-06-22 13:54:44 (GMT)
commitadfa1ba398c74720b42f16f06fd3ec0353599fa5 (patch)
tree25aaef54963b7a5e1e9a334a2493f1f4d9b00fe6 /Objects/unionobject.c
parentbc6c12c72a9536acc96e7b9355fd69d1083a43c1 (diff)
downloadcpython-adfa1ba398c74720b42f16f06fd3ec0353599fa5.zip
cpython-adfa1ba398c74720b42f16f06fd3ec0353599fa5.tar.gz
cpython-adfa1ba398c74720b42f16f06fd3ec0353599fa5.tar.bz2
bpo-44483: Fix crash in union object with bad ``__module__`` (GH-26848)
Diffstat (limited to 'Objects/unionobject.c')
-rw-r--r--Objects/unionobject.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index 0535036..a66d615 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -284,6 +284,16 @@ is_new_type(PyObject *obj)
return is_typing_module(obj);
}
+// Emulates short-circuiting behavior of the ``||`` operator
+// while also checking negative values.
+#define CHECK_RES(res) { \
+ int result = res; \
+ if (result) { \
+ return result; \
+ } \
+}
+
+// Returns 1 on true, 0 on false, and -1 on error.
static int
is_unionable(PyObject *obj)
{
@@ -291,10 +301,11 @@ is_unionable(PyObject *obj)
return 1;
}
PyTypeObject *type = Py_TYPE(obj);
+ CHECK_RES(is_typevar(obj));
+ CHECK_RES(is_new_type(obj));
+ CHECK_RES(is_special_form(obj));
return (
- is_typevar(obj) ||
- is_new_type(obj) ||
- is_special_form(obj) ||
+ // The following checks never fail.
PyType_Check(obj) ||
PyObject_TypeCheck(obj, &Py_GenericAliasType) ||
type == &_Py_UnionType);