Skip to content

Commit 89aac6f

Browse files
gh-105375: Improve _pickle error handling (#105475)
Error handling was deferred in some cases, which could potentially lead to exceptions being overwritten.
1 parent 6c832dd commit 89aac6f

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bugs in :mod:`pickle` where exceptions could be overwritten.

Modules/_pickle.c

+27-12
Original file line numberDiff line numberDiff line change
@@ -1168,10 +1168,13 @@ _Pickler_New(PickleState *st)
11681168
self->reducer_override = NULL;
11691169

11701170
self->memo = PyMemoTable_New();
1171+
if (self->memo == NULL) {
1172+
Py_DECREF(self);
1173+
return NULL;
1174+
}
11711175
self->output_buffer = PyBytes_FromStringAndSize(NULL,
11721176
self->max_output_len);
1173-
1174-
if (self->memo == NULL || self->output_buffer == NULL) {
1177+
if (self->output_buffer == NULL) {
11751178
Py_DECREF(self);
11761179
return NULL;
11771180
}
@@ -1654,9 +1657,12 @@ _Unpickler_New(PyObject *module)
16541657
self->memo_size = 32;
16551658
self->memo_len = 0;
16561659
self->memo = _Unpickler_NewMemo(self->memo_size);
1660+
if (self->memo == NULL) {
1661+
Py_DECREF(self);
1662+
return NULL;
1663+
}
16571664
self->stack = (Pdata *)Pdata_New(st);
1658-
1659-
if (self->memo == NULL || self->stack == NULL) {
1665+
if (self->stack == NULL) {
16601666
Py_DECREF(self);
16611667
return NULL;
16621668
}
@@ -4828,11 +4834,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
48284834
PyObject *key, *value;
48294835

48304836
key = PyLong_FromVoidPtr(entry.me_key);
4837+
if (key == NULL) {
4838+
goto error;
4839+
}
48314840
value = Py_BuildValue("nO", entry.me_value, entry.me_key);
4832-
4833-
if (key == NULL || value == NULL) {
4834-
Py_XDECREF(key);
4835-
Py_XDECREF(value);
4841+
if (value == NULL) {
4842+
Py_DECREF(key);
48364843
goto error;
48374844
}
48384845
status = PyDict_SetItem(new_memo, key, value);
@@ -5988,12 +5995,20 @@ load_stack_global(PickleState *st, UnpicklerObject *self)
59885995
PyObject *global_name;
59895996

59905997
PDATA_POP(st, self->stack, global_name);
5998+
if (global_name == NULL) {
5999+
return -1;
6000+
}
59916001
PDATA_POP(st, self->stack, module_name);
5992-
if (module_name == NULL || !PyUnicode_CheckExact(module_name) ||
5993-
global_name == NULL || !PyUnicode_CheckExact(global_name)) {
6002+
if (module_name == NULL) {
6003+
Py_DECREF(global_name);
6004+
return -1;
6005+
}
6006+
if (!PyUnicode_CheckExact(module_name) ||
6007+
!PyUnicode_CheckExact(global_name))
6008+
{
59946009
PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str");
5995-
Py_XDECREF(global_name);
5996-
Py_XDECREF(module_name);
6010+
Py_DECREF(global_name);
6011+
Py_DECREF(module_name);
59976012
return -1;
59986013
}
59996014
global = find_class(self, module_name, global_name);

0 commit comments

Comments
 (0)