Skip to content

Commit 36c393c

Browse files
[3.11] gh-105375: Explicitly initialise all {Pickler,Unpickler}Object fields (#105686) (#105711)
* [3.11] gh-105375: Explicitly initialise all {Pickler,Unpickler}Object fields (#105686) All fields must be explicitly initialised to prevent manipulation of uninitialised fields in dealloc. Align initialisation order with the layout of the object structs. (cherry picked from commit ca3cc4b) Co-authored-by: Erlend E. Aasland <[email protected]>
1 parent 261d0b4 commit 36c393c

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

Modules/_pickle.c

+52-37
Original file line numberDiff line numberDiff line change
@@ -1116,42 +1116,49 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len)
11161116
static PicklerObject *
11171117
_Pickler_New(void)
11181118
{
1119-
PicklerObject *self;
1120-
1121-
self = PyObject_GC_New(PicklerObject, &Pickler_Type);
1122-
if (self == NULL)
1119+
PyMemoTable *memo = PyMemoTable_New();
1120+
if (memo == NULL) {
11231121
return NULL;
1122+
}
1123+
1124+
const Py_ssize_t max_output_len = WRITE_BUF_SIZE;
1125+
PyObject *output_buffer = PyBytes_FromStringAndSize(NULL, max_output_len);
1126+
if (output_buffer == NULL) {
1127+
goto error;
1128+
}
11241129

1130+
PicklerObject *self = PyObject_GC_New(PicklerObject, &Pickler_Type);
1131+
if (self == NULL) {
1132+
goto error;
1133+
}
1134+
1135+
self->memo = memo;
11251136
self->pers_func = NULL;
1137+
self->pers_func_self = NULL;
11261138
self->dispatch_table = NULL;
1127-
self->buffer_callback = NULL;
1139+
self->reducer_override = NULL;
11281140
self->write = NULL;
1141+
self->output_buffer = output_buffer;
1142+
self->output_len = 0;
1143+
self->max_output_len = max_output_len;
11291144
self->proto = 0;
11301145
self->bin = 0;
11311146
self->framing = 0;
11321147
self->frame_start = -1;
1148+
self->buf_size = 0;
11331149
self->fast = 0;
11341150
self->fast_nesting = 0;
11351151
self->fix_imports = 0;
11361152
self->fast_memo = NULL;
1137-
self->max_output_len = WRITE_BUF_SIZE;
1138-
self->output_len = 0;
1139-
self->reducer_override = NULL;
1140-
1141-
self->memo = PyMemoTable_New();
1142-
if (self->memo == NULL) {
1143-
Py_DECREF(self);
1144-
return NULL;
1145-
}
1146-
self->output_buffer = PyBytes_FromStringAndSize(NULL,
1147-
self->max_output_len);
1148-
if (self->output_buffer == NULL) {
1149-
Py_DECREF(self);
1150-
return NULL;
1151-
}
1153+
self->buffer_callback = NULL;
11521154

11531155
PyObject_GC_Track(self);
11541156
return self;
1157+
1158+
error:
1159+
PyMem_Free(memo);
1160+
Py_XDECREF(output_buffer);
1161+
return NULL;
11551162
}
11561163

11571164
static int
@@ -1602,13 +1609,29 @@ _Unpickler_MemoCleanup(UnpicklerObject *self)
16021609
static UnpicklerObject *
16031610
_Unpickler_New(void)
16041611
{
1605-
UnpicklerObject *self;
1606-
1607-
self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
1608-
if (self == NULL)
1612+
const int MEMO_SIZE = 32;
1613+
PyObject **memo = _Unpickler_NewMemo(MEMO_SIZE);
1614+
if (memo == NULL) {
16091615
return NULL;
1616+
}
1617+
1618+
PyObject *stack = Pdata_New();
1619+
if (stack == NULL) {
1620+
goto error;
1621+
}
16101622

1623+
UnpicklerObject *self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
1624+
if (self == NULL) {
1625+
goto error;
1626+
}
1627+
1628+
self->stack = (Pdata *)stack;
1629+
self->memo = memo;
1630+
self->memo_size = MEMO_SIZE;
1631+
self->memo_len = 0;
16111632
self->pers_func = NULL;
1633+
self->pers_func_self = NULL;
1634+
memset(&self->buffer, 0, sizeof(Py_buffer));
16121635
self->input_buffer = NULL;
16131636
self->input_line = NULL;
16141637
self->input_len = 0;
@@ -1626,22 +1649,14 @@ _Unpickler_New(void)
16261649
self->marks_size = 0;
16271650
self->proto = 0;
16281651
self->fix_imports = 0;
1629-
memset(&self->buffer, 0, sizeof(Py_buffer));
1630-
self->memo_size = 32;
1631-
self->memo_len = 0;
1632-
self->memo = _Unpickler_NewMemo(self->memo_size);
1633-
if (self->memo == NULL) {
1634-
Py_DECREF(self);
1635-
return NULL;
1636-
}
1637-
self->stack = (Pdata *)Pdata_New();
1638-
if (self->stack == NULL) {
1639-
Py_DECREF(self);
1640-
return NULL;
1641-
}
16421652

16431653
PyObject_GC_Track(self);
16441654
return self;
1655+
1656+
error:
1657+
PyMem_Free(memo);
1658+
Py_XDECREF(stack);
1659+
return NULL;
16451660
}
16461661

16471662
/* Returns -1 (with an exception set) on failure, 0 on success. This may

0 commit comments

Comments
 (0)