Issue #14172: Fix reference leak when marshalling a buffer-like object (other than a bytes object).

This commit is contained in:
Antoine Pitrou 2012-03-02 18:12:43 +01:00
parent b2b18632ce
commit 679e9d36f7
3 changed files with 30 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from test import support from test import support
import array
import marshal import marshal
import sys import sys
import unittest import unittest
@ -137,6 +138,27 @@ class ContainerTestCase(unittest.TestCase, HelperMixin):
for constructor in (set, frozenset): for constructor in (set, frozenset):
self.helper(constructor(self.d.keys())) self.helper(constructor(self.d.keys()))
class BufferTestCase(unittest.TestCase, HelperMixin):
def test_bytearray(self):
b = bytearray(b"abc")
self.helper(b)
new = marshal.loads(marshal.dumps(b))
self.assertEqual(type(new), bytes)
def test_memoryview(self):
b = memoryview(b"abc")
self.helper(b)
new = marshal.loads(marshal.dumps(b))
self.assertEqual(type(new), bytes)
def test_array(self):
a = array.array('B', b"abc")
new = marshal.loads(marshal.dumps(a))
self.assertEqual(new, b"abc")
class BugsTestCase(unittest.TestCase): class BugsTestCase(unittest.TestCase):
def test_bug_5888452(self): def test_bug_5888452(self):
# Simple-minded check for SF 588452: Debug build crashes # Simple-minded check for SF 588452: Debug build crashes
@ -243,6 +265,7 @@ def test_main():
CodeTestCase, CodeTestCase,
ContainerTestCase, ContainerTestCase,
ExceptionTestCase, ExceptionTestCase,
BufferTestCase,
BugsTestCase) BugsTestCase)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -10,6 +10,9 @@ What's New in Python 3.2.3 release candidate 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #14172: Fix reference leak when marshalling a buffer-like object
(other than a bytes object).
- Issue #13521: dict.setdefault() now does only one lookup for the given key, - Issue #13521: dict.setdefault() now does only one lookup for the given key,
making it "atomic" for many purposes. Patch by Filip Gruszczyński. making it "atomic" for many purposes. Patch by Filip Gruszczyński.

View File

@ -411,11 +411,12 @@ w_object(PyObject *v, WFILE *p)
else if (PyObject_CheckBuffer(v)) { else if (PyObject_CheckBuffer(v)) {
/* Write unknown buffer-style objects as a string */ /* Write unknown buffer-style objects as a string */
char *s; char *s;
PyBufferProcs *pb = v->ob_type->tp_as_buffer;
Py_buffer view; Py_buffer view;
if ((*pb->bf_getbuffer)(v, &view, PyBUF_SIMPLE) != 0) { if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
w_byte(TYPE_UNKNOWN, p); w_byte(TYPE_UNKNOWN, p);
p->depth--;
p->error = WFERR_UNMARSHALLABLE; p->error = WFERR_UNMARSHALLABLE;
return;
} }
w_byte(TYPE_STRING, p); w_byte(TYPE_STRING, p);
n = view.len; n = view.len;
@ -427,8 +428,7 @@ w_object(PyObject *v, WFILE *p)
} }
w_long((long)n, p); w_long((long)n, p);
w_string(s, (int)n, p); w_string(s, (int)n, p);
if (pb->bf_releasebuffer != NULL) PyBuffer_Release(&view);
(*pb->bf_releasebuffer)(v, &view);
} }
else { else {
w_byte(TYPE_UNKNOWN, p); w_byte(TYPE_UNKNOWN, p);