Skip to content

Commit 4d4251d

Browse files
[3.11] gh-105375: Improve _pickle error handling (#105475) (#105583)
(cherry picked from commit 89aac6f) Error handling was deferred in some cases, which could potentially lead to exceptions being overwritten.
1 parent 90e357b commit 4d4251d

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed
Lines changed: 1 addition & 0 deletions
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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,10 +1139,13 @@ _Pickler_New(void)
11391139
self->reducer_override = NULL;
11401140

11411141
self->memo = PyMemoTable_New();
1142+
if (self->memo == NULL) {
1143+
Py_DECREF(self);
1144+
return NULL;
1145+
}
11421146
self->output_buffer = PyBytes_FromStringAndSize(NULL,
11431147
self->max_output_len);
1144-
1145-
if (self->memo == NULL || self->output_buffer == NULL) {
1148+
if (self->output_buffer == NULL) {
11461149
Py_DECREF(self);
11471150
return NULL;
11481151
}
@@ -1627,9 +1630,12 @@ _Unpickler_New(void)
16271630
self->memo_size = 32;
16281631
self->memo_len = 0;
16291632
self->memo = _Unpickler_NewMemo(self->memo_size);
1633+
if (self->memo == NULL) {
1634+
Py_DECREF(self);
1635+
return NULL;
1636+
}
16301637
self->stack = (Pdata *)Pdata_New();
1631-
1632-
if (self->memo == NULL || self->stack == NULL) {
1638+
if (self->stack == NULL) {
16331639
Py_DECREF(self);
16341640
return NULL;
16351641
}
@@ -4833,11 +4839,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
48334839
PyObject *key, *value;
48344840

48354841
key = PyLong_FromVoidPtr(entry.me_key);
4842+
if (key == NULL) {
4843+
goto error;
4844+
}
48364845
value = Py_BuildValue("nO", entry.me_value, entry.me_key);
4837-
4838-
if (key == NULL || value == NULL) {
4839-
Py_XDECREF(key);
4840-
Py_XDECREF(value);
4846+
if (value == NULL) {
4847+
Py_DECREF(key);
48414848
goto error;
48424849
}
48434850
status = PyDict_SetItem(new_memo, key, value);
@@ -6033,13 +6040,21 @@ load_stack_global(UnpicklerObject *self)
60336040
PyObject *global_name;
60346041

60356042
PDATA_POP(self->stack, global_name);
6043+
if (global_name == NULL) {
6044+
return -1;
6045+
}
60366046
PDATA_POP(self->stack, module_name);
6037-
if (module_name == NULL || !PyUnicode_CheckExact(module_name) ||
6038-
global_name == NULL || !PyUnicode_CheckExact(global_name)) {
6047+
if (module_name == NULL) {
6048+
Py_DECREF(global_name);
6049+
return -1;
6050+
}
6051+
if (!PyUnicode_CheckExact(module_name) ||
6052+
!PyUnicode_CheckExact(global_name))
6053+
{
60396054
PickleState *st = _Pickle_GetGlobalState();
60406055
PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str");
6041-
Py_XDECREF(global_name);
6042-
Py_XDECREF(module_name);
6056+
Py_DECREF(global_name);
6057+
Py_DECREF(module_name);
60436058
return -1;
60446059
}
60456060
global = find_class(self, module_name, global_name);

0 commit comments

Comments
 (0)