]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-146092: Fix error handling in _BINARY_OP_ADD_FLOAT opcode (#146119)
authorVictor Stinner <vstinner@python.org>
Thu, 19 Mar 2026 11:14:33 +0000 (12:14 +0100)
committerGitHub <noreply@github.com>
Thu, 19 Mar 2026 11:14:33 +0000 (12:14 +0100)
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.

Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-16-57-56.gh-issue-146092.wCKFYS.rst [new file with mode: 0644]
Objects/floatobject.c
Python/bytecodes.c
Python/executor_cases.c.h
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 (file)
index 0000000..5d17c88
--- /dev/null
@@ -0,0 +1,2 @@
+Handle properly memory allocation failures on str and float opcodes. Patch by
+Victor Stinner.
index 4cf6d509fe281b43e477a93f4847d4b1a4a70200..1b04696752993465e5c83a1798dbda67ab377ad3 100644 (file)
@@ -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 *
index 78325111374a3f2f24881fc295afba0ad84b3dee..7a33f63a051780443651c39ee355757907f6ac00 100644 (file)
@@ -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:
index 9dcd9afe884153a12e3210134476337012ae19ec..cef14cbf930ed1f24dfbb0e3100392d7a7654d55 100644 (file)
             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);
index 20b5c4b3f497a93191ab633b5513cfd9bb8c49ce..f6dec81af265e285f611df27c404bcfd38e8950b 100644 (file)
                 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);