Discussion:
[Python-3000-checkins] r65661 - in python/branches/py3k: Doc/c-api/arg.rst Doc/whatsnew/2.6.rst Include/abstract.h Include/object.h Lib/test/test_sys.py Modules/_bsddb.c Modules/_codecsmodule.c Modules/_ctypes/_ctypes.c Modules/_fileio.c Modules/_hashopenssl.c Modules/_json.c Modules/_multiprocessing/connection.h Modules/_sre.c Modules/_struct.c Modules/arraymodule.c Modules/audioop.c Modules/binascii.c Modules/bz2module.c Modules/cjkcodecs/multibytecodec.c Modules/fcntlmodule.c Modules/mmapmodule.c Modules/posixmodule.c Modules/socketmodule.c Modules/zlibmodule.c Objects/abstract.c Objects/bytearrayobject.c Objects/bytesobject.c Objects/memoryobject.c Objects/unicodeobject.c PC/winreg.c Python/getargs.c Python/marshal.c
martin.v.loewis
2008-08-13 15:53:09 UTC
Permalink
Author: martin.v.loewis
Date: Wed Aug 13 17:53:07 2008
New Revision: 65661

Log:
Merged revisions 65654 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/trunk

........
r65654 | martin.v.loewis | 2008-08-12 16:49:50 +0200 (Tue, 12 Aug 2008) | 6 lines

Issue #3139: Make buffer-interface thread-safe wrt. PyArg_ParseTuple,
by denying s# to parse objects that have a releasebuffer procedure,
and introducing s*.

More module might need to get converted to use s*.
........


Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Doc/c-api/arg.rst
python/branches/py3k/Doc/whatsnew/2.6.rst
python/branches/py3k/Include/abstract.h
python/branches/py3k/Include/object.h
python/branches/py3k/Lib/test/test_sys.py
python/branches/py3k/Modules/_bsddb.c
python/branches/py3k/Modules/_codecsmodule.c
python/branches/py3k/Modules/_ctypes/_ctypes.c
python/branches/py3k/Modules/_fileio.c
python/branches/py3k/Modules/_hashopenssl.c
python/branches/py3k/Modules/_json.c
python/branches/py3k/Modules/_multiprocessing/connection.h
python/branches/py3k/Modules/_sre.c
python/branches/py3k/Modules/_struct.c
python/branches/py3k/Modules/arraymodule.c
python/branches/py3k/Modules/audioop.c
python/branches/py3k/Modules/binascii.c
python/branches/py3k/Modules/bz2module.c
python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
python/branches/py3k/Modules/fcntlmodule.c
python/branches/py3k/Modules/mmapmodule.c
python/branches/py3k/Modules/posixmodule.c
python/branches/py3k/Modules/socketmodule.c
python/branches/py3k/Modules/zlibmodule.c
python/branches/py3k/Objects/abstract.c
python/branches/py3k/Objects/bytearrayobject.c
python/branches/py3k/Objects/bytesobject.c
python/branches/py3k/Objects/memoryobject.c
python/branches/py3k/Objects/unicodeobject.c
python/branches/py3k/PC/winreg.c
python/branches/py3k/Python/getargs.c
python/branches/py3k/Python/marshal.c

Modified: python/branches/py3k/Doc/c-api/arg.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/arg.rst (original)
+++ python/branches/py3k/Doc/c-api/arg.rst Wed Aug 13 17:53:07 2008
@@ -40,6 +40,12 @@
other read-buffer compatible objects pass back a reference to the raw internal
data representation.

+``s*`` (string, Unicode, or any buffer compatible object) [Py_buffer \*]
+ Similar to ``s#``, this code fills a Py_buffer structure provided by the caller.
+ The buffer gets locked, so that the caller can subsequently use the buffer even
+ inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is responsible for calling
+ ``PyBuffer_Release`` with the structure after it has processed the data.
+
``y`` (bytes object) [const char \*]
This variant on ``s`` convert a Python bytes object to a C pointer to a
character string. The bytes object must not contain embedded NUL bytes; if it
@@ -49,6 +55,9 @@
This variant on ``s#`` stores into two C variables, the first one a pointer to a
character string, the second one its length. This only accepts bytes objects.

+``y*`` (bytes object) [Py_buffer \*]
+ This is to ``s*`` as ``y`` is to ``s``.
+
``z`` (string or ``None``) [const char \*]
Like ``s``, but the Python object may also be ``None``, in which case the C
pointer is set to *NULL*.
@@ -56,6 +65,9 @@
``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int]
This is to ``s#`` as ``z`` is to ``s``.

+``z*`` (string or ``None`` or any buffer compatible object) [Py_buffer*]
+ This is to ``s*`` as ``z`` is to ``s``.
+
``u`` (Unicode object) [Py_UNICODE \*]
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide
@@ -244,6 +256,9 @@
single-segment buffer objects are accepted; :exc:`TypeError` is raised for all
others.

+``w*`` (read-write byte-oriented buffer) [Py_buffer \*]
+ This is to ``w`` what ``s*`` is to ``s``.
+
``(items)`` (tuple) [*matching-items*]
The object must be a Python sequence whose length is the number of format units
in *items*. The C arguments must correspond to the individual format units in

Modified: python/branches/py3k/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.6.rst (original)
+++ python/branches/py3k/Doc/whatsnew/2.6.rst Wed Aug 13 17:53:07 2008
@@ -1064,7 +1064,7 @@
can use this operation to lock memory in place
while an external caller could be modifying the contents,
so there's a corresponding
-``PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)`` to
+``PyBuffer_Release(Py_buffer *view)`` to
indicate that the external caller is done.

The **flags** argument to :cfunc:`PyObject_GetBuffer` specifies
@@ -2841,7 +2841,7 @@

* The new buffer interface, previously described in
`the PEP 3118 section <#pep-3118-revised-buffer-protocol>`__,
- adds :cfunc:`PyObject_GetBuffer` and :cfunc:`PyObject_ReleaseBuffer`,
+ adds :cfunc:`PyObject_GetBuffer` and :cfunc:`PyBuffer_Release`,
as well as a few other functions.

* Python's use of the C stdio library is now thread-safe, or at least

Modified: python/branches/py3k/Include/abstract.h
==============================================================================
--- python/branches/py3k/Include/abstract.h (original)
+++ python/branches/py3k/Include/abstract.h Wed Aug 13 17:53:07 2008
@@ -526,24 +526,6 @@
*/


- PyAPI_FUNC(void) PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view);
-
-
- /* C-API version of the releasebuffer function call. It
- checks to make sure the object has the required function
- pointer and issues the call. The obj must have the buffer
- interface or this function will cause a segfault (i.e. it
- is assumed to be called only after a corresponding
- getbuffer which already verified the existence of the
- tp_as_buffer pointer).
-
- Returns 0 on success and -1 (with an error raised) on
- failure. This function always succeeds (as a NO-OP) if
- there is no releasebuffer function for the object so that
- it can always be called when the consumer is done with the
- buffer
- */
-
PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);

/* Get the memory area pointed to by the indices for the buffer given.
@@ -600,7 +582,7 @@
per element.
*/

- PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, void *buf,
+ PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
Py_ssize_t len, int readonly,
int flags);

@@ -610,6 +592,10 @@
and -1 (with raising an error) on error.
*/

+ PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
+
+ /* Releases a Py_buffer obtained from getbuffer ParseTuple's s*.
+ */

PyAPI_FUNC(PyObject *) PyObject_Format(PyObject* obj,
PyObject *format_spec);

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h (original)
+++ python/branches/py3k/Include/object.h Wed Aug 13 17:53:07 2008
@@ -142,7 +142,8 @@

/* buffer interface */
typedef struct bufferinfo {
- void *buf;
+ void *buf;
+ PyObject *obj; /* borrowed 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/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py (original)
+++ python/branches/py3k/Lib/test/test_sys.py Wed Aug 13 17:53:07 2008
@@ -550,7 +550,7 @@
check(32768*32768-1, size(vh) + 2*self.H)
check(32768*32768, size(vh) + 3*self.H)
# memory
- check(memoryview(b''), size(h + 'P P2P2i5P'))
+ check(memoryview(b''), size(h + 'P PP2P2i5P'))
# module
check(unittest, size(h + '3P'))
# None

Modified: python/branches/py3k/Modules/_bsddb.c
==============================================================================
--- python/branches/py3k/Modules/_bsddb.c (original)
+++ python/branches/py3k/Modules/_bsddb.c Wed Aug 13 17:53:07 2008
@@ -288,7 +288,7 @@
static void free_buf_view(PyObject *obj, Py_buffer *view)
{
if (view) {
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
PyMem_Free(view);
}
}
@@ -319,7 +319,7 @@
if (view->ndim > 1) {
PyErr_SetString(PyExc_BufferError,
"buffers must be single dimension");
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
PyMem_Free(view);
return NULL;
}

Modified: python/branches/py3k/Modules/_codecsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_codecsmodule.c (original)
+++ python/branches/py3k/Modules/_codecsmodule.c Wed Aug 13 17:53:07 2008
@@ -252,20 +252,20 @@
utf_7_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_7_decode",
- &data, &size, &errors, &final))
- return NULL;
- consumed = size;
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_7_decode",
+ &pbuf, &errors, &final))
+ return NULL;
+ consumed = pbuf.len;

- decoded = PyUnicode_DecodeUTF7Stateful(data, size, errors,
- final ? NULL : &consumed);
+ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors,
+ final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -275,24 +275,20 @@
utf_8_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_8_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size;
-
- decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
+ consumed = pbuf.len;
+
+ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors,
final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -302,24 +298,20 @@
utf_16_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -329,53 +321,45 @@
utf_16_le_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_le_decode",
+ &pbuf, &errors, &final))
return NULL;

- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
-
}

static PyObject *
utf_16_be_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_be_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -393,24 +377,20 @@
utf_16_ex_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;

- if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
- &data, &size, &errors, &byteorder, &final))
+ if (!PyArg_ParseTuple(args, "s*|zii:utf_16_ex_decode",
+ &pbuf, &errors, &byteorder, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@@ -422,24 +402,20 @@
utf_32_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -449,53 +425,43 @@
utf_32_le_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
- PyObject *decoded = NULL;
+ PyObject *decoded;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_le_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_le_decode",
+ &pbuf, &errors, &final))
return NULL;
-
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
- &byteorder, final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
-
}

static PyObject *
utf_32_be_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
- PyObject *decoded = NULL;
+ PyObject *decoded;

- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_be_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_be_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
- &byteorder, final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -513,24 +479,20 @@
utf_32_ex_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;

- if (!PyArg_ParseTuple(args, "t#|zii:utf_32_ex_decode",
- &data, &size, &errors, &byteorder, &final))
+ if (!PyArg_ParseTuple(args, "s*|zii:utf_32_ex_decode",
+ &pbuf, &errors, &byteorder, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- unicode = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@@ -542,83 +504,88 @@
unicode_escape_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
+ PyObject *unicode;

- if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode",
+ &pbuf, &errors))
return NULL;

- return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}

static PyObject *
raw_unicode_escape_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
+ PyObject *unicode;

- if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode",
+ &pbuf, &errors))
return NULL;

- return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}

static PyObject *
latin_1_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;

- if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode",
+ &pbuf, &errors))
return NULL;

- return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}

static PyObject *
ascii_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;

- if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:ascii_decode",
+ &pbuf, &errors))
return NULL;

- return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}

static PyObject *
charmap_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;
PyObject *mapping = NULL;

- if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
- &data, &size, &errors, &mapping))
+ if (!PyArg_ParseTuple(args, "s*|zO:charmap_decode",
+ &pbuf, &errors, &mapping))
return NULL;
if (mapping == Py_None)
mapping = NULL;

- return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
- size);
+ unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}

#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
@@ -627,21 +594,23 @@
mbcs_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size, consumed;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
- PyObject *decoded;
+ Py_ssize_t consumed;
+ PyObject *decoded = NULL;

- if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:mbcs_decode",
+ &pbuf, &errors, &final))
return NULL;
+ consumed = pbuf.len;

- decoded = PyUnicode_DecodeMBCSStateful(
- data, size, errors, final ? NULL : &consumed);
- if (!decoded)
+ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors,
+ final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
+ if (decoded == NULL)
return NULL;
- return codec_tuple(decoded, final ? size : consumed);
+ return codec_tuple(decoded, consumed);
}

#endif /* MS_WINDOWS */
@@ -652,15 +621,21 @@
readbuffer_encode(PyObject *self,
PyObject *args)
{
+ Py_buffer pdata;
const char *data;
Py_ssize_t size;
const char *errors = NULL;
+ PyObject *result;

- if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode",
+ &pdata, &errors))
return NULL;
+ data = pdata.buf;
+ size = pdata.len;

- return codec_tuple(PyBytes_FromStringAndSize(data, size), size);
+ result = PyBytes_FromStringAndSize(data, size);
+ PyBuffer_Release(&pdata);
+ return codec_tuple(result, size);
}

static PyObject *

Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c (original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c Wed Aug 13 17:53:07 2008
@@ -1050,10 +1050,10 @@

memcpy(self->b_ptr, ptr, size);

- PyObject_ReleaseBuffer(value, &view);
+ PyBuffer_Release(&view);
return 0;
fail:
- PyObject_ReleaseBuffer(value, &view);
+ PyBuffer_Release(&view);
return -1;
}

@@ -2462,6 +2462,8 @@
if (view == NULL) return 0;

view->buf = self->b_ptr;
+ view->obj = _self;
+ Py_INCREF(_self);
view->len = self->b_size;
view->readonly = 0;
/* use default format character if not set */

Modified: python/branches/py3k/Modules/_fileio.c
==============================================================================
--- python/branches/py3k/Modules/_fileio.c (original)
+++ python/branches/py3k/Modules/_fileio.c Wed Aug 13 17:53:07 2008
@@ -357,7 +357,7 @@
static PyObject *
fileio_readinto(PyFileIOObject *self, PyObject *args)
{
- char *ptr;
+ Py_buffer pbuf;
Py_ssize_t n;

if (self->fd < 0)
@@ -365,13 +365,14 @@
if (!self->readable)
return err_mode("reading");

- if (!PyArg_ParseTuple(args, "w#", &ptr, &n))
+ if (!PyArg_ParseTuple(args, "w*", &pbuf))
return NULL;

Py_BEGIN_ALLOW_THREADS
errno = 0;
- n = read(self->fd, ptr, n);
+ n = read(self->fd, pbuf.buf, pbuf.len);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (n < 0) {
if (errno == EAGAIN)
Py_RETURN_NONE;
@@ -489,22 +490,24 @@
static PyObject *
fileio_write(PyFileIOObject *self, PyObject *args)
{
+ Py_buffer pbuf;
Py_ssize_t n;
- char *ptr;

if (self->fd < 0)
return err_closed();
if (!self->writable)
return err_mode("writing");

- if (!PyArg_ParseTuple(args, "s#", &ptr, &n))
+ if (!PyArg_ParseTuple(args, "s*", &pbuf))
return NULL;

Py_BEGIN_ALLOW_THREADS
errno = 0;
- n = write(self->fd, ptr, n);
+ n = write(self->fd, pbuf.buf, pbuf.len);
Py_END_ALLOW_THREADS

+ PyBuffer_Release(&pbuf);
+
if (n < 0) {
if (errno == EAGAIN)
Py_RETURN_NONE;

Modified: python/branches/py3k/Modules/_hashopenssl.c
==============================================================================
--- python/branches/py3k/Modules/_hashopenssl.c (original)
+++ python/branches/py3k/Modules/_hashopenssl.c Wed Aug 13 17:53:07 2008
@@ -164,7 +164,7 @@
if ((viewp)->ndim > 1) { \
PyErr_SetString(PyExc_BufferError, \
"Buffer must be single dimension"); \
- PyObject_ReleaseBuffer((obj), (viewp)); \
+ PyBuffer_Release((viewp)); \
return NULL; \
} \
} while(0);
@@ -186,7 +186,7 @@
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));

- PyObject_ReleaseBuffer(obj, &view);
+ PyBuffer_Release(&view);

Py_INCREF(Py_None);
return Py_None;
@@ -267,7 +267,7 @@
if (!PyArg_Parse(name_obj, "s", &nameStr)) {
PyErr_SetString(PyExc_TypeError, "name must be a string");
if (data_obj)
- PyObject_ReleaseBuffer(data_obj, &view);
+ PyBuffer_Release(&view);
return -1;
}

@@ -275,7 +275,7 @@
if (!digest) {
PyErr_SetString(PyExc_ValueError, "unknown hash function");
if (data_obj)
- PyObject_ReleaseBuffer(data_obj, &view);
+ PyBuffer_Release(&view);
return -1;
}
EVP_DigestInit(&self->ctx, digest);
@@ -286,7 +286,7 @@
if (data_obj) {
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
- PyObject_ReleaseBuffer(data_obj, &view);
+ PyBuffer_Release(&view);
}

return 0;
@@ -421,7 +421,7 @@
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));

if (data_obj)
- PyObject_ReleaseBuffer(data_obj, &view);
+ PyBuffer_Release(&view);
return ret_obj;
}

@@ -455,7 +455,7 @@
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int)); \
\
if (data_obj) \
- PyObject_ReleaseBuffer(data_obj, &view); \
+ PyBuffer_Release(&view); \
return ret_obj; \
}


Modified: python/branches/py3k/Modules/_json.c
==============================================================================
--- python/branches/py3k/Modules/_json.c (original)
+++ python/branches/py3k/Modules/_json.c Wed Aug 13 17:53:07 2008
@@ -261,7 +261,7 @@
/* Pick up this chunk if it's not zero length */
if (next != end) {
PyObject *strchunk;
- if (PyBuffer_FillInfo(&info, &buf[end], next - end, 1, 0) < 0) {
+ if (PyBuffer_FillInfo(&info, NULL, &buf[end], next - end, 1, 0) < 0) {
goto bail;
}
strchunk = PyMemoryView_FromMemory(&info);

Modified: python/branches/py3k/Modules/_multiprocessing/connection.h
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/connection.h (original)
+++ python/branches/py3k/Modules/_multiprocessing/connection.h Wed Aug 13 17:53:07 2008
@@ -96,21 +96,26 @@
static PyObject *
connection_sendbytes(ConnectionObject *self, PyObject *args)
{
+ Py_buffer pbuffer;
char *buffer;
Py_ssize_t length, offset=0, size=PY_SSIZE_T_MIN;
int res;

- if (!PyArg_ParseTuple(args, F_RBUFFER "#|" F_PY_SSIZE_T F_PY_SSIZE_T,
- &buffer, &length, &offset, &size))
+ if (!PyArg_ParseTuple(args, F_RBUFFER "*|" F_PY_SSIZE_T F_PY_SSIZE_T,
+ &pbuffer, &offset, &size))
return NULL;
+ buffer = pbuffer.buf;
+ length = pbuffer.len;

- CHECK_WRITABLE(self);
+ CHECK_WRITABLE(self); /* XXX release buffer in case of failure */

if (offset < 0) {
+ PyBuffer_Release(&pbuffer);
PyErr_SetString(PyExc_ValueError, "offset is negative");
return NULL;
}
if (length < offset) {
+ PyBuffer_Release(&pbuffer);
PyErr_SetString(PyExc_ValueError, "buffer length < offset");
return NULL;
}
@@ -119,10 +124,12 @@
size = length - offset;
} else {
if (size < 0) {
+ PyBuffer_Release(&pbuffer);
PyErr_SetString(PyExc_ValueError, "size is negative");
return NULL;
}
if (offset + size > length) {
+ PyBuffer_Release(&pbuffer);
PyErr_SetString(PyExc_ValueError,
"buffer length < offset + size");
return NULL;
@@ -131,6 +138,7 @@

res = conn_send_string(self, buffer + offset, size);

+ PyBuffer_Release(&pbuffer);
if (res < 0)
return mp_SetError(PyExc_IOError, res);

@@ -187,21 +195,25 @@
char *freeme = NULL, *buffer = NULL;
Py_ssize_t res, length, offset = 0;
PyObject *result = NULL;
+ Py_buffer pbuf;

- if (!PyArg_ParseTuple(args, "w#|" F_PY_SSIZE_T,
- &buffer, &length, &offset))
+ CHECK_READABLE(self);
+
+ if (!PyArg_ParseTuple(args, "w*|" F_PY_SSIZE_T,
+ &pbuf, &offset))
return NULL;

- CHECK_READABLE(self);
+ buffer = pbuf.buf;
+ length = pbuf.len;

if (offset < 0) {
PyErr_SetString(PyExc_ValueError, "negative offset");
- return NULL;
+ goto _error;
}

if (offset > length) {
PyErr_SetString(PyExc_ValueError, "offset too large");
- return NULL;
+ goto _error;
}

res = conn_recv_string(self, buffer+offset, length-offset,
@@ -231,11 +243,17 @@
PyErr_SetObject(BufferTooShort, result);
Py_DECREF(result);
}
- return NULL;
+ goto _error;
}
}

+_cleanup:
+ PyBuffer_Release(&pbuf);
return result;
+
+_error:
+ result = NULL;
+ goto _cleanup;
}

/*

Modified: python/branches/py3k/Modules/_sre.c
==============================================================================
--- python/branches/py3k/Modules/_sre.c (original)
+++ python/branches/py3k/Modules/_sre.c Wed Aug 13 17:53:07 2008
@@ -1704,7 +1704,7 @@
/* Release the buffer immediately --- possibly dangerous
but doing something else would require some re-factoring
*/
- PyObject_ReleaseBuffer(string, &view);
+ PyBuffer_Release(&view);

if (bytes < 0) {
PyErr_SetString(PyExc_TypeError, "buffer has negative size");

Modified: python/branches/py3k/Modules/_struct.c
==============================================================================
--- python/branches/py3k/Modules/_struct.c (original)
+++ python/branches/py3k/Modules/_struct.c Wed Aug 13 17:53:07 2008
@@ -1567,11 +1567,11 @@
PyErr_Format(StructError,
"unpack requires a bytes argument of length %zd",
soself->s_size);
- PyObject_ReleaseBuffer(input, &vbuf);
+ PyBuffer_Release(&vbuf);
return NULL;
}
result = s_unpack_internal(soself, vbuf.buf);
- PyObject_ReleaseBuffer(input, &vbuf);
+ PyBuffer_Release(&vbuf);
return result;
}

@@ -1609,11 +1609,11 @@
PyErr_Format(StructError,
"unpack_from requires a buffer of at least %zd bytes",
soself->s_size);
- PyObject_ReleaseBuffer(input, &vbuf);
+ PyBuffer_Release(&vbuf);
return NULL;
}
result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
- PyObject_ReleaseBuffer(input, &vbuf);
+ PyBuffer_Release(&vbuf);
return result;
}


Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c (original)
+++ python/branches/py3k/Modules/arraymodule.c Wed Aug 13 17:53:07 2008
@@ -1820,6 +1820,8 @@
if (view==NULL) goto finish;

view->buf = (void *)self->ob_item;
+ view->obj = (PyObject*)self;
+ Py_INCREF(self);
if (view->buf == NULL)
view->buf = (void *)emptybuf;
view->len = (Py_SIZE(self)) * self->ob_descr->itemsize;

Modified: python/branches/py3k/Modules/audioop.c
==============================================================================
--- python/branches/py3k/Modules/audioop.c (original)
+++ python/branches/py3k/Modules/audioop.c Wed Aug 13 17:53:07 2008
@@ -783,20 +783,24 @@
static PyObject *
audioop_tomono(PyObject *self, PyObject *args)
{
+ Py_buffer pcp;
signed char *cp, *ncp;
int len, size, val1 = 0, val2 = 0;
double fac1, fac2, fval, maxval;
PyObject *rv;
int i;

- if ( !PyArg_ParseTuple(args, "s#idd:tomono",
- &cp, &len, &size, &fac1, &fac2 ) )
+ if ( !PyArg_ParseTuple(args, "s*idd:tomono",
+ &pcp, &size, &fac1, &fac2 ) )
return 0;
+ cp = pcp.buf;
+ len = pcp.len;

if ( size == 1 ) maxval = (double) 0x7f;
else if ( size == 2 ) maxval = (double) 0x7fff;
else if ( size == 4 ) maxval = (double) 0x7fffffff;
else {
+ PyBuffer_Release(&pcp);
PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
return 0;
}
@@ -822,6 +826,7 @@
else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
}
+ PyBuffer_Release(&pcp);
return rv;
}


Modified: python/branches/py3k/Modules/binascii.c
==============================================================================
--- python/branches/py3k/Modules/binascii.c (original)
+++ python/branches/py3k/Modules/binascii.c Wed Aug 13 17:53:07 2008
@@ -188,6 +188,7 @@
static PyObject *
binascii_a2b_uu(PyObject *self, PyObject *args)
{
+ Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -195,8 +196,10 @@
PyObject *rv;
Py_ssize_t ascii_len, bin_len;

- if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) )
+ if ( !PyArg_ParseTuple(args, "y*:a2b_uu", &pascii) )
return NULL;
+ ascii_data = pascii.buf;
+ ascii_len = pascii.len;

assert(ascii_len >= 0);

@@ -205,8 +208,10 @@
ascii_len--;

/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
+ PyBuffer_Release(&pascii);
return NULL;
+ }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);

for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
@@ -258,6 +263,7 @@
return NULL;
}
}
+ PyBuffer_Release(&pascii);
return rv;
}

@@ -266,6 +272,7 @@
static PyObject *
binascii_b2a_uu(PyObject *self, PyObject *args)
{
+ Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -273,17 +280,22 @@
PyObject *rv;
Py_ssize_t bin_len;

- if ( !PyArg_ParseTuple(args, "s#:b2a_uu", &bin_data, &bin_len) )
+ if ( !PyArg_ParseTuple(args, "s*:b2a_uu", &pbin) )
return NULL;
+ bin_data = pbin.buf;
+ bin_len = pbin.len;
if ( bin_len > 45 ) {
/* The 45 is a limit that appears in all uuencode's */
PyErr_SetString(Error, "At most 45 bytes at once");
+ PyBuffer_Release(&pbin);
return NULL;
}

/* We're lazy and allocate to much (fixed up later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2+2)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2+2)) == NULL ) {
+ PyBuffer_Release(&pbin);
return NULL;
+ }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);

/* Store the length */
@@ -312,6 +324,7 @@
Py_DECREF(rv);
rv = NULL;
}
+ PyBuffer_Release(&pbin);
return rv;
}

@@ -346,6 +359,7 @@
static PyObject *
binascii_a2b_base64(PyObject *self, PyObject *args)
{
+ Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -354,19 +368,25 @@
Py_ssize_t ascii_len, bin_len;
int quad_pos = 0;

- if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) )
+ if ( !PyArg_ParseTuple(args, "y*:a2b_base64", &pascii) )
return NULL;
+ ascii_data = pascii.buf;
+ ascii_len = pascii.len;

assert(ascii_len >= 0);

- if (ascii_len > PY_SSIZE_T_MAX - 3)
+ if (ascii_len > PY_SSIZE_T_MAX - 3) {
+ PyBuffer_Release(&pascii);
return PyErr_NoMemory();
+ }

bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */

/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
+ PyBuffer_Release(&pascii);
return NULL;
+ }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
bin_len = 0;

@@ -419,6 +439,7 @@
}

if (leftbits != 0) {
+ PyBuffer_Release(&pascii);
PyErr_SetString(Error, "Incorrect padding");
Py_DECREF(rv);
return NULL;
@@ -438,6 +459,7 @@
Py_DECREF(rv);
rv = PyBytes_FromStringAndSize("", 0);
}
+ PyBuffer_Release(&pascii);
return rv;
}

@@ -446,6 +468,7 @@
static PyObject *
binascii_b2a_base64(PyObject *self, PyObject *args)
{
+ Py_buffer pbuf;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -453,21 +476,26 @@
PyObject *rv;
Py_ssize_t bin_len;

- if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) )
+ if ( !PyArg_ParseTuple(args, "s*:b2a_base64", &pbuf) )
return NULL;
+ bin_data = pbuf.buf;
+ bin_len = pbuf.len;

assert(bin_len >= 0);

if ( bin_len > BASE64_MAXBIN ) {
PyErr_SetString(Error, "Too much data for base64 line");
+ PyBuffer_Release(&pbuf);
return NULL;
}

/* We're lazy and allocate too much (fixed up later).
"+3" leaves room for up to two pad characters and a trailing
newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) {
+ PyBuffer_Release(&pbuf);
return NULL;
+ }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);

for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
@@ -498,6 +526,7 @@
Py_DECREF(rv);
rv = NULL;
}
+ PyBuffer_Release(&pbuf);
return rv;
}

@@ -581,22 +610,29 @@
static PyObject *
binascii_rlecode_hqx(PyObject *self, PyObject *args)
{
+ Py_buffer pbuf;
unsigned char *in_data, *out_data;
PyObject *rv;
unsigned char ch;
Py_ssize_t in, inend, len;

- if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
+ if ( !PyArg_ParseTuple(args, "s*:rlecode_hqx", &pbuf) )
return NULL;
+ in_data = pbuf.buf;
+ len = pbuf.len;

assert(len >= 0);

- if (len > PY_SSIZE_T_MAX / 2 - 2)
+ if (len > PY_SSIZE_T_MAX / 2 - 2) {
+ PyBuffer_Release(&pbuf);
return PyErr_NoMemory();
+ }

/* Worst case: output is twice as big as input (fixed later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
+ PyBuffer_Release(&pbuf);
return NULL;
+ }
out_data = (unsigned char *)PyBytes_AS_STRING(rv);

for( in=0; in<len; in++) {
@@ -629,6 +665,7 @@
Py_DECREF(rv);
rv = NULL;
}
+ PyBuffer_Release(&pbuf);
return rv;
}

@@ -637,6 +674,7 @@
static PyObject *
binascii_b2a_hqx(PyObject *self, PyObject *args)
{
+ Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -644,17 +682,23 @@
PyObject *rv;
Py_ssize_t len;

- if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
+ if ( !PyArg_ParseTuple(args, "s*:b2a_hqx", &pbin) )
return NULL;
+ bin_data = pbin.buf;
+ len = pbin.len;

assert(len >= 0);

- if (len > PY_SSIZE_T_MAX / 2 - 2)
+ if (len > PY_SSIZE_T_MAX / 2 - 2) {
+ PyBuffer_Release(&pbin);
return PyErr_NoMemory();
+ }

/* Allocate a buffer that is at least large enough */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
+ PyBuffer_Release(&pbin);
return NULL;
+ }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);

for( ; len > 0 ; len--, bin_data++ ) {
@@ -678,6 +722,7 @@
Py_DECREF(rv);
rv = NULL;
}
+ PyBuffer_Release(&pbin);
return rv;
}

@@ -686,26 +731,35 @@
static PyObject *
binascii_rledecode_hqx(PyObject *self, PyObject *args)
{
+ Py_buffer pin;
unsigned char *in_data, *out_data;
unsigned char in_byte, in_repeat;
PyObject *rv;
Py_ssize_t in_len, out_len, out_len_left;

- if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
+ if ( !PyArg_ParseTuple(args, "s*:rledecode_hqx", &pin) )
return NULL;
+ in_data = pin.buf;
+ in_len = pin.len;

assert(in_len >= 0);

/* Empty string is a special case */
- if ( in_len == 0 )
+ if ( in_len == 0 ) {
+ PyBuffer_Release(&pin);
return PyBytes_FromStringAndSize("", 0);
- else if (in_len > PY_SSIZE_T_MAX / 2)
+ }
+ else if (in_len > PY_SSIZE_T_MAX / 2) {
+ PyBuffer_Release(&pin);
return PyErr_NoMemory();
+ }

/* Allocate a buffer of reasonable size. Resized when needed */
out_len = in_len*2;
- if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL )
+ if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) {
+ PyBuffer_Release(&pin);
return NULL;
+ }
out_len_left = out_len;
out_data = (unsigned char *)PyBytes_AS_STRING(rv);

@@ -718,6 +772,7 @@
if ( --in_len < 0 ) { \
PyErr_SetString(Incomplete, ""); \
Py_DECREF(rv); \
+ PyBuffer_Release(&pin); \
return NULL; \
} \
b = *in_data++; \
@@ -728,7 +783,7 @@
if ( --out_len_left < 0 ) { \
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
- { Py_DECREF(rv); return NULL; } \
+ { Py_DECREF(rv); PyBuffer_Release(&pin); return NULL; } \
out_data = (unsigned char *)PyBytes_AS_STRING(rv) \
+ out_len; \
out_len_left = out_len-1; \
@@ -783,6 +838,7 @@
Py_DECREF(rv);
rv = NULL;
}
+ PyBuffer_Release(&pin);
return rv;
}

@@ -792,17 +848,21 @@
static PyObject *
binascii_crc_hqx(PyObject *self, PyObject *args)
{
+ Py_buffer pin;
unsigned char *bin_data;
unsigned int crc;
Py_ssize_t len;

- if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
+ if ( !PyArg_ParseTuple(args, "s*i:crc_hqx", &pin, &crc) )
return NULL;
+ bin_data = pin.buf;
+ len = pin.len;

while(len-- > 0) {
crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
}

+ PyBuffer_Release(&pin);
return Py_BuildValue("i", crc);
}

@@ -815,13 +875,17 @@
binascii_crc32(PyObject *self, PyObject *args)
{
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
+ Py_buffer pbuf;
Byte *buf;
Py_ssize_t len;
int signed_val;

- if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &len, &crc32val))
+ if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val))
return NULL;
+ buf = (Byte*)pbuf.buf;
+ len = pbuf.len;
signed_val = crc32(crc32val, buf, len);
+ PyBuffer_Release(&pbuf);
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
}
#else /* USE_ZLIB_CRC32 */
@@ -946,13 +1010,16 @@
static PyObject *
binascii_crc32(PyObject *self, PyObject *args)
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
+ Py_buffer pbin;
unsigned char *bin_data;
unsigned int crc = 0; /* initial value of CRC */
Py_ssize_t len;
unsigned int result;

- if ( !PyArg_ParseTuple(args, "s#|I:crc32", &bin_data, &len, &crc) )
+ if ( !PyArg_ParseTuple(args, "s*|I:crc32", &pbin, &crc) )
return NULL;
+ bin_data = pbin.buf;
+ len = pbin.len;

crc = ~ crc;
while (len-- > 0) {
@@ -961,6 +1028,7 @@
}

result = (crc ^ 0xFFFFFFFF);
+ PyBuffer_Release(&pbuf);
return PyLong_FromUnsignedLong(result & 0xffffffff);
}
#endif /* USE_ZLIB_CRC32 */
@@ -969,22 +1037,29 @@
static PyObject *
binascii_hexlify(PyObject *self, PyObject *args)
{
+ Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;

- if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
+ if (!PyArg_ParseTuple(args, "s*:b2a_hex", &parg))
return NULL;
+ argbuf = parg.buf;
+ arglen = parg.len;

assert(arglen >= 0);
- if (arglen > PY_SSIZE_T_MAX / 2)
+ if (arglen > PY_SSIZE_T_MAX / 2) {
+ PyBuffer_Release(&parg);
return PyErr_NoMemory();
+ }

retval = PyBytes_FromStringAndSize(NULL, arglen*2);
- if (!retval)
+ if (!retval) {
+ PyBuffer_Release(&parg);
return NULL;
+ }
retbuf = PyBytes_AS_STRING(retval);

/* make hex version of string, taken from shamodule.c */
@@ -997,6 +1072,7 @@
c = (c>9) ? c+'a'-10 : c + '0';
retbuf[j++] = c;
}
+ PyBuffer_Release(&parg);
return retval;
}

@@ -1024,14 +1100,17 @@
static PyObject *
binascii_unhexlify(PyObject *self, PyObject *args)
{
+ Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;

- if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
+ if (!PyArg_ParseTuple(args, "s*:a2b_hex", &parg))
return NULL;
+ argbuf = parg.buf;
+ arglen = parg.len;

assert(arglen >= 0);

@@ -1040,13 +1119,16 @@
* raise an exception.
*/
if (arglen % 2) {
+ PyBuffer_Release(&parg);
PyErr_SetString(Error, "Odd-length string");
return NULL;
}

retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
- if (!retval)
+ if (!retval) {
+ PyBuffer_Release(&parg);
return NULL;
+ }
retbuf = PyBytes_AS_STRING(retval);

for (i=j=0; i < arglen; i += 2) {
@@ -1059,9 +1141,11 @@
}
retbuf[j++] = (top << 4) + bot;
}
+ PyBuffer_Release(&parg);
return retval;

finally:
+ PyBuffer_Release(&parg);
Py_DECREF(retval);
return NULL;
}
@@ -1094,15 +1178,18 @@
{
Py_ssize_t in, out;
char ch;
+ Py_buffer pdata;
unsigned char *data, *odata;
Py_ssize_t datalen = 0;
PyObject *rv;
static char *kwlist[] = {"data", "header", NULL};
int header = 0;

- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i", kwlist, &data,
- &datalen, &header))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i", kwlist, &pdata,
+ &header))
return NULL;
+ data = pdata.buf;
+ datalen = pdata.len;

/* We allocate the output same size as input, this is overkill.
* The previous implementation used calloc() so we'll zero out the
@@ -1110,6 +1197,7 @@
*/
odata = (unsigned char *) PyMem_Malloc(datalen);
if (odata == NULL) {
+ PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1160,9 +1248,11 @@
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
+ PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
+ PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}
@@ -1193,6 +1283,7 @@
binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
{
Py_ssize_t in, out;
+ Py_buffer pdata;
unsigned char *data, *odata;
Py_ssize_t datalen = 0, odatalen = 0;
PyObject *rv;
@@ -1206,9 +1297,11 @@
int crlf = 0;
unsigned char *p;

- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|iii", kwlist, &data,
- &datalen, &quotetabs, &istext, &header))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|iii", kwlist, &pdata,
+ &quotetabs, &istext, &header))
return NULL;
+ data = pdata.buf;
+ datalen = pdata.len;

/* See if this string is using CRLF line ends */
/* XXX: this function has the side effect of converting all of
@@ -1286,6 +1379,7 @@
*/
odata = (unsigned char *) PyMem_Malloc(odatalen);
if (odata == NULL) {
+ PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1360,9 +1454,11 @@
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
+ PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
+ PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}

Modified: python/branches/py3k/Modules/bz2module.c
==============================================================================
--- python/branches/py3k/Modules/bz2module.c (original)
+++ python/branches/py3k/Modules/bz2module.c Wed Aug 13 17:53:07 2008
@@ -691,12 +691,15 @@
BZ2File_write(BZ2FileObject *self, PyObject *args)
{
PyObject *ret = NULL;
+ Py_buffer pbuf;
char *buf;
int len;
int bzerror;

- if (!PyArg_ParseTuple(args, "y#:write", &buf, &len))
+ if (!PyArg_ParseTuple(args, "y*:write", &pbuf))
return NULL;
+ buf = pbuf.buf;
+ len = pbuf.len;

ACQUIRE_LOCK(self);
switch (self->mode) {
@@ -728,6 +731,7 @@
ret = Py_None;

cleanup:
+ PyBuffer_Release(&pbuf);
RELEASE_LOCK(self);
return ret;
}
@@ -1353,6 +1357,7 @@
static PyObject *
BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -1361,11 +1366,15 @@
bz_stream *bzs = &self->bzs;
int bzerror;

- if (!PyArg_ParseTuple(args, "y#:compress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "y*:compress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;

- if (datasize == 0)
+ if (datasize == 0) {
+ PyBuffer_Release(&pdata);
return PyBytes_FromStringAndSize("", 0);
+ }

ACQUIRE_LOCK(self);
if (!self->running) {
@@ -1412,10 +1421,12 @@
goto error;

RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
return ret;

error:
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
@@ -1642,6 +1653,7 @@
static PyObject *
BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -1650,8 +1662,10 @@
bz_stream *bzs = &self->bzs;
int bzerror;

- if (!PyArg_ParseTuple(args, "y#:decompress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "y*:decompress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;

ACQUIRE_LOCK(self);
if (!self->running) {
@@ -1711,10 +1725,12 @@
}

RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
return ret;

error:
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
@@ -1853,6 +1869,7 @@
bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
{
int compresslevel=9;
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize;
@@ -1862,14 +1879,17 @@
int bzerror;
static char *kwlist[] = {"data", "compresslevel", 0};

- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y#|i",
- kwlist, &data, &datasize,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i",
+ kwlist, &pdata,
&compresslevel))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;

if (compresslevel < 1 || compresslevel > 9) {
PyErr_SetString(PyExc_ValueError,
"compresslevel must be between 1 and 9");
+ PyBuffer_Release(&pdata);
return NULL;
}

@@ -1878,8 +1898,10 @@
bufsize = datasize + (datasize/100+1) + 600;

ret = PyBytes_FromStringAndSize(NULL, bufsize);
- if (!ret)
+ if (!ret) {
+ PyBuffer_Release(&pdata);
return NULL;
+ }

memset(bzs, 0, sizeof(bz_stream));

@@ -1891,6 +1913,7 @@
bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -1904,6 +1927,7 @@
} else if (bzerror != BZ_FINISH_OK) {
BZ2_bzCompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -1911,6 +1935,7 @@
bufsize = Util_NewBufferSize(bufsize);
if (_PyBytes_Resize(&ret, bufsize) < 0) {
BZ2_bzCompressEnd(bzs);
+ PyBuffer_Release(&pdata);
return NULL;
}
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
@@ -1925,6 +1950,7 @@
}
BZ2_bzCompressEnd(bzs);

+ PyBuffer_Release(&pdata);
return ret;
}

@@ -1938,6 +1964,7 @@
static PyObject *
bz2_decompress(PyObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -1946,15 +1973,21 @@
bz_stream *bzs = &_bzs;
int bzerror;

- if (!PyArg_ParseTuple(args, "y#:decompress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "y*:decompress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;

- if (datasize == 0)
+ if (datasize == 0) {
+ PyBuffer_Release(&pdata);
return PyBytes_FromStringAndSize("", 0);
+ }

ret = PyBytes_FromStringAndSize(NULL, bufsize);
- if (!ret)
+ if (!ret) {
+ PyBuffer_Release(&pdata);
return NULL;
+ }

memset(bzs, 0, sizeof(bz_stream));

@@ -1967,6 +2000,7 @@
if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror);
Py_DECREF(ret);
+ PyBuffer_Release(&pdata);
return NULL;
}

@@ -1979,6 +2013,7 @@
} else if (bzerror != BZ_OK) {
BZ2_bzDecompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -1986,6 +2021,7 @@
BZ2_bzDecompressEnd(bzs);
PyErr_SetString(PyExc_ValueError,
"couldn't find end of stream");
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -1993,6 +2029,7 @@
bufsize = Util_NewBufferSize(bufsize);
if (_PyBytes_Resize(&ret, bufsize) < 0) {
BZ2_bzDecompressEnd(bzs);
+ PyBuffer_Release(&pdata);
return NULL;
}
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
@@ -2006,6 +2043,7 @@
}
}
BZ2_bzDecompressEnd(bzs);
+ PyBuffer_Release(&pdata);

return ret;
}

Modified: python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
==============================================================================
--- python/branches/py3k/Modules/cjkcodecs/multibytecodec.c (original)
+++ python/branches/py3k/Modules/cjkcodecs/multibytecodec.c Wed Aug 13 17:53:07 2008
@@ -608,18 +608,24 @@
MultibyteCodec_State state;
MultibyteDecodeBuffer buf;
PyObject *errorcb;
+ Py_buffer pdata;
const char *data, *errors = NULL;
Py_ssize_t datalen, finalsize;

- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z:decode",
- codeckwarglist, &data, &datalen, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|z:decode",
+ codeckwarglist, &pdata, &errors))
return NULL;
+ data = pdata.buf;
+ datalen = pdata.len;

errorcb = internal_error_callback(errors);
- if (errorcb == NULL)
+ if (errorcb == NULL) {
+ PyBuffer_Release(&pdata);
return NULL;
+ }

if (datalen == 0) {
+ PyBuffer_Release(&pdata);
ERROR_DECREF(errorcb);
return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
}
@@ -659,11 +665,13 @@
if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
goto errorexit;

+ PyBuffer_Release(&pdata);
Py_XDECREF(buf.excobj);
ERROR_DECREF(errorcb);
return make_tuple(buf.outobj, datalen);

errorexit:
+ PyBuffer_Release(&pdata);
ERROR_DECREF(errorcb);
Py_XDECREF(buf.excobj);
Py_XDECREF(buf.outobj);

Modified: python/branches/py3k/Modules/fcntlmodule.c
==============================================================================
--- python/branches/py3k/Modules/fcntlmodule.c (original)
+++ python/branches/py3k/Modules/fcntlmodule.c Wed Aug 13 17:53:07 2008
@@ -113,15 +113,18 @@
unsigned int code;
int arg;
int ret;
+ Py_buffer pstr;
char *str;
Py_ssize_t len;
int mutate_arg = 1;
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */

- if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
+ if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
conv_descriptor, &fd, &code,
- &str, &len, &mutate_arg)) {
+ &pstr, &mutate_arg)) {
char *arg;
+ str = pstr.buf;
+ len = pstr.len;

if (mutate_arg) {
if (len <= IOCTL_BUFSZ) {
@@ -135,6 +138,7 @@
}
else {
if (len > IOCTL_BUFSZ) {
+ PyBuffer_Release(&pstr);
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
@@ -156,6 +160,7 @@
if (mutate_arg && (len < IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
+ PyBuffer_Release(&pstr); /* No further access to str below this point */
if (ret < 0) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
@@ -169,9 +174,12 @@
}

PyErr_Clear();
- if (PyArg_ParseTuple(args, "O&Is#:ioctl",
- conv_descriptor, &fd, &code, &str, &len)) {
+ if (PyArg_ParseTuple(args, "O&Is*:ioctl",
+ conv_descriptor, &fd, &code, &pstr)) {
+ str = pstr.buf;
+ len = pstr.len;
if (len > IOCTL_BUFSZ) {
+ PyBuffer_Release(&pstr);
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
@@ -182,9 +190,11 @@
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS
if (ret < 0) {
+ PyBuffer_Release(&pstr);
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
+ PyBuffer_Release(&pstr);
return PyBytes_FromStringAndSize(buf, len);
}


Modified: python/branches/py3k/Modules/mmapmodule.c
==============================================================================
--- python/branches/py3k/Modules/mmapmodule.c (original)
+++ python/branches/py3k/Modules/mmapmodule.c Wed Aug 13 17:53:07 2008
@@ -651,7 +651,7 @@
mmap_buffer_getbuf(mmap_object *self, Py_buffer *view, int flags)
{
CHECK_VALID(-1);
- if (PyBuffer_FillInfo(view, self->data, self->size,
+ if (PyBuffer_FillInfo(view, (PyObject*)self, self->data, self->size,
(self->access == ACCESS_READ), flags) < 0)
return -1;
self->exports++;
@@ -843,7 +843,7 @@
if (vbuf.len != slicelen) {
PyErr_SetString(PyExc_IndexError,
"mmap slice assignment is wrong size");
- PyObject_ReleaseBuffer(value, &vbuf);
+ PyBuffer_Release(&vbuf);
return -1;
}

@@ -862,7 +862,7 @@
self->data[cur] = ((char *)vbuf.buf)[i];
}
}
- PyObject_ReleaseBuffer(value, &vbuf);
+ PyBuffer_Release(&vbuf);
return 0;
}
else {

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Wed Aug 13 17:53:07 2008
@@ -4894,15 +4894,16 @@
static PyObject *
posix_write(PyObject *self, PyObject *args)
{
+ Py_buffer pbuf;
int fd;
Py_ssize_t size;
- char *buffer;

- if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
+ if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
return NULL;
Py_BEGIN_ALLOW_THREADS
- size = write(fd, buffer, (size_t)size);
+ size = write(fd, pbuf.buf, (size_t)pbuf.len);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (size < 0)
return posix_error();
return PyLong_FromSsize_t(size);

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c (original)
+++ python/branches/py3k/Modules/socketmodule.c Wed Aug 13 17:53:07 2008
@@ -2251,15 +2251,19 @@

int recvlen = 0, flags = 0;
ssize_t readlen;
+ Py_buffer pbuf;
char *buf;
int buflen;

/* Get the buffer's memory */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv_into", kwlist,
- &buf, &buflen, &recvlen, &flags))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recv_into", kwlist,
+ &pbuf, &recvlen, &flags))
return NULL;
+ buf = pbuf.buf;
+ buflen = pbuf.len;

if (recvlen < 0) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"negative buffersize in recv_into");
return NULL;
@@ -2271,6 +2275,7 @@

/* Check if the buffer is large enough */
if (buflen < recvlen) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"buffer too small for requested bytes");
return NULL;
@@ -2280,9 +2285,11 @@
readlen = sock_recv_guts(s, buf, recvlen, flags);
if (readlen < 0) {
/* Return an error. */
+ PyBuffer_Release(&pbuf);
return NULL;
}

+ PyBuffer_Release(&pbuf);
/* Return the number of bytes read. Note that we do not do anything
special here in the case that readlen < recvlen. */
return PyLong_FromSsize_t(readlen);
@@ -2424,18 +2431,22 @@

int recvlen = 0, flags = 0;
ssize_t readlen;
+ Py_buffer pbuf;
char *buf;
int buflen;

PyObject *addr = NULL;

- if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom_into",
- kwlist, &buf, &buflen,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recvfrom_into",
+ kwlist, &pbuf,
&recvlen, &flags))
return NULL;
+ buf = pbuf.buf;
+ buflen = pbuf.len;
assert(buf != 0 && buflen > 0);

if (recvlen < 0) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"negative buffersize in recvfrom_into");
return NULL;
@@ -2447,11 +2458,13 @@

readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
if (readlen < 0) {
+ PyBuffer_Release(&pbuf);
/* Return an error */
Py_XDECREF(addr);
return NULL;
}

+ PyBuffer_Release(&pbuf);
/* Return the number of bytes read and the address. Note that we do
not do anything special here in the case that readlen < recvlen. */
return Py_BuildValue("lN", readlen, addr);
@@ -2470,12 +2483,17 @@
{
char *buf;
int len, n = -1, flags = 0, timeout;
+ Py_buffer pbuf;

- if (!PyArg_ParseTuple(args, "y#|i:send", &buf, &len, &flags))
+ if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags))
return NULL;

- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }
+ buf = pbuf.buf;
+ len = pbuf.len;

Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 1);
@@ -2487,6 +2505,8 @@
#endif
Py_END_ALLOW_THREADS

+ PyBuffer_Release(&pbuf);
+
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;
@@ -2511,12 +2531,17 @@
{
char *buf;
int len, n = -1, flags = 0, timeout;
+ Py_buffer pbuf;

- if (!PyArg_ParseTuple(args, "y#|i:sendall", &buf, &len, &flags))
+ if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags))
return NULL;
+ buf = pbuf.buf;
+ len = pbuf.len;

- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }

Py_BEGIN_ALLOW_THREADS
do {
@@ -2535,6 +2560,7 @@
len -= n;
} while (len > 0);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);

if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
@@ -2561,24 +2587,32 @@
static PyObject *
sock_sendto(PySocketSockObject *s, PyObject *args)
{
+ Py_buffer pbuf;
PyObject *addro;
char *buf;
+ Py_ssize_t len;
sock_addr_t addrbuf;
- int addrlen, len, n = -1, flags, timeout;
+ int addrlen, n = -1, flags, timeout;

flags = 0;
- if (!PyArg_ParseTuple(args, "y#O:sendto", &buf, &len, &addro)) {
+ if (!PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro)) {
PyErr_Clear();
- if (!PyArg_ParseTuple(args, "y#iO:sendto",
- &buf, &len, &flags, &addro))
+ if (!PyArg_ParseTuple(args, "y*iO:sendto",
+ &pbuf, &flags, &addro))
return NULL;
}
+ buf = pbuf.buf;
+ len = pbuf.len;

- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }

- if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) {
+ PyBuffer_Release(&pbuf);
return NULL;
+ }

Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 1);
@@ -2586,6 +2620,7 @@
n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
Py_END_ALLOW_THREADS

+ PyBuffer_Release(&pbuf);
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;

Modified: python/branches/py3k/Modules/zlibmodule.c
==============================================================================
--- python/branches/py3k/Modules/zlibmodule.c (original)
+++ python/branches/py3k/Modules/zlibmodule.c Wed Aug 13 17:53:07 2008
@@ -118,18 +118,22 @@
PyZlib_compress(PyObject *self, PyObject *args)
{
PyObject *ReturnVal = NULL;
+ Py_buffer pinput;
Byte *input, *output;
int length, level=Z_DEFAULT_COMPRESSION, err;
z_stream zst;

/* require Python string object, optional 'level' arg */
- if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level))
+ if (!PyArg_ParseTuple(args, "s*|i:compress", &pinput, &level))
return NULL;
+ input = pinput.buf;
+ length = pinput.len;

zst.avail_out = length + length/1000 + 12 + 1;

output = (Byte*)malloc(zst.avail_out);
if (output == NULL) {
+ PyBuffer_Release(&pinput);
PyErr_SetString(PyExc_MemoryError,
"Can't allocate memory to compress data");
return NULL;
@@ -180,6 +184,7 @@
zlib_error(zst, err, "while finishing compression");

error:
+ PyBuffer_Release(&pinput);
free(output);

return ReturnVal;
@@ -195,15 +200,18 @@
PyZlib_decompress(PyObject *self, PyObject *args)
{
PyObject *result_str;
+ Py_buffer pinput;
Byte *input;
int length, err;
int wsize=DEF_WBITS;
Py_ssize_t r_strlen=DEFAULTALLOC;
z_stream zst;

- if (!PyArg_ParseTuple(args, "s#|in:decompress",
- &input, &length, &wsize, &r_strlen))
+ if (!PyArg_ParseTuple(args, "s*|in:decompress",
+ &pinput, &wsize, &r_strlen))
return NULL;
+ input = pinput.buf;
+ length = pinput.len;

if (r_strlen <= 0)
r_strlen = 1;
@@ -211,8 +219,10 @@
zst.avail_in = length;
zst.avail_out = r_strlen;

- if (!(result_str = PyByteArray_FromStringAndSize(NULL, r_strlen)))
+ if (!(result_str = PyByteArray_FromStringAndSize(NULL, r_strlen))) {
+ PyBuffer_Release(&pinput);
return NULL;
+ }

zst.zalloc = (alloc_func)NULL;
zst.zfree = (free_func)Z_NULL;
@@ -281,9 +291,11 @@
if (PyByteArray_Resize(result_str, zst.total_out) < 0)
goto error;

+ PyBuffer_Release(&pinput);
return result_str;

error:
+ PyBuffer_Release(&pinput);
Py_XDECREF(result_str);
return NULL;
}
@@ -396,14 +408,19 @@
{
int err, inplen, length = DEFAULTALLOC;
PyObject *RetVal;
+ Py_buffer pinput;
Byte *input;
unsigned long start_total_out;

- if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen))
+ if (!PyArg_ParseTuple(args, "s*:compress", &pinput))
return NULL;
+ input = pinput.buf;
+ inplen = pinput.len;

- if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length)))
+ if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length))) {
+ PyBuffer_Release(&pinput);
return NULL;
+ }

ENTER_ZLIB

@@ -452,6 +469,7 @@

error:
LEAVE_ZLIB
+ PyBuffer_Release(&pinput);
return RetVal;
}

@@ -472,13 +490,17 @@
int err, inplen, old_length, length = DEFAULTALLOC;
int max_length = 0;
PyObject *RetVal;
+ Py_buffer pinput;
Byte *input;
unsigned long start_total_out;

- if (!PyArg_ParseTuple(args, "s#|i:decompress", &input,
- &inplen, &max_length))
+ if (!PyArg_ParseTuple(args, "s*|i:decompress", &pinput,
+ &max_length))
return NULL;
+ input = pinput.buf;
+ inplen = pinput.len;
if (max_length < 0) {
+ PyBuffer_Release(&pinput);
PyErr_SetString(PyExc_ValueError,
"max_length must be greater than zero");
return NULL;
@@ -487,8 +509,10 @@
/* limit amount of data allocated to max_length */
if (max_length && length > max_length)
length = max_length;
- if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length)))
+ if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length))) {
+ PyBuffer_Release(&pinput);
return NULL;
+ }

ENTER_ZLIB

@@ -577,7 +601,7 @@

error:
LEAVE_ZLIB
-
+ PyBuffer_Release(&pinput);
return RetVal;
}

@@ -916,12 +940,13 @@
PyZlib_crc32(PyObject *self, PyObject *args)
{
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
- Byte *buf;
- int len, signed_val;
+ Py_buffer pbuf;
+ int signed_val;

- if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &len, &crc32val))
+ if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val))
return NULL;
- signed_val = crc32(crc32val, buf, len);
+ signed_val = crc32(crc32val, pbuf.buf, pbuf.len);
+ PyBuffer_Release(&pbuf);
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
}


Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c (original)
+++ python/branches/py3k/Objects/abstract.c Wed Aug 13 17:53:07 2008
@@ -349,16 +349,6 @@
return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
}

-void
-PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)
-{
- if (obj->ob_type->tp_as_buffer != NULL &&
- obj->ob_type->tp_as_buffer->bf_releasebuffer != NULL) {
- (*(obj->ob_type->tp_as_buffer->bf_releasebuffer))(obj, view);
- }
-}
-
-
static int
_IsFortranContiguous(Py_buffer *view)
{
@@ -590,15 +580,15 @@

if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
- PyObject_ReleaseBuffer(dest, &view_dest);
+ PyBuffer_Release(&view_dest);
return -1;
}

if (view_dest.len < view_src.len) {
PyErr_SetString(PyExc_BufferError,
"destination is too small to receive data from source");
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return -1;
}

@@ -608,8 +598,8 @@
PyBuffer_IsContiguous(&view_src, 'F'))) {
/* simplest copy is all that is needed */
memcpy(view_dest.buf, view_src.buf, view_src.len);
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return 0;
}

@@ -619,8 +609,8 @@
indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
if (indices == NULL) {
PyErr_NoMemory();
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return -1;
}
for (k=0; k<view_src.ndim;k++) {
@@ -638,8 +628,8 @@
memcpy(dptr, sptr, view_src.itemsize);
}
PyMem_Free(indices);
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return 0;
}

@@ -668,7 +658,7 @@
}

int
-PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
+PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
int readonly, int flags)
{
if (view == NULL) return 0;
@@ -679,6 +669,7 @@
return -1;
}

+ view->obj = obj;
view->buf = buf;
view->len = len;
view->readonly = readonly;
@@ -698,6 +689,17 @@
return 0;
}

+void
+PyBuffer_Release(Py_buffer *view)
+{
+ PyObject *obj = view->obj;
+ if (!obj || !Py_TYPE(obj)->tp_as_buffer || !Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
+ /* Unmanaged buffer */
+ return;
+ Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
+
+}
+
PyObject *
PyObject_Format(PyObject *obj, PyObject *format_spec)
{

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c (original)
+++ python/branches/py3k/Objects/bytearrayobject.c Wed Aug 13 17:53:07 2008
@@ -69,7 +69,7 @@
ptr = "";
else
ptr = obj->ob_bytes;
- ret = PyBuffer_FillInfo(view, ptr, Py_SIZE(obj), 0, flags);
+ ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
if (ret >= 0) {
obj->ob_exports++;
}
@@ -248,9 +248,9 @@

done:
if (va.len != -1)
- PyObject_ReleaseBuffer(a, &va);
+ PyBuffer_Release(&va);
if (vb.len != -1)
- PyObject_ReleaseBuffer(b, &vb);
+ PyBuffer_Release(&vb);
return (PyObject *)result;
}

@@ -278,7 +278,7 @@
mysize = Py_SIZE(self);
size = mysize + vo.len;
if (size < 0) {
- PyObject_ReleaseBuffer(other, &vo);
+ PyBuffer_Release(&vo);
return PyErr_NoMemory();
}
if (size < self->ob_alloc) {
@@ -286,11 +286,11 @@
self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
}
else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
- PyObject_ReleaseBuffer(other, &vo);
+ PyBuffer_Release(&vo);
return NULL;
}
memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
- PyObject_ReleaseBuffer(other, &vo);
+ PyBuffer_Release(&vo);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -501,7 +501,7 @@

finish:
if (vbytes.len != -1)
- PyObject_ReleaseBuffer(values, &vbytes);
+ PyBuffer_Release(&vbytes);
return res;
}

@@ -767,10 +767,10 @@
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
goto fail;
- PyObject_ReleaseBuffer(arg, &view);
+ PyBuffer_Release(&view);
return 0;
fail:
- PyObject_ReleaseBuffer(arg, &view);
+ PyBuffer_Release(&view);
return -1;
}

@@ -954,7 +954,7 @@
other_size = _getbuffer(other, &other_bytes);
if (other_size < 0) {
PyErr_Clear();
- PyObject_ReleaseBuffer(self, &self_bytes);
+ PyBuffer_Release(&self_bytes);
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
@@ -989,8 +989,8 @@
}

res = cmp ? Py_True : Py_False;
- PyObject_ReleaseBuffer(self, &self_bytes);
- PyObject_ReleaseBuffer(other, &other_bytes);
+ PyBuffer_Release(&self_bytes);
+ PyBuffer_Release(&other_bytes);
Py_INCREF(res);
return res;
}
@@ -998,6 +998,11 @@
static void
bytes_dealloc(PyByteArrayObject *self)
{
+ if (self->ob_exports > 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "deallocated bytearray object has exported buffers");
+ PyErr_Print();
+ }
if (self->ob_bytes != 0) {
PyMem_Free(self->ob_bytes);
}
@@ -1065,7 +1070,7 @@
res = stringlib_rfind_slice(
PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
subbuf.buf, subbuf.len, start, end);
- PyObject_ReleaseBuffer(subobj, &subbuf);
+ PyBuffer_Release(&subbuf);
return res;
}

@@ -1115,7 +1120,7 @@
count_obj = PyLong_FromSsize_t(
stringlib_count(str + start, end - start, vsub.buf, vsub.len)
);
- PyObject_ReleaseBuffer(sub_obj, &vsub);
+ PyBuffer_Release(&vsub);
return count_obj;
}

@@ -1191,7 +1196,7 @@
return -1;
pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
varg.buf, varg.len, 0);
- PyObject_ReleaseBuffer(arg, &varg);
+ PyBuffer_Release(&varg);
return pos >= 0;
}
if (ival < 0 || ival >= 256) {
@@ -1241,7 +1246,7 @@
rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);

done:
- PyObject_ReleaseBuffer(substr, &vsubstr);
+ PyBuffer_Release(&vsubstr);
return rv;
}

@@ -1421,9 +1426,9 @@
PyByteArray_Resize(result, output - output_start);

done:
- PyObject_ReleaseBuffer(tableobj, &vtable);
+ PyBuffer_Release(&vtable);
if (delobj != NULL)
- PyObject_ReleaseBuffer(delobj, &vdel);
+ PyBuffer_Release(&vdel);
return result;
}

@@ -2042,7 +2047,7 @@
if (_getbuffer(from, &vfrom) < 0)
return NULL;
if (_getbuffer(to, &vto) < 0) {
- PyObject_ReleaseBuffer(from, &vfrom);
+ PyBuffer_Release(&vfrom);
return NULL;
}

@@ -2050,8 +2055,8 @@
vfrom.buf, vfrom.len,
vto.buf, vto.len, count);

- PyObject_ReleaseBuffer(from, &vfrom);
- PyObject_ReleaseBuffer(to, &vto);
+ PyBuffer_Release(&vfrom);
+ PyBuffer_Release(&vto);
return res;
}

@@ -2207,7 +2212,7 @@

if (n == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}
if (n == 1)
@@ -2215,7 +2220,7 @@

list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -2243,12 +2248,12 @@
#endif
SPLIT_ADD(s, i, len);
FIX_PREALLOC_SIZE(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return list;

onError:
Py_DECREF(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -2439,7 +2444,7 @@

if (n == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}
else if (n == 1)
@@ -2447,7 +2452,7 @@

list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -2468,12 +2473,12 @@
FIX_PREALLOC_SIZE(list);
if (PyList_Reverse(list) < 0)
goto onError;
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return list;

onError:
Py_DECREF(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -2749,7 +2754,7 @@
else
right = rstrip_helper(myptr, mysize, argptr, argsize);
if (arg != Py_None)
- PyObject_ReleaseBuffer(arg, &varg);
+ PyBuffer_Release(&varg);
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
}

@@ -2783,7 +2788,7 @@
left = lstrip_helper(myptr, mysize, argptr, argsize);
right = mysize;
if (arg != Py_None)
- PyObject_ReleaseBuffer(arg, &varg);
+ PyBuffer_Release(&varg);
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
}

@@ -2817,7 +2822,7 @@
left = 0;
right = rstrip_helper(myptr, mysize, argptr, argsize);
if (arg != Py_None)
- PyObject_ReleaseBuffer(arg, &varg);
+ PyBuffer_Release(&varg);
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
}


Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c (original)
+++ python/branches/py3k/Objects/bytesobject.c Wed Aug 13 17:53:07 2008
@@ -710,9 +710,9 @@

done:
if (va.len != -1)
- PyObject_ReleaseBuffer(a, &va);
+ PyBuffer_Release(&va);
if (vb.len != -1)
- PyObject_ReleaseBuffer(b, &vb);
+ PyBuffer_Release(&vb);
return result;
}

@@ -781,7 +781,7 @@
return -1;
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
varg.buf, varg.len, 0);
- PyObject_ReleaseBuffer(arg, &varg);
+ PyBuffer_Release(&varg);
return pos >= 0;
}
if (ival < 0 || ival >= 256) {
@@ -964,7 +964,7 @@
static int
string_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags)
{
- return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_SIZE(self),
+ return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self),
1, flags);
}

@@ -1160,7 +1160,7 @@

if (n == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}
else if (n == 1)
@@ -1168,7 +1168,7 @@

list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -1196,12 +1196,12 @@
#endif
SPLIT_ADD(s, i, len);
FIX_PREALLOC_SIZE(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return list;

onError:
Py_DECREF(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -1376,7 +1376,7 @@

if (n == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}
else if (n == 1)
@@ -1384,7 +1384,7 @@

list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -1406,12 +1406,12 @@
FIX_PREALLOC_SIZE(list);
if (PyList_Reverse(list) < 0)
goto onError;
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return list;

onError:
Py_DECREF(list);
- PyObject_ReleaseBuffer(subobj, &vsub);
+ PyBuffer_Release(&vsub);
return NULL;
}

@@ -1690,7 +1690,7 @@
j++;
}

- PyObject_ReleaseBuffer(sepobj, &vsep);
+ PyBuffer_Release(&vsep);

if (i == 0 && j == len && PyBytes_CheckExact(self)) {
Py_INCREF(self);
@@ -2945,11 +2945,11 @@
if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval,
&view, view.len, 'C') < 0)
goto fail;
- PyObject_ReleaseBuffer(x, &view);
+ PyBuffer_Release(&view);
return new;
fail:
Py_XDECREF(new);
- PyObject_ReleaseBuffer(x, &view);
+ PyBuffer_Release(&view);
return NULL;
}


Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c (original)
+++ python/branches/py3k/Objects/memoryobject.c Wed Aug 13 17:53:07 2008
@@ -6,19 +6,21 @@
static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
- if (view != NULL)
+ if (view != NULL) {
+ if (self->view.obj)
+ Py_INCREF(self->view.obj);
*view = self->view;
- if (self->base == NULL)
+ }
+ if (self->view.obj == NULL)
return 0;
- return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
+ return self->view.obj->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
PyBUF_FULL);
}

static void
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
{
- if (self->base != NULL)
- PyObject_ReleaseBuffer(self->base, NULL);
+ PyBuffer_Release(&self->view);
}

PyDoc_STRVAR(memory_doc,
@@ -36,6 +38,8 @@
if (mview == NULL) return NULL;
mview->base = NULL;
mview->view = *info;
+ if (info->obj)
+ Py_INCREF(mview->view.obj);
return (PyObject *)mview;
}

@@ -256,7 +260,7 @@
}
bytes = PyByteArray_FromStringAndSize(NULL, view->len);
if (bytes == NULL) {
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
return NULL;
}
dest = PyByteArray_AS_STRING(bytes);
@@ -271,7 +275,7 @@
else {
if (_indirect_copy_nd(dest, view, fort) < 0) {
Py_DECREF(bytes);
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
return NULL;
}
}
@@ -281,12 +285,12 @@
mem->base = PyTuple_Pack(2, obj, bytes);
Py_DECREF(bytes);
if (mem->base == NULL) {
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
return NULL;
}
}
else {
- PyObject_ReleaseBuffer(obj, view);
+ PyBuffer_Release(view);
/* steal the reference */
mem->base = bytes;
}
@@ -407,7 +411,7 @@
static void
memory_dealloc(PyMemoryViewObject *self)
{
- if (self->base != NULL) {
+ if (self->view.obj != NULL) {
if (PyTuple_Check(self->base)) {
/* Special case when first element is generic object
with buffer interface and the second element is a
@@ -424,11 +428,10 @@
be "locked" and was locked and will be unlocked
again after this call.
*/
- PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0),
- &(self->view));
+ PyBuffer_Release(&(self->view));
}
else {
- PyObject_ReleaseBuffer(self->base, &(self->view));
+ PyBuffer_Release(&(self->view));
}
Py_CLEAR(self->base);
}
@@ -453,7 +456,7 @@

res = PyByteArray_FromStringAndSize(NULL, view.len);
PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C');
- PyObject_ReleaseBuffer((PyObject *)self, &view);
+ PyBuffer_Release(&view);
return res;
}

@@ -466,7 +469,7 @@

if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
return -1;
- PyObject_ReleaseBuffer((PyObject *)self, &view);
+ PyBuffer_Release(&view);
return view.len;
}


Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Wed Aug 13 17:53:07 2008
@@ -1198,7 +1198,7 @@

/* Decode via the codec registry */
buffer = NULL;
- if (PyBuffer_FillInfo(&info, (void *)s, size, 1, PyBUF_SIMPLE) < 0)
+ if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_SIMPLE) < 0)
goto onError;
buffer = PyMemoryView_FromMemory(&info);
if (buffer == NULL)

Modified: python/branches/py3k/PC/winreg.c
==============================================================================
--- python/branches/py3k/PC/winreg.c (original)
+++ python/branches/py3k/PC/winreg.c Wed Aug 13 17:53:07 2008
@@ -814,13 +814,13 @@

*retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
if (*retDataBuf==NULL){
- PyObject_ReleaseBuffer(value, &view);
+ PyBuffer_Release(&view);
PyErr_NoMemory();
return FALSE;
}
*retDataSize = view.len;
memcpy(*retDataBuf, view.buf, view.len);
- PyObject_ReleaseBuffer(value, &view);
+ PyBuffer_Release(&view);
}
break;
}

Modified: python/branches/py3k/Python/getargs.c
==============================================================================
--- python/branches/py3k/Python/getargs.c (original)
+++ python/branches/py3k/Python/getargs.c Wed Aug 13 17:53:07 2008
@@ -44,6 +44,7 @@
static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
size_t, PyObject **);
static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
+static int getbuffer(PyObject *, Py_buffer *, char**);

static int vgetargskeywords(PyObject *, PyObject *,
const char *, char **, va_list *, int);
@@ -789,7 +790,25 @@
need to be cleaned up! */

case 's': {/* text string */
- if (*format == '#') {
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg),
+ 1, 0);
+ }
+ else { /* any buffer-like object */
+ char *buf;
+ if (getbuffer(arg, p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ }
+ format++;
+ } else if (*format == '#') {
void **p = (void **)va_arg(*p_va, char **);
FETCH_SIZE;

@@ -832,10 +851,17 @@
case 'y': {/* any buffer-like object, but not PyUnicode */
void **p = (void **)va_arg(*p_va, char **);
char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
+ Py_ssize_t count;
+ if (*format == '*') {
+ if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ format++;
+ break;
+ }
+ count = convertbuffer(arg, p, &buf);
if (count < 0)
return converterr(buf, arg, msgbuf, bufsize);
- if (*format == '#') {
+ else if (*format == '#') {
FETCH_SIZE;
STORE_SIZE(count);
format++;
@@ -844,7 +870,27 @@
}

case 'z': {/* like 's' or 's#', but None is okay, stored as NULL */
- if (*format == '#') { /* any buffer-like object */
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (arg == Py_None)
+ PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg),
+ 1, 0);
+ }
+ else { /* any buffer-like object */
+ char *buf;
+ if (getbuffer(arg, p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ }
+ format++;
+ } else if (*format == '#') { /* any buffer-like object */
void **p = (void **)va_arg(*p_va, char **);
FETCH_SIZE;

@@ -1189,6 +1235,26 @@
int temp=-1;
Py_buffer view;

+ if (pb && pb->bf_releasebuffer && *format != '*')
+ /* Buffer must be released, yet caller does not use
+ the Py_buffer protocol. */
+ return converterr("pinned buffer", arg, msgbuf, bufsize);
+
+
+ if (pb && pb->bf_getbuffer && *format == '*') {
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ format++;
+ if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ PyErr_Clear();
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
+ }
+ if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
+ return converterr("contiguous buffer", arg, msgbuf, bufsize);
+ break;
+ }
+
+ /* Here we have processed w*, only w and w# remain. */
if (pb == NULL ||
pb->bf_getbuffer == NULL ||
((temp = (*pb->bf_getbuffer)(arg, &view,
@@ -1209,8 +1275,6 @@
STORE_SIZE(count);
format++;
}
- if (pb->bf_releasebuffer != NULL)
- (*pb->bf_releasebuffer)(arg, &view);
break;
}

@@ -1237,10 +1301,11 @@

count = view.len;
*p = view.buf;
- /* XXX : shouldn't really release buffer, but it should be O.K.
- */
- if (pb->bf_releasebuffer != NULL)
- (*pb->bf_releasebuffer)(arg, &view);
+ if (pb->bf_releasebuffer)
+ return converterr(
+ "string or pinned buffer",
+ arg, msgbuf, bufsize);
+
if (count < 0)
return converterr("(unspecified)", arg, msgbuf, bufsize);
{
@@ -1269,7 +1334,8 @@
*errmsg = NULL;
*p = NULL;
if (pb == NULL ||
- pb->bf_getbuffer == NULL) {
+ pb->bf_getbuffer == NULL ||
+ pb->bf_releasebuffer != NULL) {
*errmsg = "bytes or read-only buffer";
return -1;
}
@@ -1285,6 +1351,35 @@
return count;
}

+/* XXX for 3.x, getbuffer and convertbuffer can probably
+ be merged again. */
+static int
+getbuffer(PyObject *arg, Py_buffer *view, char**errmsg)
+{
+ void *buf;
+ Py_ssize_t count;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ if (pb == NULL) {
+ *errmsg = "string or buffer";
+ return -1;
+ }
+ if (pb->bf_getbuffer) {
+ if (pb->bf_getbuffer(arg, view, 0) < 0)
+ return -1;
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ *errmsg = "contiguous buffer";
+ return -1;
+ }
+ return 0;
+ }
+
+ count = convertbuffer(arg, &buf, errmsg);
+ if (count < 0)
+ return count;
+ PyBuffer_FillInfo(view, NULL, buf, count, 1, 0);
+ return 0;
+}
+
/* Support for keyword arguments donated by
Geoff Philbrick <philbric at delphi.hks.com> */

@@ -1624,6 +1719,8 @@
else
(void) va_arg(*p_va, int *);
format++;
+ } else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
+ format++;
}
break;
}

Modified: python/branches/py3k/Python/marshal.c
==============================================================================
--- python/branches/py3k/Python/marshal.c (original)
+++ python/branches/py3k/Python/marshal.c Wed Aug 13 17:53:07 2008
@@ -1168,11 +1168,14 @@
marshal_loads(PyObject *self, PyObject *args)
{
RFILE rf;
+ Py_buffer p;
char *s;
Py_ssize_t n;
PyObject* result;
- if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
+ if (!PyArg_ParseTuple(args, "s*:loads", &p))
return NULL;
+ s = p.buf;
+ n = p.len;
rf.fp = NULL;
rf.ptr = s;
rf.end = s + n;
@@ -1180,6 +1183,7 @@
rf.depth = 0;
result = read_object(&rf);
Py_DECREF(rf.strings);
+ PyBuffer_Release(&p);
return result;
}

Loading...