Issue #14172: Fix reference leak when marshalling a buffer-like object (other than a bytes object).
This commit is contained in:
parent
b2b18632ce
commit
679e9d36f7
|
@ -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__":
|
||||||
|
|
|
@ -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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue