From: Victor Stinner Date: Thu, 19 Mar 2026 11:14:33 +0000 (+0100) Subject: [3.14] gh-146092: Fix error handling in _BINARY_OP_ADD_FLOAT opcode (#146119) X-Git-Tag: v3.14.4~110 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f29c1d0dabb84fc91caf874881b501345702793;p=thirdparty%2FPython%2Fcpython.git [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. --- 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 000000000000..5d17c88540cf --- /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 4cf6d509fe28..1b0469675299 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 78325111374a..7a33f63a0517 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 9dcd9afe8841..cef14cbf930e 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 20b5c4b3f497..f6dec81af265 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);