]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-105375: Improve _pickle error handling (#105475) (#105584)
authorErlend E. Aasland <erlend.aasland@protonmail.com>
Fri, 9 Jun 2023 18:08:32 +0000 (20:08 +0200)
committerGitHub <noreply@github.com>
Fri, 9 Jun 2023 18:08:32 +0000 (18:08 +0000)
(cherry picked from commit 89aac6f6b7b3af046ec137121c90732289e79efc)

Error handling was deferred in some cases, which could potentially lead
to exceptions being overwritten.

Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst [new file with mode: 0644]
Modules/_pickle.c

diff --git a/Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst b/Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst
new file mode 100644 (file)
index 0000000..3030477
--- /dev/null
@@ -0,0 +1 @@
+Fix bugs in :mod:`pickle` where exceptions could be overwritten.
index bf7ecae0cc0e5000382c06ae3f3c4f01c8f79898..d6a273b1044e4429adb7054b40016863167ba2d3 100644 (file)
@@ -1168,10 +1168,13 @@ _Pickler_New(PickleState *st)
     self->reducer_override = NULL;
 
     self->memo = PyMemoTable_New();
+    if (self->memo == NULL) {
+        Py_DECREF(self);
+        return NULL;
+    }
     self->output_buffer = PyBytes_FromStringAndSize(NULL,
                                                     self->max_output_len);
-
-    if (self->memo == NULL || self->output_buffer == NULL) {
+    if (self->output_buffer == NULL) {
         Py_DECREF(self);
         return NULL;
     }
@@ -1654,9 +1657,12 @@ _Unpickler_New(PyObject *module)
     self->memo_size = 32;
     self->memo_len = 0;
     self->memo = _Unpickler_NewMemo(self->memo_size);
+    if (self->memo == NULL) {
+        Py_DECREF(self);
+        return NULL;
+    }
     self->stack = (Pdata *)Pdata_New(st);
-
-    if (self->memo == NULL || self->stack == NULL) {
+    if (self->stack == NULL) {
         Py_DECREF(self);
         return NULL;
     }
@@ -4834,11 +4840,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
             PyObject *key, *value;
 
             key = PyLong_FromVoidPtr(entry.me_key);
+            if (key == NULL) {
+                goto error;
+            }
             value = Py_BuildValue("nO", entry.me_value, entry.me_key);
-
-            if (key == NULL || value == NULL) {
-                Py_XDECREF(key);
-                Py_XDECREF(value);
+            if (value == NULL) {
+                Py_DECREF(key);
                 goto error;
             }
             status = PyDict_SetItem(new_memo, key, value);
@@ -5994,12 +6001,20 @@ load_stack_global(PickleState *st, UnpicklerObject *self)
     PyObject *global_name;
 
     PDATA_POP(st, self->stack, global_name);
+    if (global_name == NULL) {
+        return -1;
+    }
     PDATA_POP(st, self->stack, module_name);
-    if (module_name == NULL || !PyUnicode_CheckExact(module_name) ||
-        global_name == NULL || !PyUnicode_CheckExact(global_name)) {
+    if (module_name == NULL) {
+        Py_DECREF(global_name);
+        return -1;
+    }
+    if (!PyUnicode_CheckExact(module_name) ||
+        !PyUnicode_CheckExact(global_name))
+    {
         PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str");
-        Py_XDECREF(global_name);
-        Py_XDECREF(module_name);
+        Py_DECREF(global_name);
+        Py_DECREF(module_name);
         return -1;
     }
     global = find_class(self, module_name, global_name);