From a03e2b28c1fd59e94d89577410b69779dce45d1c Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Tue, 15 May 2018 08:13:06 -0500 Subject: [PATCH] Don't leak objects in _pickle_27.c load_[short_]binbytes. Fixes #36. --- CHANGES.rst | 5 +++-- setup.py | 2 +- src/zodbpickle/_pickle_27.c | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index adee753..67eca0d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,10 +1,11 @@ ``zodbpickle`` Changelog ======================== -1.1 (unreleased) +1.0.1 (unreleased) ---------------- -- Nothing changed yet. +- Fix a memory leak in pickle protocol 3 under Python 2. See `issue 36 + `_. 1.0 (2018-02-09) diff --git a/setup.py b/setup.py index 6c97315..f5f356d 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ setup( name='zodbpickle', - version='1.1.dev0', + version='1.0.1.dev0', description='Fork of Python 3 pickle module.', author='Python and Zope Foundation', author_email='zodb-dev@zope.org', diff --git a/src/zodbpickle/_pickle_27.c b/src/zodbpickle/_pickle_27.c index aa4fac7..a990a6f 100644 --- a/src/zodbpickle/_pickle_27.c +++ b/src/zodbpickle/_pickle_27.c @@ -3900,12 +3900,24 @@ load_binbytes(Unpicklerobject *self) return -1; if (!( args = PyTuple_New(1) )) - return -1; + goto done; if (!(PyTuple_SET_ITEM(args, 0, py_string))) - return -1; + /* practically speaking this macro cannot fail */ + goto done; if (!( py_binary = PyObject_CallObject(BinaryType, args))) + goto done; + +done: + if (!args) { + /* The tuple steals the string reference, + * so we don't need to decref it if we have the tuple. + */ + Py_XDECREF(py_string); + } + Py_XDECREF(args); + if ( !py_binary ) return -1; PDATA_PUSH(self->stack, py_binary, -1); @@ -3929,15 +3941,28 @@ load_short_binbytes(Unpicklerobject *self) if (self->read_func(self, &s, l) < 0) return -1; - if (!( py_string = PyString_FromStringAndSize(s, l))) return -1; + if (!( py_string = PyString_FromStringAndSize(s, l))) + return -1; if (!( args = PyTuple_New(1) )) - return -1; + goto done; if (!(PyTuple_SET_ITEM(args, 0, py_string))) - return -1; + /* practically speaking this macro cannot fail */ + goto done; if (!( py_binary = PyObject_CallObject(BinaryType, args))) + goto done; + +done: + if (!args) { + /* The tuple steals the string reference, + * so we don't need to decref it if we have the tuple. + */ + Py_XDECREF(py_string); + } + Py_XDECREF(args); + if ( !py_binary ) return -1; PDATA_PUSH(self->stack, py_binary, -1);