diff options
| author | Peter Bierma <zintensitydev@gmail.com> | 2025-04-08 10:31:43 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-08 10:31:43 (GMT) |
| commit | ac3c439cdfee8452f2bcceacd67a1f4e423ac3cf (patch) | |
| tree | d82077aabcc46b2186b32b25f3341dc0d9605188 /Python | |
| parent | 3eda1460359c7e6af4c5b125a63388635a3ed477 (diff) | |
| download | cpython-ac3c439cdfee8452f2bcceacd67a1f4e423ac3cf.zip cpython-ac3c439cdfee8452f2bcceacd67a1f4e423ac3cf.tar.gz cpython-ac3c439cdfee8452f2bcceacd67a1f4e423ac3cf.tar.bz2 | |
gh-131998: Fix `NULL` dereference when using an unbound method descriptor in a specialized code path (#132000)
Co-authored-by: sobolevn <mail@sobolevn.me>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Mark Shannon <mark@hotpy.org>
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/bytecodes.c | 4 | ||||
| -rw-r--r-- | Python/executor_cases.c.h | 10 | ||||
| -rw-r--r-- | Python/generated_cases.c.h | 12 |
3 files changed, 26 insertions, 0 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index d17cac2..53da324 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4300,12 +4300,14 @@ dummy_func( arguments--; total_args++; } + EXIT_IF(total_args == 0); PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; EXIT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); PyMethodDef *meth = method->d_method; EXIT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS)); PyTypeObject *d_type = method->d_common.d_type; PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); EXIT_IF(!Py_IS_TYPE(self, d_type)); STAT_INC(CALL, hit); int nargs = total_args - 1; @@ -4378,12 +4380,14 @@ dummy_func( arguments--; total_args++; } + EXIT_IF(total_args == 0); PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; /* Builtin METH_FASTCALL methods, without keywords */ EXIT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); PyMethodDef *meth = method->d_method; EXIT_IF(meth->ml_flags != METH_FASTCALL); PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); EXIT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); STAT_INC(CALL, hit); int nargs = total_args - 1; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 497aa90..3457ff0 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5838,6 +5838,10 @@ arguments--; total_args++; } + if (total_args == 0) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); + } PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) { UOP_STAT_INC(uopcode, miss); @@ -5850,6 +5854,7 @@ } PyTypeObject *d_type = method->d_common.d_type; PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); if (!Py_IS_TYPE(self, d_type)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); @@ -5990,6 +5995,10 @@ arguments--; total_args++; } + if (total_args == 0) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); + } PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) { UOP_STAT_INC(uopcode, miss); @@ -6001,6 +6010,7 @@ JUMP_TO_JUMP_TARGET(); } PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); if (!Py_IS_TYPE(self, method->d_common.d_type)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index fa3de19..fb4ab92 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3333,6 +3333,11 @@ arguments--; total_args++; } + if (total_args == 0) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) { UPDATE_MISS_STATS(CALL); @@ -3346,6 +3351,7 @@ JUMP_TO_PREDICTED(CALL); } PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); if (!Py_IS_TYPE(self, method->d_common.d_type)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); @@ -3453,6 +3459,11 @@ arguments--; total_args++; } + if (total_args == 0) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o; if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) { UPDATE_MISS_STATS(CALL); @@ -3467,6 +3478,7 @@ } PyTypeObject *d_type = method->d_common.d_type; PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]); + assert(self != NULL); if (!Py_IS_TYPE(self, d_type)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); |
