From 7f29c1d0dabb84fc91caf874881b501345702793 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 19 Mar 2026 12:14:33 +0100 Subject: [PATCH] [3.14] gh-146092: Fix error handling in _BINARY_OP_ADD_FLOAT opcode (#146119) Fix error handling in _PyFloat_FromDouble_ConsumeInputs() used by _BINARY_OP_ADD_FLOAT, _BINARY_OP_SUBTRACT_FLOAT and _BINARY_OP_MULTIPLY_FLOAT opcodes. PyStackRef_FromPyObjectSteal() must not be called with a NULL pointer. Fix also _BINARY_OP_INPLACE_ADD_UNICODE opcode. --- .../2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst | 2 ++ Objects/floatobject.c | 6 +++++- Python/bytecodes.c | 7 +++++-- Python/executor_cases.c.h | 7 +++---- Python/generated_cases.c.h | 7 +++---- 5 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst new file mode 100644 index 00000000000..5d17c88540c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst @@ -0,0 +1,2 @@ +Handle properly memory allocation failures on str and float opcodes. Patch by +Victor Stinner. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 4cf6d509fe2..1b046967529 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -139,7 +139,11 @@ _PyStackRef _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef righ { PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc); PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc); - return PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(value)); + PyObject *obj = PyFloat_FromDouble(value); + if (obj == NULL) { + return PyStackRef_NULL; + } + return PyStackRef_FromPyObjectSteal(obj); } static PyObject * diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 78325111374..7a33f63a051 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -793,9 +793,12 @@ dummy_func( PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local); PyObject *right_o = PyStackRef_AsPyObjectSteal(right); PyUnicode_Append(&temp, right_o); - *target_local = PyStackRef_FromPyObjectSteal(temp); Py_DECREF(right_o); - ERROR_IF(PyStackRef_IsNull(*target_local)); + if (temp == NULL) { + *target_local = PyStackRef_NULL; + ERROR_IF(true); + } + *target_local = PyStackRef_FromPyObjectSteal(temp); #if TIER_ONE // The STORE_FAST is already done. This is done here in tier one, // and during trace projection in tier two: diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9dcd9afe884..cef14cbf930 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1131,14 +1131,13 @@ assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyUnicode_Append(&temp, right_o); - stack_pointer = _PyFrame_GetStackPointer(frame); - *target_local = PyStackRef_FromPyObjectSteal(temp); - _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(right_o); stack_pointer = _PyFrame_GetStackPointer(frame); - if (PyStackRef_IsNull(*target_local)) { + if (temp == NULL) { + *target_local = PyStackRef_NULL; JUMP_TO_ERROR(); } + *target_local = PyStackRef_FromPyObjectSteal(temp); #if TIER_ONE assert(next_instr->op.code == STORE_FAST); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 20b5c4b3f49..f6dec81af26 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -392,14 +392,13 @@ assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyUnicode_Append(&temp, right_o); - stack_pointer = _PyFrame_GetStackPointer(frame); - *target_local = PyStackRef_FromPyObjectSteal(temp); - _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(right_o); stack_pointer = _PyFrame_GetStackPointer(frame); - if (PyStackRef_IsNull(*target_local)) { + if (temp == NULL) { + *target_local = PyStackRef_NULL; JUMP_TO_LABEL(error); } + *target_local = PyStackRef_FromPyObjectSteal(temp); #if TIER_ONE assert(next_instr->op.code == STORE_FAST);