Discussion:
[Python-3000-checkins] r66047 - in python/branches/py3k: Include/object.h Misc/NEWS Modules/binascii.c Objects/abstract.c Python/getargs.c
benjamin.peterson
2008-08-27 00:31:37 UTC
Permalink
Author: benjamin.peterson
Date: Wed Aug 27 02:31:37 2008
New Revision: 66047

Log:
Fix #3651 various memory leaks when using the buffer interface

by Amaury Forgeot d'Arc
Reviewer: Antoine Pitrou


Modified:
python/branches/py3k/Include/object.h
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/binascii.c
python/branches/py3k/Objects/abstract.c
python/branches/py3k/Python/getargs.c

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h (original)
+++ python/branches/py3k/Include/object.h Wed Aug 27 02:31:37 2008
@@ -143,7 +143,7 @@
/* buffer interface */
typedef struct bufferinfo {
void *buf;
- PyObject *obj; /* borrowed reference */
+ PyObject *obj; /* owned reference */
Py_ssize_t len;
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
pointed to by strides in simple case.*/

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Aug 27 02:31:37 2008
@@ -21,6 +21,10 @@

- Issue #3663: Py_None was decref'd when printing SyntaxErrors.

+- Issue #3651: Fix various memory leaks when using the buffer
+ interface, or when the "s#" code of PyArg_ParseTuple is given a
+ bytes object.
+
- Issue #3657: Fix uninitialized memory read when pickling longs.
Found by valgrind.


Modified: python/branches/py3k/Modules/binascii.c
==============================================================================
--- python/branches/py3k/Modules/binascii.c (original)
+++ python/branches/py3k/Modules/binascii.c Wed Aug 27 02:31:37 2008
@@ -231,6 +231,7 @@
*/
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
PyErr_SetString(Error, "Illegal char");
+ PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -259,6 +260,7 @@
if ( this_ch != ' ' && this_ch != ' '+64 &&
this_ch != '\n' && this_ch != '\r' ) {
PyErr_SetString(Error, "Trailing garbage");
+ PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -805,6 +807,7 @@
** of the string only). This is a programmer error.
*/
PyErr_SetString(Error, "Orphaned RLE code at start");
+ PyBuffer_Release(&pin);
Py_DECREF(rv);
return NULL;
}

Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c (original)
+++ python/branches/py3k/Objects/abstract.c Wed Aug 27 02:31:37 2008
@@ -260,6 +260,7 @@
*buffer_len = view.len;
if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);
+ Py_XDECREF(view.obj);
return 0;
}

@@ -305,6 +306,7 @@
*buffer_len = view.len;
if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);
+ Py_XDECREF(view.obj);
return 0;
}

@@ -332,6 +334,7 @@
*buffer_len = view.len;
if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);
+ Py_XDECREF(view.obj);
return 0;
}


Modified: python/branches/py3k/Python/getargs.c
==============================================================================
--- python/branches/py3k/Python/getargs.c (original)
+++ python/branches/py3k/Python/getargs.c Wed Aug 27 02:31:37 2008
@@ -1245,7 +1245,7 @@
/* Caller is interested in Py_buffer, and the object
supports it directly. */
format++;
- if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
return converterr("read-write buffer", arg, msgbuf, bufsize);
}
@@ -1257,11 +1257,11 @@
/* Here we have processed w*, only w and w# remain. */
if (pb == NULL ||
pb->bf_getbuffer == NULL ||
- ((temp = (*pb->bf_getbuffer)(arg, &view,
- PyBUF_SIMPLE)) != 0) ||
+ ((temp = PyObject_GetBuffer(arg, &view,
+ PyBUF_SIMPLE)) != 0) ||
view.readonly == 1) {
- if (temp==0 && pb->bf_releasebuffer != NULL) {
- (*pb->bf_releasebuffer)(arg, &view);
+ if (temp==0) {
+ PyBuffer_Release(&view);
}
return converterr("single-segment read-write buffer",
arg, msgbuf, bufsize);
@@ -1295,7 +1295,7 @@
"bytes or read-only character buffer",
arg, msgbuf, bufsize);

- if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0)
+ if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0)
return converterr("string or single-segment read-only buffer",
arg, msgbuf, bufsize);

@@ -1306,6 +1306,8 @@
"string or pinned buffer",
arg, msgbuf, bufsize);

+ PyBuffer_Release(&view);
+
if (count < 0)
return converterr("(unspecified)", arg, msgbuf, bufsize);
{
@@ -1340,14 +1342,13 @@
return -1;
}

- if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0) {
+ if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) {
*errmsg = "bytes or single-segment read-only buffer";
return -1;
}
count = view.len;
*p = view.buf;
- if (pb->bf_releasebuffer != NULL)
- (*pb->bf_releasebuffer)(arg, &view);
+ PyBuffer_Release(&view);
return count;
}

@@ -1364,7 +1365,7 @@
return -1;
}
if (pb->bf_getbuffer) {
- if (pb->bf_getbuffer(arg, view, 0) < 0) {
+ if (PyObject_GetBuffer(arg, view, 0) < 0) {
*errmsg = "convertible to a buffer";
return -1;
}

Loading...