Merged revisions 65654 via svnmerge from

svn+ssh://pythondev@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*.
........
This commit is contained in:
Martin v. Löwis 2008-08-13 15:53:07 +00:00
parent 688356f59f
commit 423be95dcf
32 changed files with 721 additions and 390 deletions

View File

@ -40,6 +40,12 @@ variable(s) whose address should be passed.
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 @@ variable(s) whose address should be passed.
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 @@ variable(s) whose address should be passed.
``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 @@ variable(s) whose address should be passed.
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

View File

@ -1064,7 +1064,7 @@ about the object's memory representation. Objects
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 @@ Changes to Python's build process and to the C API include:
* 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

View File

@ -526,24 +526,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
*/
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 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
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 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
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);

View File

@ -142,7 +142,8 @@ typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
/* 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.*/

View File

@ -550,7 +550,7 @@ class SizeofTest(unittest.TestCase):
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

View File

@ -288,7 +288,7 @@ static void free_dbt(DBT *dbt)
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 @@ static Py_buffer * _malloc_view(PyObject *obj)
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;
}

View File

@ -252,20 +252,20 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 @@ static PyObject *
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 *

View File

@ -1050,10 +1050,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value)
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 @@ static int CData_GetBuffer(PyObject *_self, Py_buffer *view, int flags)
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 */

View File

@ -357,7 +357,7 @@ fileio_seekable(PyFileIOObject *self)
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 @@ fileio_readinto(PyFileIOObject *self, PyObject *args)
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 @@ fileio_read(PyFileIOObject *self, PyObject *args)
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;

View File

@ -164,7 +164,7 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
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_update(EVPobject *self, PyObject *args)
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 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
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 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
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 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
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 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
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 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int)); \
\
if (data_obj) \
PyObject_ReleaseBuffer(data_obj, &view); \
PyBuffer_Release(&view); \
return ret_obj; \
}

View File

@ -261,7 +261,7 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict)
/* 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);

View File

@ -96,21 +96,26 @@ connection_dealloc(ConnectionObject* self)
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 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
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 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
res = conn_send_string(self, buffer + offset, size);
PyBuffer_Release(&pbuffer);
if (res < 0)
return mp_SetError(PyExc_IOError, res);
@ -187,21 +195,25 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
char *freeme = NULL, *buffer = NULL;
Py_ssize_t res, length, offset = 0;
PyObject *result = NULL;
if (!PyArg_ParseTuple(args, "w#|" F_PY_SSIZE_T,
&buffer, &length, &offset))
return NULL;
Py_buffer pbuf;
CHECK_READABLE(self);
if (!PyArg_ParseTuple(args, "w*|" F_PY_SSIZE_T,
&pbuf, &offset))
return NULL;
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 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
PyErr_SetObject(BufferTooShort, result);
Py_DECREF(result);
}
return NULL;
goto _error;
}
}
_cleanup:
PyBuffer_Release(&pbuf);
return result;
_error:
result = NULL;
goto _cleanup;
}
/*

View File

@ -1704,7 +1704,7 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
/* 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");

View File

@ -1567,11 +1567,11 @@ s_unpack(PyObject *self, PyObject *input)
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 @@ s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
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;
}

View File

@ -1820,6 +1820,8 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
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;

View File

@ -783,20 +783,24 @@ audioop_mul(PyObject *self, PyObject *args)
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 @@ audioop_tomono(PyObject *self, PyObject *args)
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;
}

View File

@ -188,6 +188,7 @@ PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
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 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
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 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
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 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
return NULL;
}
}
PyBuffer_Release(&pascii);
return rv;
}
@ -266,6 +272,7 @@ PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
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 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
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 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = NULL;
}
PyBuffer_Release(&pbin);
return rv;
}
@ -346,6 +359,7 @@ PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
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 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
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 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
}
if (leftbits != 0) {
PyBuffer_Release(&pascii);
PyErr_SetString(Error, "Incorrect padding");
Py_DECREF(rv);
return NULL;
@ -438,6 +459,7 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = PyBytes_FromStringAndSize("", 0);
}
PyBuffer_Release(&pascii);
return rv;
}
@ -446,6 +468,7 @@ PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
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 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
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 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = NULL;
}
PyBuffer_Release(&pbuf);
return rv;
}
@ -581,22 +610,29 @@ PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
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 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = NULL;
}
PyBuffer_Release(&pbuf);
return rv;
}
@ -637,6 +674,7 @@ PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
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 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
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 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = NULL;
}
PyBuffer_Release(&pbin);
return rv;
}
@ -686,26 +731,35 @@ PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
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 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --in_len < 0 ) { \
PyErr_SetString(Incomplete, ""); \
Py_DECREF(rv); \
PyBuffer_Release(&pin); \
return NULL; \
} \
b = *in_data++; \
@ -728,7 +783,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
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 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
Py_DECREF(rv);
rv = NULL;
}
PyBuffer_Release(&pin);
return rv;
}
@ -792,17 +848,21 @@ PyDoc_STRVAR(doc_crc_hqx,
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 @@ static PyObject *
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 unsigned int crc_32_tab[256] = {
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 @@ binascii_crc32(PyObject *self, PyObject *args)
}
result = (crc ^ 0xFFFFFFFF);
PyBuffer_Release(&pbuf);
return PyLong_FromUnsignedLong(result & 0xffffffff);
}
#endif /* USE_ZLIB_CRC32 */
@ -969,22 +1037,29 @@ binascii_crc32(PyObject *self, PyObject *args)
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 @@ binascii_hexlify(PyObject *self, PyObject *args)
c = (c>9) ? c+'a'-10 : c + '0';
retbuf[j++] = c;
}
PyBuffer_Release(&parg);
return retval;
}
@ -1024,14 +1100,17 @@ to_int(int c)
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 @@ binascii_unhexlify(PyObject *self, PyObject *args)
* 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 @@ binascii_unhexlify(PyObject *self, PyObject *args)
}
retbuf[j++] = (top << 4) + bot;
}
PyBuffer_Release(&parg);
return retval;
finally:
PyBuffer_Release(&parg);
Py_DECREF(retval);
return NULL;
}
@ -1094,15 +1178,18 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
{
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 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(datalen);
if (odata == NULL) {
PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@ -1160,9 +1248,11 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
}
}
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 @@ static PyObject*
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 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
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 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(odatalen);
if (odata == NULL) {
PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@ -1360,9 +1454,11 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}

View File

@ -691,12 +691,15 @@ static PyObject *
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 @@ BZ2File_write(BZ2FileObject *self, PyObject *args)
ret = Py_None;
cleanup:
PyBuffer_Release(&pbuf);
RELEASE_LOCK(self);
return ret;
}
@ -1353,6 +1357,7 @@ and return what is left in the internal buffers.\n\
static PyObject *
BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
{
Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@ -1361,11 +1366,15 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
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 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
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 @@ unused_data attribute.\n\
static PyObject *
BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
{
Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@ -1650,8 +1662,10 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
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 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
}
RELEASE_LOCK(self);
PyBuffer_Release(&pdata);
return ret;
error:
RELEASE_LOCK(self);
PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
@ -1853,6 +1869,7 @@ static PyObject *
bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
{
int compresslevel=9;
Py_buffer pdata;
char *data;
int datasize;
int bufsize;
@ -1862,14 +1879,17 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
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 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
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 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
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 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
} else if (bzerror != BZ_FINISH_OK) {
BZ2_bzCompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@ -1911,6 +1935,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
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_compress(PyObject *self, PyObject *args, PyObject *kwargs)
}
BZ2_bzCompressEnd(bzs);
PyBuffer_Release(&pdata);
return ret;
}
@ -1938,6 +1964,7 @@ use an instance of BZ2Decompressor instead.\n\
static PyObject *
bz2_decompress(PyObject *self, PyObject *args)
{
Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@ -1946,15 +1973,21 @@ bz2_decompress(PyObject *self, PyObject *args)
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 @@ bz2_decompress(PyObject *self, PyObject *args)
if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror);
Py_DECREF(ret);
PyBuffer_Release(&pdata);
return NULL;
}
@ -1979,6 +2013,7 @@ bz2_decompress(PyObject *self, PyObject *args)
} else if (bzerror != BZ_OK) {
BZ2_bzDecompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@ -1986,6 +2021,7 @@ bz2_decompress(PyObject *self, PyObject *args)
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 @@ bz2_decompress(PyObject *self, PyObject *args)
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_decompress(PyObject *self, PyObject *args)
}
}
BZ2_bzDecompressEnd(bzs);
PyBuffer_Release(&pdata);
return ret;
}

View File

@ -608,18 +608,24 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
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 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
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);

View File

@ -113,15 +113,18 @@ fcntl_ioctl(PyObject *self, PyObject *args)
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 @@ fcntl_ioctl(PyObject *self, PyObject *args)
}
else {
if (len > IOCTL_BUFSZ) {
PyBuffer_Release(&pstr);
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
@ -156,6 +160,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
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 @@ fcntl_ioctl(PyObject *self, PyObject *args)
}
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 @@ fcntl_ioctl(PyObject *self, PyObject *args)
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);
}

View File

@ -651,7 +651,7 @@ static int
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 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
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 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
self->data[cur] = ((char *)vbuf.buf)[i];
}
}
PyObject_ReleaseBuffer(value, &vbuf);
PyBuffer_Release(&vbuf);
return 0;
}
else {

View File

@ -4894,15 +4894,16 @@ Write a string to a file descriptor.");
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);

View File

@ -2251,15 +2251,19 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
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 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
/* 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 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
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 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
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 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
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 @@ sock_send(PySocketSockObject *s, PyObject *args)
{
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 @@ sock_send(PySocketSockObject *s, PyObject *args)
#endif
Py_END_ALLOW_THREADS
PyBuffer_Release(&pbuf);
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;
@ -2511,12 +2531,17 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
{
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 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
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 @@ to tell how much data has been sent.");
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 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
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;

View File

@ -118,18 +118,22 @@ static PyObject *
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 @@ PyZlib_compress(PyObject *self, PyObject *args)
zlib_error(zst, err, "while finishing compression");
error:
PyBuffer_Release(&pinput);
free(output);
return ReturnVal;
@ -195,15 +200,18 @@ static PyObject *
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 @@ PyZlib_decompress(PyObject *self, PyObject *args)
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 @@ PyZlib_decompress(PyObject *self, PyObject *args)
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 @@ PyZlib_objcompress(compobject *self, PyObject *args)
{
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 @@ PyZlib_objcompress(compobject *self, PyObject *args)
error:
LEAVE_ZLIB
PyBuffer_Release(&pinput);
return RetVal;
}
@ -472,13 +490,17 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
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 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
/* 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 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
error:
LEAVE_ZLIB
PyBuffer_Release(&pinput);
return RetVal;
}
@ -916,12 +940,13 @@ static PyObject *
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);
}

View File

@ -349,16 +349,6 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
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 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
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 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
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 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
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 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
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 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
}
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 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
return -1;
}
view->obj = obj;
view->buf = buf;
view->len = len;
view->readonly = readonly;
@ -698,6 +689,17 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
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)
{

View File

@ -69,7 +69,7 @@ bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
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 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
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 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
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 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
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 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
finish:
if (vbytes.len != -1)
PyObject_ReleaseBuffer(values, &vbytes);
PyBuffer_Release(&vbytes);
return res;
}
@ -767,10 +767,10 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
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 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
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 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
}
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 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
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 @@ bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
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 @@ bytes_count(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_contains(PyObject *self, PyObject *arg)
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 @@ _bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
done:
PyObject_ReleaseBuffer(substr, &vsubstr);
PyBuffer_Release(&vsubstr);
return rv;
}
@ -1421,9 +1426,9 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
PyObject_ReleaseBuffer(subobj, &vsub);
PyBuffer_Release(&vsub);
return NULL;
}
@ -2243,12 +2248,12 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
#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 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
PyObject_ReleaseBuffer(subobj, &vsub);
PyBuffer_Release(&vsub);
return NULL;
}
@ -2468,12 +2473,12 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_strip(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_lstrip(PyByteArrayObject *self, PyObject *args)
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 @@ bytes_rstrip(PyByteArrayObject *self, PyObject *args)
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);
}

View File

@ -710,9 +710,9 @@ string_concat(PyObject *a, PyObject *b)
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 @@ string_contains(PyObject *self, PyObject *arg)
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 @@ string_subscript(PyBytesObject* self, PyObject* item)
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 @@ string_split(PyBytesObject *self, PyObject *args)
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 @@ string_split(PyBytesObject *self, PyObject *args)
list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
PyObject_ReleaseBuffer(subobj, &vsub);
PyBuffer_Release(&vsub);
return NULL;
}
@ -1196,12 +1196,12 @@ string_split(PyBytesObject *self, PyObject *args)
#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 @@ string_rsplit(PyBytesObject *self, PyObject *args)
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 @@ string_rsplit(PyBytesObject *self, PyObject *args)
list = PyList_New(PREALLOC_SIZE(maxsplit));
if (list == NULL) {
PyObject_ReleaseBuffer(subobj, &vsub);
PyBuffer_Release(&vsub);
return NULL;
}
@ -1406,12 +1406,12 @@ string_rsplit(PyBytesObject *self, PyObject *args)
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 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj)
j++;
}
PyObject_ReleaseBuffer(sepobj, &vsep);
PyBuffer_Release(&vsep);
if (i == 0 && j == len && PyBytes_CheckExact(self)) {
Py_INCREF(self);
@ -2945,11 +2945,11 @@ string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
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;
}

View File

@ -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 @@ PyMemoryView_FromMemory(Py_buffer *info)
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 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
}
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 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
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 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
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 PyMethodDef memory_methods[] = {
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 @@ memory_dealloc(PyMemoryViewObject *self)
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 @@ memory_str(PyMemoryViewObject *self)
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 @@ memory_length(PyMemoryViewObject *self)
if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
return -1;
PyObject_ReleaseBuffer((PyObject *)self, &view);
PyBuffer_Release(&view);
return view.len;
}

View File

@ -1198,7 +1198,7 @@ PyObject *PyUnicode_Decode(const char *s,
/* 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)

View File

@ -814,13 +814,13 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
*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;
}

View File

@ -44,6 +44,7 @@ static char *converttuple(PyObject *, const char **, va_list *, int,
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 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
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 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
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 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
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 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
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 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
STORE_SIZE(count);
format++;
}
if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(arg, &view);
break;
}
@ -1237,10 +1301,11 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
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 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
*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 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
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@delphi.hks.com> */
@ -1624,6 +1719,8 @@ skipitem(const char **p_format, va_list *p_va, int flags)
else
(void) va_arg(*p_va, int *);
format++;
} else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
format++;
}
break;
}

View File

@ -1168,11 +1168,14 @@ static PyObject *
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 @@ marshal_loads(PyObject *self, PyObject *args)
rf.depth = 0;
result = read_object(&rf);
Py_DECREF(rf.strings);
PyBuffer_Release(&p);
return result;
}