summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-06-12 21:35:07 (GMT)
committerGitHub <noreply@github.com>2023-06-12 21:35:07 (GMT)
commitca3cc4b95d66f7527ebe0ba4cdb1907082d9bfc8 (patch)
tree21c3f9a6ed64e53321adcb994f4575b46b5c3b05 /Modules
parentf0fb782ddb7208a59cfc38ec4bcbd8d1a81f8a58 (diff)
downloadcpython-ca3cc4b95d66f7527ebe0ba4cdb1907082d9bfc8.zip
cpython-ca3cc4b95d66f7527ebe0ba4cdb1907082d9bfc8.tar.gz
cpython-ca3cc4b95d66f7527ebe0ba4cdb1907082d9bfc8.tar.bz2
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.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_pickle.c90
1 files changed, 53 insertions, 37 deletions
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index e6eb9c7..9e70fee 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -1145,42 +1145,49 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len)
static PicklerObject *
_Pickler_New(PickleState *st)
{
- PicklerObject *self;
-
- self = PyObject_GC_New(PicklerObject, st->Pickler_Type);
- if (self == NULL)
+ PyMemoTable *memo = PyMemoTable_New();
+ if (memo == NULL) {
return NULL;
+ }
+
+ const Py_ssize_t max_output_len = WRITE_BUF_SIZE;
+ PyObject *output_buffer = PyBytes_FromStringAndSize(NULL, max_output_len);
+ if (output_buffer == NULL) {
+ goto error;
+ }
+ PicklerObject *self = PyObject_GC_New(PicklerObject, st->Pickler_Type);
+ if (self == NULL) {
+ goto error;
+ }
+
+ self->memo = memo;
self->pers_func = NULL;
+ self->pers_func_self = NULL;
self->dispatch_table = NULL;
- self->buffer_callback = NULL;
+ self->reducer_override = NULL;
self->write = NULL;
+ self->output_buffer = output_buffer;
+ self->output_len = 0;
+ self->max_output_len = max_output_len;
self->proto = 0;
self->bin = 0;
self->framing = 0;
self->frame_start = -1;
+ self->buf_size = 0;
self->fast = 0;
self->fast_nesting = 0;
self->fix_imports = 0;
self->fast_memo = NULL;
- self->max_output_len = WRITE_BUF_SIZE;
- self->output_len = 0;
- 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->output_buffer == NULL) {
- Py_DECREF(self);
- return NULL;
- }
+ self->buffer_callback = NULL;
PyObject_GC_Track(self);
return self;
+
+error:
+ PyMem_Free(memo);
+ Py_XDECREF(output_buffer);
+ return NULL;
}
static int
@@ -1628,14 +1635,31 @@ _Unpickler_MemoCleanup(UnpicklerObject *self)
static UnpicklerObject *
_Unpickler_New(PyObject *module)
{
- UnpicklerObject *self;
+ const int MEMO_SIZE = 32;
+ PyObject **memo = _Unpickler_NewMemo(MEMO_SIZE);
+ if (memo == NULL) {
+ return NULL;
+ }
+
PickleState *st = _Pickle_GetState(module);
+ PyObject *stack = Pdata_New(st);
+ if (stack == NULL) {
+ goto error;
+ }
- self = PyObject_GC_New(UnpicklerObject, st->Unpickler_Type);
- if (self == NULL)
- return NULL;
+ UnpicklerObject *self = PyObject_GC_New(UnpicklerObject,
+ st->Unpickler_Type);
+ if (self == NULL) {
+ goto error;
+ }
+ self->stack = (Pdata *)stack;
+ self->memo = memo;
+ self->memo_size = MEMO_SIZE;
+ self->memo_len = 0;
self->pers_func = NULL;
+ self->pers_func_self = NULL;
+ memset(&self->buffer, 0, sizeof(Py_buffer));
self->input_buffer = NULL;
self->input_line = NULL;
self->input_len = 0;
@@ -1653,22 +1677,14 @@ _Unpickler_New(PyObject *module)
self->marks_size = 0;
self->proto = 0;
self->fix_imports = 0;
- memset(&self->buffer, 0, sizeof(Py_buffer));
- 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->stack == NULL) {
- Py_DECREF(self);
- return NULL;
- }
PyObject_GC_Track(self);
return self;
+
+error:
+ PyMem_Free(memo);
+ Py_XDECREF(stack);
+ return NULL;
}
/* Returns -1 (with an exception set) on failure, 0 on success. This may