https://github.com/python/cpython/commit/7f29c1d0dabb84fc91caf874881b501345702793
commit: 7f29c1d0dabb84fc91caf874881b501345702793
branch: 3.14
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-19T12:14:33+01:00
summary:

[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.

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst
M Objects/floatobject.c
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h

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 00000000000000..5d17c88540cf3f
--- /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 4cf6d509fe281b..1b046967529934 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 78325111374a3f..7a33f63a051780 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 9dcd9afe884153..cef14cbf930ed1 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 20b5c4b3f497a9..f6dec81af265e2 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);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to