Commit 679e9d36 authored by Antoine Pitrou's avatar Antoine Pitrou

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

parent b2b18632
#!/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): ...@@ -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(): ...@@ -243,6 +265,7 @@ def test_main():
CodeTestCase, CodeTestCase,
ContainerTestCase, ContainerTestCase,
ExceptionTestCase, ExceptionTestCase,
BufferTestCase,
BugsTestCase) BugsTestCase)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -10,6 +10,9 @@ What's New in Python 3.2.3 release candidate 1? ...@@ -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.
......
...@@ -411,11 +411,12 @@ w_object(PyObject *v, WFILE *p) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment