mirror of
https://github.com/python/cpython.git
synced 2025-08-12 12:58:50 +00:00
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:
parent
688356f59f
commit
423be95dcf
32 changed files with 721 additions and 390 deletions
|
@ -40,6 +40,12 @@ variable(s) whose address should be passed.
|
||||||
other read-buffer compatible objects pass back a reference to the raw internal
|
other read-buffer compatible objects pass back a reference to the raw internal
|
||||||
data representation.
|
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 \*]
|
``y`` (bytes object) [const char \*]
|
||||||
This variant on ``s`` convert a Python bytes object to a C pointer to a
|
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
|
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
|
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.
|
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 \*]
|
``z`` (string or ``None``) [const char \*]
|
||||||
Like ``s``, but the Python object may also be ``None``, in which case the C
|
Like ``s``, but the Python object may also be ``None``, in which case the C
|
||||||
pointer is set to *NULL*.
|
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]
|
``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int]
|
||||||
This is to ``s#`` as ``z`` is to ``s``.
|
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 \*]
|
``u`` (Unicode object) [Py_UNICODE \*]
|
||||||
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
|
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
|
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
|
single-segment buffer objects are accepted; :exc:`TypeError` is raised for all
|
||||||
others.
|
others.
|
||||||
|
|
||||||
|
``w*`` (read-write byte-oriented buffer) [Py_buffer \*]
|
||||||
|
This is to ``w`` what ``s*`` is to ``s``.
|
||||||
|
|
||||||
``(items)`` (tuple) [*matching-items*]
|
``(items)`` (tuple) [*matching-items*]
|
||||||
The object must be a Python sequence whose length is the number of format units
|
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
|
in *items*. The C arguments must correspond to the individual format units in
|
||||||
|
|
|
@ -1064,7 +1064,7 @@ about the object's memory representation. Objects
|
||||||
can use this operation to lock memory in place
|
can use this operation to lock memory in place
|
||||||
while an external caller could be modifying the contents,
|
while an external caller could be modifying the contents,
|
||||||
so there's a corresponding
|
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.
|
indicate that the external caller is done.
|
||||||
|
|
||||||
The **flags** argument to :cfunc:`PyObject_GetBuffer` specifies
|
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 new buffer interface, previously described in
|
||||||
`the PEP 3118 section <#pep-3118-revised-buffer-protocol>`__,
|
`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.
|
as well as a few other functions.
|
||||||
|
|
||||||
* Python's use of the C stdio library is now thread-safe, or at least
|
* Python's use of the C stdio library is now thread-safe, or at least
|
||||||
|
|
|
@ -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);
|
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.
|
/* Get the memory area pointed to by the indices for the buffer given.
|
||||||
|
@ -600,7 +582,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
|
||||||
per element.
|
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,
|
Py_ssize_t len, int readonly,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
@ -610,6 +592,10 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
|
||||||
and -1 (with raising an error) on error.
|
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,
|
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject* obj,
|
||||||
PyObject *format_spec);
|
PyObject *format_spec);
|
||||||
|
|
|
@ -143,6 +143,7 @@ typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
|
||||||
/* buffer interface */
|
/* buffer interface */
|
||||||
typedef struct bufferinfo {
|
typedef struct bufferinfo {
|
||||||
void *buf;
|
void *buf;
|
||||||
|
PyObject *obj; /* borrowed reference */
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
|
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
|
||||||
pointed to by strides in simple case.*/
|
pointed to by strides in simple case.*/
|
||||||
|
|
|
@ -550,7 +550,7 @@ class SizeofTest(unittest.TestCase):
|
||||||
check(32768*32768-1, size(vh) + 2*self.H)
|
check(32768*32768-1, size(vh) + 2*self.H)
|
||||||
check(32768*32768, size(vh) + 3*self.H)
|
check(32768*32768, size(vh) + 3*self.H)
|
||||||
# memory
|
# memory
|
||||||
check(memoryview(b''), size(h + 'P P2P2i5P'))
|
check(memoryview(b''), size(h + 'P PP2P2i5P'))
|
||||||
# module
|
# module
|
||||||
check(unittest, size(h + '3P'))
|
check(unittest, size(h + '3P'))
|
||||||
# None
|
# None
|
||||||
|
|
|
@ -288,7 +288,7 @@ static void free_dbt(DBT *dbt)
|
||||||
static void free_buf_view(PyObject *obj, Py_buffer *view)
|
static void free_buf_view(PyObject *obj, Py_buffer *view)
|
||||||
{
|
{
|
||||||
if (view) {
|
if (view) {
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
PyMem_Free(view);
|
PyMem_Free(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ static Py_buffer * _malloc_view(PyObject *obj)
|
||||||
if (view->ndim > 1) {
|
if (view->ndim > 1) {
|
||||||
PyErr_SetString(PyExc_BufferError,
|
PyErr_SetString(PyExc_BufferError,
|
||||||
"buffers must be single dimension");
|
"buffers must be single dimension");
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
PyMem_Free(view);
|
PyMem_Free(view);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,20 +252,20 @@ static PyObject *
|
||||||
utf_7_decode(PyObject *self,
|
utf_7_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_7_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_7_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
consumed = size;
|
consumed = pbuf.len;
|
||||||
|
|
||||||
decoded = PyUnicode_DecodeUTF7Stateful(data, size, errors,
|
decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
final ? NULL : &consumed);
|
final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -275,24 +275,20 @@ static PyObject *
|
||||||
utf_8_decode(PyObject *self,
|
utf_8_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_8_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len;
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
consumed = size;
|
|
||||||
|
|
||||||
decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
|
decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
final ? NULL : &consumed);
|
final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -302,24 +298,20 @@ static PyObject *
|
||||||
utf_16_decode(PyObject *self,
|
utf_16_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 0;
|
int byteorder = 0;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded;
|
PyObject *decoded;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
&byteorder, final ? NULL : &consumed);
|
||||||
}
|
PyBuffer_Release(&pbuf);
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
|
|
||||||
final ? NULL : &consumed);
|
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -329,53 +321,45 @@ static PyObject *
|
||||||
utf_16_le_decode(PyObject *self,
|
utf_16_le_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = -1;
|
int byteorder = -1;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_le_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
|
|
||||||
&byteorder, final ? NULL : &consumed);
|
&byteorder, final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
utf_16_be_decode(PyObject *self,
|
utf_16_be_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 1;
|
int byteorder = 1;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_be_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
return 0;
|
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
}
|
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
|
|
||||||
&byteorder, final ? NULL : &consumed);
|
&byteorder, final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -393,24 +377,20 @@ static PyObject *
|
||||||
utf_16_ex_decode(PyObject *self,
|
utf_16_ex_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 0;
|
int byteorder = 0;
|
||||||
PyObject *unicode, *tuple;
|
PyObject *unicode, *tuple;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
|
if (!PyArg_ParseTuple(args, "s*|zii:utf_16_ex_decode",
|
||||||
&data, &size, &errors, &byteorder, &final))
|
&pbuf, &errors, &byteorder, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
&byteorder, final ? NULL : &consumed);
|
||||||
}
|
PyBuffer_Release(&pbuf);
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
|
|
||||||
final ? NULL : &consumed);
|
|
||||||
if (unicode == NULL)
|
if (unicode == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
|
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
|
||||||
|
@ -422,24 +402,20 @@ static PyObject *
|
||||||
utf_32_decode(PyObject *self,
|
utf_32_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 0;
|
int byteorder = 0;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded;
|
PyObject *decoded;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
&byteorder, final ? NULL : &consumed);
|
||||||
}
|
PyBuffer_Release(&pbuf);
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
|
|
||||||
final ? NULL : &consumed);
|
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -449,53 +425,43 @@ static PyObject *
|
||||||
utf_32_le_decode(PyObject *self,
|
utf_32_le_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = -1;
|
int byteorder = -1;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_le_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_le_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
if (size < 0) {
|
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
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);
|
&byteorder, final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
utf_32_be_decode(PyObject *self,
|
utf_32_be_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 1;
|
int byteorder = 1;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
PyObject *decoded = NULL;
|
PyObject *decoded;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_be_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_be_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
|
|
||||||
&byteorder, final ? NULL : &consumed);
|
&byteorder, final ? NULL : &consumed);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (decoded == NULL)
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
|
@ -513,24 +479,20 @@ static PyObject *
|
||||||
utf_32_ex_decode(PyObject *self,
|
utf_32_ex_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int byteorder = 0;
|
int byteorder = 0;
|
||||||
PyObject *unicode, *tuple;
|
PyObject *unicode, *tuple;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zii:utf_32_ex_decode",
|
if (!PyArg_ParseTuple(args, "s*|zii:utf_32_ex_decode",
|
||||||
&data, &size, &errors, &byteorder, &final))
|
&pbuf, &errors, &byteorder, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size < 0) {
|
consumed = pbuf.len; /* This is overwritten unless final is true. */
|
||||||
PyErr_SetString(PyExc_ValueError, "negative argument");
|
unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
|
||||||
return 0;
|
&byteorder, final ? NULL : &consumed);
|
||||||
}
|
PyBuffer_Release(&pbuf);
|
||||||
consumed = size; /* This is overwritten unless final is true. */
|
|
||||||
unicode = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
|
|
||||||
final ? NULL : &consumed);
|
|
||||||
if (unicode == NULL)
|
if (unicode == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
|
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
|
||||||
|
@ -542,83 +504,88 @@ static PyObject *
|
||||||
unicode_escape_decode(PyObject *self,
|
unicode_escape_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
|
PyObject *unicode;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
|
if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode",
|
||||||
&data, &size, &errors))
|
&pbuf, &errors))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
|
unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors);
|
||||||
size);
|
PyBuffer_Release(&pbuf);
|
||||||
|
return codec_tuple(unicode, pbuf.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
raw_unicode_escape_decode(PyObject *self,
|
raw_unicode_escape_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
|
PyObject *unicode;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
|
if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode",
|
||||||
&data, &size, &errors))
|
&pbuf, &errors))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
|
unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors);
|
||||||
size);
|
PyBuffer_Release(&pbuf);
|
||||||
|
return codec_tuple(unicode, pbuf.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
latin_1_decode(PyObject *self,
|
latin_1_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
PyObject *unicode;
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
|
if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode",
|
||||||
&data, &size, &errors))
|
&pbuf, &errors))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
|
unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors);
|
||||||
size);
|
PyBuffer_Release(&pbuf);
|
||||||
|
return codec_tuple(unicode, pbuf.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
ascii_decode(PyObject *self,
|
ascii_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
PyObject *unicode;
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
|
if (!PyArg_ParseTuple(args, "s*|z:ascii_decode",
|
||||||
&data, &size, &errors))
|
&pbuf, &errors))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
|
unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors);
|
||||||
size);
|
PyBuffer_Release(&pbuf);
|
||||||
|
return codec_tuple(unicode, pbuf.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
charmap_decode(PyObject *self,
|
charmap_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size;
|
PyObject *unicode;
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
PyObject *mapping = NULL;
|
PyObject *mapping = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
|
if (!PyArg_ParseTuple(args, "s*|zO:charmap_decode",
|
||||||
&data, &size, &errors, &mapping))
|
&pbuf, &errors, &mapping))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (mapping == Py_None)
|
if (mapping == Py_None)
|
||||||
mapping = NULL;
|
mapping = NULL;
|
||||||
|
|
||||||
return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
|
unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors);
|
||||||
size);
|
PyBuffer_Release(&pbuf);
|
||||||
|
return codec_tuple(unicode, pbuf.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
|
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
|
||||||
|
@ -627,21 +594,23 @@ static PyObject *
|
||||||
mbcs_decode(PyObject *self,
|
mbcs_decode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
const char *data;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t size, consumed;
|
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
int final = 0;
|
int final = 0;
|
||||||
PyObject *decoded;
|
Py_ssize_t consumed;
|
||||||
|
PyObject *decoded = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
|
if (!PyArg_ParseTuple(args, "s*|zi:mbcs_decode",
|
||||||
&data, &size, &errors, &final))
|
&pbuf, &errors, &final))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
consumed = pbuf.len;
|
||||||
|
|
||||||
decoded = PyUnicode_DecodeMBCSStateful(
|
decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors,
|
||||||
data, size, errors, final ? NULL : &consumed);
|
final ? NULL : &consumed);
|
||||||
if (!decoded)
|
PyBuffer_Release(&pbuf);
|
||||||
|
if (decoded == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return codec_tuple(decoded, final ? size : consumed);
|
return codec_tuple(decoded, consumed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
@ -652,15 +621,21 @@ static PyObject *
|
||||||
readbuffer_encode(PyObject *self,
|
readbuffer_encode(PyObject *self,
|
||||||
PyObject *args)
|
PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pdata;
|
||||||
const char *data;
|
const char *data;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
|
if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode",
|
||||||
&data, &size, &errors))
|
&pdata, &errors))
|
||||||
return NULL;
|
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 *
|
static PyObject *
|
||||||
|
|
|
@ -1050,10 +1050,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value)
|
||||||
|
|
||||||
memcpy(self->b_ptr, ptr, size);
|
memcpy(self->b_ptr, ptr, size);
|
||||||
|
|
||||||
PyObject_ReleaseBuffer(value, &view);
|
PyBuffer_Release(&view);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
PyObject_ReleaseBuffer(value, &view);
|
PyBuffer_Release(&view);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2462,6 +2462,8 @@ static int CData_GetBuffer(PyObject *_self, Py_buffer *view, int flags)
|
||||||
if (view == NULL) return 0;
|
if (view == NULL) return 0;
|
||||||
|
|
||||||
view->buf = self->b_ptr;
|
view->buf = self->b_ptr;
|
||||||
|
view->obj = _self;
|
||||||
|
Py_INCREF(_self);
|
||||||
view->len = self->b_size;
|
view->len = self->b_size;
|
||||||
view->readonly = 0;
|
view->readonly = 0;
|
||||||
/* use default format character if not set */
|
/* use default format character if not set */
|
||||||
|
|
|
@ -357,7 +357,7 @@ fileio_seekable(PyFileIOObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
fileio_readinto(PyFileIOObject *self, PyObject *args)
|
fileio_readinto(PyFileIOObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
char *ptr;
|
Py_buffer pbuf;
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
|
|
||||||
if (self->fd < 0)
|
if (self->fd < 0)
|
||||||
|
@ -365,13 +365,14 @@ fileio_readinto(PyFileIOObject *self, PyObject *args)
|
||||||
if (!self->readable)
|
if (!self->readable)
|
||||||
return err_mode("reading");
|
return err_mode("reading");
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "w#", &ptr, &n))
|
if (!PyArg_ParseTuple(args, "w*", &pbuf))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
errno = 0;
|
errno = 0;
|
||||||
n = read(self->fd, ptr, n);
|
n = read(self->fd, pbuf.buf, pbuf.len);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -489,22 +490,24 @@ fileio_read(PyFileIOObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
fileio_write(PyFileIOObject *self, PyObject *args)
|
fileio_write(PyFileIOObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuf;
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
if (self->fd < 0)
|
if (self->fd < 0)
|
||||||
return err_closed();
|
return err_closed();
|
||||||
if (!self->writable)
|
if (!self->writable)
|
||||||
return err_mode("writing");
|
return err_mode("writing");
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#", &ptr, &n))
|
if (!PyArg_ParseTuple(args, "s*", &pbuf))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
errno = 0;
|
errno = 0;
|
||||||
n = write(self->fd, ptr, n);
|
n = write(self->fd, pbuf.buf, pbuf.len);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
|
@ -164,7 +164,7 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
|
||||||
if ((viewp)->ndim > 1) { \
|
if ((viewp)->ndim > 1) { \
|
||||||
PyErr_SetString(PyExc_BufferError, \
|
PyErr_SetString(PyExc_BufferError, \
|
||||||
"Buffer must be single dimension"); \
|
"Buffer must be single dimension"); \
|
||||||
PyObject_ReleaseBuffer((obj), (viewp)); \
|
PyBuffer_Release((viewp)); \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
@ -186,7 +186,7 @@ EVP_update(EVPobject *self, PyObject *args)
|
||||||
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
|
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
|
||||||
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
||||||
|
|
||||||
PyObject_ReleaseBuffer(obj, &view);
|
PyBuffer_Release(&view);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return 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)) {
|
if (!PyArg_Parse(name_obj, "s", &nameStr)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "name must be a string");
|
PyErr_SetString(PyExc_TypeError, "name must be a string");
|
||||||
if (data_obj)
|
if (data_obj)
|
||||||
PyObject_ReleaseBuffer(data_obj, &view);
|
PyBuffer_Release(&view);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
|
||||||
if (!digest) {
|
if (!digest) {
|
||||||
PyErr_SetString(PyExc_ValueError, "unknown hash function");
|
PyErr_SetString(PyExc_ValueError, "unknown hash function");
|
||||||
if (data_obj)
|
if (data_obj)
|
||||||
PyObject_ReleaseBuffer(data_obj, &view);
|
PyBuffer_Release(&view);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
EVP_DigestInit(&self->ctx, digest);
|
EVP_DigestInit(&self->ctx, digest);
|
||||||
|
@ -286,7 +286,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
|
||||||
if (data_obj) {
|
if (data_obj) {
|
||||||
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
|
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
|
||||||
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
||||||
PyObject_ReleaseBuffer(data_obj, &view);
|
PyBuffer_Release(&view);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -421,7 +421,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||||
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
|
||||||
|
|
||||||
if (data_obj)
|
if (data_obj)
|
||||||
PyObject_ReleaseBuffer(data_obj, &view);
|
PyBuffer_Release(&view);
|
||||||
return ret_obj;
|
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)); \
|
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int)); \
|
||||||
\
|
\
|
||||||
if (data_obj) \
|
if (data_obj) \
|
||||||
PyObject_ReleaseBuffer(data_obj, &view); \
|
PyBuffer_Release(&view); \
|
||||||
return ret_obj; \
|
return ret_obj; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* Pick up this chunk if it's not zero length */
|
||||||
if (next != end) {
|
if (next != end) {
|
||||||
PyObject *strchunk;
|
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;
|
goto bail;
|
||||||
}
|
}
|
||||||
strchunk = PyMemoryView_FromMemory(&info);
|
strchunk = PyMemoryView_FromMemory(&info);
|
||||||
|
|
|
@ -96,21 +96,26 @@ connection_dealloc(ConnectionObject* self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
connection_sendbytes(ConnectionObject *self, PyObject *args)
|
connection_sendbytes(ConnectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuffer;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
Py_ssize_t length, offset=0, size=PY_SSIZE_T_MIN;
|
Py_ssize_t length, offset=0, size=PY_SSIZE_T_MIN;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, F_RBUFFER "#|" F_PY_SSIZE_T F_PY_SSIZE_T,
|
if (!PyArg_ParseTuple(args, F_RBUFFER "*|" F_PY_SSIZE_T F_PY_SSIZE_T,
|
||||||
&buffer, &length, &offset, &size))
|
&pbuffer, &offset, &size))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buffer = pbuffer.buf;
|
||||||
|
length = pbuffer.len;
|
||||||
|
|
||||||
CHECK_WRITABLE(self);
|
CHECK_WRITABLE(self); /* XXX release buffer in case of failure */
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
|
PyBuffer_Release(&pbuffer);
|
||||||
PyErr_SetString(PyExc_ValueError, "offset is negative");
|
PyErr_SetString(PyExc_ValueError, "offset is negative");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (length < offset) {
|
if (length < offset) {
|
||||||
|
PyBuffer_Release(&pbuffer);
|
||||||
PyErr_SetString(PyExc_ValueError, "buffer length < offset");
|
PyErr_SetString(PyExc_ValueError, "buffer length < offset");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -119,10 +124,12 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
|
||||||
size = length - offset;
|
size = length - offset;
|
||||||
} else {
|
} else {
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
|
PyBuffer_Release(&pbuffer);
|
||||||
PyErr_SetString(PyExc_ValueError, "size is negative");
|
PyErr_SetString(PyExc_ValueError, "size is negative");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (offset + size > length) {
|
if (offset + size > length) {
|
||||||
|
PyBuffer_Release(&pbuffer);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"buffer length < offset + size");
|
"buffer length < offset + size");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -131,6 +138,7 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
|
||||||
|
|
||||||
res = conn_send_string(self, buffer + offset, size);
|
res = conn_send_string(self, buffer + offset, size);
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuffer);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return mp_SetError(PyExc_IOError, res);
|
return mp_SetError(PyExc_IOError, res);
|
||||||
|
|
||||||
|
@ -187,21 +195,25 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
|
||||||
char *freeme = NULL, *buffer = NULL;
|
char *freeme = NULL, *buffer = NULL;
|
||||||
Py_ssize_t res, length, offset = 0;
|
Py_ssize_t res, length, offset = 0;
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
Py_buffer pbuf;
|
||||||
if (!PyArg_ParseTuple(args, "w#|" F_PY_SSIZE_T,
|
|
||||||
&buffer, &length, &offset))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
CHECK_READABLE(self);
|
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) {
|
if (offset < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "negative offset");
|
PyErr_SetString(PyExc_ValueError, "negative offset");
|
||||||
return NULL;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset > length) {
|
if (offset > length) {
|
||||||
PyErr_SetString(PyExc_ValueError, "offset too large");
|
PyErr_SetString(PyExc_ValueError, "offset too large");
|
||||||
return NULL;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = conn_recv_string(self, buffer+offset, length-offset,
|
res = conn_recv_string(self, buffer+offset, length-offset,
|
||||||
|
@ -231,11 +243,17 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
|
||||||
PyErr_SetObject(BufferTooShort, result);
|
PyErr_SetObject(BufferTooShort, result);
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
}
|
}
|
||||||
return NULL;
|
goto _error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cleanup:
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
result = NULL;
|
||||||
|
goto _cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1704,7 +1704,7 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
|
||||||
/* Release the buffer immediately --- possibly dangerous
|
/* Release the buffer immediately --- possibly dangerous
|
||||||
but doing something else would require some re-factoring
|
but doing something else would require some re-factoring
|
||||||
*/
|
*/
|
||||||
PyObject_ReleaseBuffer(string, &view);
|
PyBuffer_Release(&view);
|
||||||
|
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
PyErr_SetString(PyExc_TypeError, "buffer has negative size");
|
PyErr_SetString(PyExc_TypeError, "buffer has negative size");
|
||||||
|
|
|
@ -1567,11 +1567,11 @@ s_unpack(PyObject *self, PyObject *input)
|
||||||
PyErr_Format(StructError,
|
PyErr_Format(StructError,
|
||||||
"unpack requires a bytes argument of length %zd",
|
"unpack requires a bytes argument of length %zd",
|
||||||
soself->s_size);
|
soself->s_size);
|
||||||
PyObject_ReleaseBuffer(input, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
result = s_unpack_internal(soself, vbuf.buf);
|
result = s_unpack_internal(soself, vbuf.buf);
|
||||||
PyObject_ReleaseBuffer(input, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1609,11 +1609,11 @@ s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
PyErr_Format(StructError,
|
PyErr_Format(StructError,
|
||||||
"unpack_from requires a buffer of at least %zd bytes",
|
"unpack_from requires a buffer of at least %zd bytes",
|
||||||
soself->s_size);
|
soself->s_size);
|
||||||
PyObject_ReleaseBuffer(input, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
|
result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
|
||||||
PyObject_ReleaseBuffer(input, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1820,6 +1820,8 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
|
||||||
if (view==NULL) goto finish;
|
if (view==NULL) goto finish;
|
||||||
|
|
||||||
view->buf = (void *)self->ob_item;
|
view->buf = (void *)self->ob_item;
|
||||||
|
view->obj = (PyObject*)self;
|
||||||
|
Py_INCREF(self);
|
||||||
if (view->buf == NULL)
|
if (view->buf == NULL)
|
||||||
view->buf = (void *)emptybuf;
|
view->buf = (void *)emptybuf;
|
||||||
view->len = (Py_SIZE(self)) * self->ob_descr->itemsize;
|
view->len = (Py_SIZE(self)) * self->ob_descr->itemsize;
|
||||||
|
|
|
@ -783,20 +783,24 @@ audioop_mul(PyObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
audioop_tomono(PyObject *self, PyObject *args)
|
audioop_tomono(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pcp;
|
||||||
signed char *cp, *ncp;
|
signed char *cp, *ncp;
|
||||||
int len, size, val1 = 0, val2 = 0;
|
int len, size, val1 = 0, val2 = 0;
|
||||||
double fac1, fac2, fval, maxval;
|
double fac1, fac2, fval, maxval;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( !PyArg_ParseTuple(args, "s#idd:tomono",
|
if ( !PyArg_ParseTuple(args, "s*idd:tomono",
|
||||||
&cp, &len, &size, &fac1, &fac2 ) )
|
&pcp, &size, &fac1, &fac2 ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
cp = pcp.buf;
|
||||||
|
len = pcp.len;
|
||||||
|
|
||||||
if ( size == 1 ) maxval = (double) 0x7f;
|
if ( size == 1 ) maxval = (double) 0x7f;
|
||||||
else if ( size == 2 ) maxval = (double) 0x7fff;
|
else if ( size == 2 ) maxval = (double) 0x7fff;
|
||||||
else if ( size == 4 ) maxval = (double) 0x7fffffff;
|
else if ( size == 4 ) maxval = (double) 0x7fffffff;
|
||||||
else {
|
else {
|
||||||
|
PyBuffer_Release(&pcp);
|
||||||
PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
|
PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
|
||||||
return 0;
|
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 == 2 ) *SHORTP(ncp, i/2) = (short)val1;
|
||||||
else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
|
else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pcp);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,7 @@ PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_a2b_uu(PyObject *self, PyObject *args)
|
binascii_a2b_uu(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pascii;
|
||||||
unsigned char *ascii_data, *bin_data;
|
unsigned char *ascii_data, *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
|
@ -195,8 +196,10 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
Py_ssize_t ascii_len, bin_len;
|
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;
|
return NULL;
|
||||||
|
ascii_data = pascii.buf;
|
||||||
|
ascii_len = pascii.len;
|
||||||
|
|
||||||
assert(ascii_len >= 0);
|
assert(ascii_len >= 0);
|
||||||
|
|
||||||
|
@ -205,8 +208,10 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
|
||||||
ascii_len--;
|
ascii_len--;
|
||||||
|
|
||||||
/* Allocate the buffer */
|
/* Allocate the buffer */
|
||||||
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
|
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
|
||||||
|
PyBuffer_Release(&pascii);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
|
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
|
||||||
|
@ -258,6 +263,7 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pascii);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +272,7 @@ PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_b2a_uu(PyObject *self, PyObject *args)
|
binascii_b2a_uu(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbin;
|
||||||
unsigned char *ascii_data, *bin_data;
|
unsigned char *ascii_data, *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
|
@ -273,17 +280,22 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
Py_ssize_t bin_len;
|
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;
|
return NULL;
|
||||||
|
bin_data = pbin.buf;
|
||||||
|
bin_len = pbin.len;
|
||||||
if ( bin_len > 45 ) {
|
if ( bin_len > 45 ) {
|
||||||
/* The 45 is a limit that appears in all uuencode's */
|
/* The 45 is a limit that appears in all uuencode's */
|
||||||
PyErr_SetString(Error, "At most 45 bytes at once");
|
PyErr_SetString(Error, "At most 45 bytes at once");
|
||||||
|
PyBuffer_Release(&pbin);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're lazy and allocate to much (fixed up later) */
|
/* 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;
|
return NULL;
|
||||||
|
}
|
||||||
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
/* Store the length */
|
/* Store the length */
|
||||||
|
@ -312,6 +324,7 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pbin);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,6 +359,7 @@ PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_a2b_base64(PyObject *self, PyObject *args)
|
binascii_a2b_base64(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pascii;
|
||||||
unsigned char *ascii_data, *bin_data;
|
unsigned char *ascii_data, *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
|
@ -354,19 +368,25 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
|
||||||
Py_ssize_t ascii_len, bin_len;
|
Py_ssize_t ascii_len, bin_len;
|
||||||
int quad_pos = 0;
|
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;
|
return NULL;
|
||||||
|
ascii_data = pascii.buf;
|
||||||
|
ascii_len = pascii.len;
|
||||||
|
|
||||||
assert(ascii_len >= 0);
|
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();
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
|
bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
|
||||||
|
|
||||||
/* Allocate the buffer */
|
/* Allocate the buffer */
|
||||||
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
|
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
|
||||||
|
PyBuffer_Release(&pascii);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
bin_len = 0;
|
bin_len = 0;
|
||||||
|
|
||||||
|
@ -419,6 +439,7 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftbits != 0) {
|
if (leftbits != 0) {
|
||||||
|
PyBuffer_Release(&pascii);
|
||||||
PyErr_SetString(Error, "Incorrect padding");
|
PyErr_SetString(Error, "Incorrect padding");
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -438,6 +459,7 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = PyBytes_FromStringAndSize("", 0);
|
rv = PyBytes_FromStringAndSize("", 0);
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pascii);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +468,7 @@ PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_b2a_base64(PyObject *self, PyObject *args)
|
binascii_b2a_base64(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuf;
|
||||||
unsigned char *ascii_data, *bin_data;
|
unsigned char *ascii_data, *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
|
@ -453,21 +476,26 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
Py_ssize_t bin_len;
|
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;
|
return NULL;
|
||||||
|
bin_data = pbuf.buf;
|
||||||
|
bin_len = pbuf.len;
|
||||||
|
|
||||||
assert(bin_len >= 0);
|
assert(bin_len >= 0);
|
||||||
|
|
||||||
if ( bin_len > BASE64_MAXBIN ) {
|
if ( bin_len > BASE64_MAXBIN ) {
|
||||||
PyErr_SetString(Error, "Too much data for base64 line");
|
PyErr_SetString(Error, "Too much data for base64 line");
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're lazy and allocate too much (fixed up later).
|
/* We're lazy and allocate too much (fixed up later).
|
||||||
"+3" leaves room for up to two pad characters and a trailing
|
"+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). */
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
|
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
|
||||||
|
@ -498,6 +526,7 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,22 +610,29 @@ PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_rlecode_hqx(PyObject *self, PyObject *args)
|
binascii_rlecode_hqx(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuf;
|
||||||
unsigned char *in_data, *out_data;
|
unsigned char *in_data, *out_data;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
Py_ssize_t in, inend, len;
|
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;
|
return NULL;
|
||||||
|
in_data = pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
|
|
||||||
assert(len >= 0);
|
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();
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
/* Worst case: output is twice as big as input (fixed later) */
|
/* 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;
|
return NULL;
|
||||||
|
}
|
||||||
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
for( in=0; in<len; in++) {
|
for( in=0; in<len; in++) {
|
||||||
|
@ -629,6 +665,7 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,6 +674,7 @@ PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_b2a_hqx(PyObject *self, PyObject *args)
|
binascii_b2a_hqx(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbin;
|
||||||
unsigned char *ascii_data, *bin_data;
|
unsigned char *ascii_data, *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
|
@ -644,17 +682,23 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
|
|
||||||
if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
|
if ( !PyArg_ParseTuple(args, "s*:b2a_hqx", &pbin) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
bin_data = pbin.buf;
|
||||||
|
len = pbin.len;
|
||||||
|
|
||||||
assert(len >= 0);
|
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();
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a buffer that is at least large enough */
|
/* 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;
|
return NULL;
|
||||||
|
}
|
||||||
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
for( ; len > 0 ; len--, bin_data++ ) {
|
for( ; len > 0 ; len--, bin_data++ ) {
|
||||||
|
@ -678,6 +722,7 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pbin);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,26 +731,35 @@ PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_rledecode_hqx(PyObject *self, PyObject *args)
|
binascii_rledecode_hqx(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pin;
|
||||||
unsigned char *in_data, *out_data;
|
unsigned char *in_data, *out_data;
|
||||||
unsigned char in_byte, in_repeat;
|
unsigned char in_byte, in_repeat;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
Py_ssize_t in_len, out_len, out_len_left;
|
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;
|
return NULL;
|
||||||
|
in_data = pin.buf;
|
||||||
|
in_len = pin.len;
|
||||||
|
|
||||||
assert(in_len >= 0);
|
assert(in_len >= 0);
|
||||||
|
|
||||||
/* Empty string is a special case */
|
/* Empty string is a special case */
|
||||||
if ( in_len == 0 )
|
if ( in_len == 0 ) {
|
||||||
|
PyBuffer_Release(&pin);
|
||||||
return PyBytes_FromStringAndSize("", 0);
|
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();
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a buffer of reasonable size. Resized when needed */
|
/* Allocate a buffer of reasonable size. Resized when needed */
|
||||||
out_len = in_len*2;
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
out_len_left = out_len;
|
out_len_left = out_len;
|
||||||
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
||||||
|
|
||||||
|
@ -718,6 +772,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
|
||||||
if ( --in_len < 0 ) { \
|
if ( --in_len < 0 ) { \
|
||||||
PyErr_SetString(Incomplete, ""); \
|
PyErr_SetString(Incomplete, ""); \
|
||||||
Py_DECREF(rv); \
|
Py_DECREF(rv); \
|
||||||
|
PyBuffer_Release(&pin); \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
b = *in_data++; \
|
b = *in_data++; \
|
||||||
|
@ -728,7 +783,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
|
||||||
if ( --out_len_left < 0 ) { \
|
if ( --out_len_left < 0 ) { \
|
||||||
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
|
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
|
||||||
if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
|
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_data = (unsigned char *)PyBytes_AS_STRING(rv) \
|
||||||
+ out_len; \
|
+ out_len; \
|
||||||
out_len_left = out_len-1; \
|
out_len_left = out_len-1; \
|
||||||
|
@ -783,6 +838,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pin);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,17 +848,21 @@ PyDoc_STRVAR(doc_crc_hqx,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_crc_hqx(PyObject *self, PyObject *args)
|
binascii_crc_hqx(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pin;
|
||||||
unsigned char *bin_data;
|
unsigned char *bin_data;
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
Py_ssize_t len;
|
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;
|
return NULL;
|
||||||
|
bin_data = pin.buf;
|
||||||
|
len = pin.len;
|
||||||
|
|
||||||
while(len-- > 0) {
|
while(len-- > 0) {
|
||||||
crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
|
crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyBuffer_Release(&pin);
|
||||||
return Py_BuildValue("i", crc);
|
return Py_BuildValue("i", crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,13 +875,17 @@ static PyObject *
|
||||||
binascii_crc32(PyObject *self, PyObject *args)
|
binascii_crc32(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
|
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
|
||||||
|
Py_buffer pbuf;
|
||||||
Byte *buf;
|
Byte *buf;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
int signed_val;
|
int signed_val;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &len, &crc32val))
|
if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buf = (Byte*)pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
signed_val = crc32(crc32val, buf, len);
|
signed_val = crc32(crc32val, buf, len);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
|
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
|
||||||
}
|
}
|
||||||
#else /* USE_ZLIB_CRC32 */
|
#else /* USE_ZLIB_CRC32 */
|
||||||
|
@ -946,13 +1010,16 @@ static unsigned int crc_32_tab[256] = {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_crc32(PyObject *self, PyObject *args)
|
binascii_crc32(PyObject *self, PyObject *args)
|
||||||
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
|
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
|
||||||
|
Py_buffer pbin;
|
||||||
unsigned char *bin_data;
|
unsigned char *bin_data;
|
||||||
unsigned int crc = 0; /* initial value of CRC */
|
unsigned int crc = 0; /* initial value of CRC */
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
unsigned int result;
|
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;
|
return NULL;
|
||||||
|
bin_data = pbin.buf;
|
||||||
|
len = pbin.len;
|
||||||
|
|
||||||
crc = ~ crc;
|
crc = ~ crc;
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
|
@ -961,6 +1028,7 @@ binascii_crc32(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (crc ^ 0xFFFFFFFF);
|
result = (crc ^ 0xFFFFFFFF);
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return PyLong_FromUnsignedLong(result & 0xffffffff);
|
return PyLong_FromUnsignedLong(result & 0xffffffff);
|
||||||
}
|
}
|
||||||
#endif /* USE_ZLIB_CRC32 */
|
#endif /* USE_ZLIB_CRC32 */
|
||||||
|
@ -969,22 +1037,29 @@ binascii_crc32(PyObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_hexlify(PyObject *self, PyObject *args)
|
binascii_hexlify(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer parg;
|
||||||
char* argbuf;
|
char* argbuf;
|
||||||
Py_ssize_t arglen;
|
Py_ssize_t arglen;
|
||||||
PyObject *retval;
|
PyObject *retval;
|
||||||
char* retbuf;
|
char* retbuf;
|
||||||
Py_ssize_t i, j;
|
Py_ssize_t i, j;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
|
if (!PyArg_ParseTuple(args, "s*:b2a_hex", &parg))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
argbuf = parg.buf;
|
||||||
|
arglen = parg.len;
|
||||||
|
|
||||||
assert(arglen >= 0);
|
assert(arglen >= 0);
|
||||||
if (arglen > PY_SSIZE_T_MAX / 2)
|
if (arglen > PY_SSIZE_T_MAX / 2) {
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
retval = PyBytes_FromStringAndSize(NULL, arglen*2);
|
retval = PyBytes_FromStringAndSize(NULL, arglen*2);
|
||||||
if (!retval)
|
if (!retval) {
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
retbuf = PyBytes_AS_STRING(retval);
|
retbuf = PyBytes_AS_STRING(retval);
|
||||||
|
|
||||||
/* make hex version of string, taken from shamodule.c */
|
/* 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';
|
c = (c>9) ? c+'a'-10 : c + '0';
|
||||||
retbuf[j++] = c;
|
retbuf[j++] = c;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,14 +1100,17 @@ to_int(int c)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binascii_unhexlify(PyObject *self, PyObject *args)
|
binascii_unhexlify(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer parg;
|
||||||
char* argbuf;
|
char* argbuf;
|
||||||
Py_ssize_t arglen;
|
Py_ssize_t arglen;
|
||||||
PyObject *retval;
|
PyObject *retval;
|
||||||
char* retbuf;
|
char* retbuf;
|
||||||
Py_ssize_t i, j;
|
Py_ssize_t i, j;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
|
if (!PyArg_ParseTuple(args, "s*:a2b_hex", &parg))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
argbuf = parg.buf;
|
||||||
|
arglen = parg.len;
|
||||||
|
|
||||||
assert(arglen >= 0);
|
assert(arglen >= 0);
|
||||||
|
|
||||||
|
@ -1040,13 +1119,16 @@ binascii_unhexlify(PyObject *self, PyObject *args)
|
||||||
* raise an exception.
|
* raise an exception.
|
||||||
*/
|
*/
|
||||||
if (arglen % 2) {
|
if (arglen % 2) {
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
PyErr_SetString(Error, "Odd-length string");
|
PyErr_SetString(Error, "Odd-length string");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
|
retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
|
||||||
if (!retval)
|
if (!retval) {
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
retbuf = PyBytes_AS_STRING(retval);
|
retbuf = PyBytes_AS_STRING(retval);
|
||||||
|
|
||||||
for (i=j=0; i < arglen; i += 2) {
|
for (i=j=0; i < arglen; i += 2) {
|
||||||
|
@ -1059,9 +1141,11 @@ binascii_unhexlify(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
retbuf[j++] = (top << 4) + bot;
|
retbuf[j++] = (top << 4) + bot;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
PyBuffer_Release(&parg);
|
||||||
Py_DECREF(retval);
|
Py_DECREF(retval);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1094,15 +1178,18 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
Py_ssize_t in, out;
|
Py_ssize_t in, out;
|
||||||
char ch;
|
char ch;
|
||||||
|
Py_buffer pdata;
|
||||||
unsigned char *data, *odata;
|
unsigned char *data, *odata;
|
||||||
Py_ssize_t datalen = 0;
|
Py_ssize_t datalen = 0;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
static char *kwlist[] = {"data", "header", NULL};
|
static char *kwlist[] = {"data", "header", NULL};
|
||||||
int header = 0;
|
int header = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i", kwlist, &data,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i", kwlist, &pdata,
|
||||||
&datalen, &header))
|
&header))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datalen = pdata.len;
|
||||||
|
|
||||||
/* We allocate the output same size as input, this is overkill.
|
/* We allocate the output same size as input, this is overkill.
|
||||||
* The previous implementation used calloc() so we'll zero out the
|
* 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);
|
odata = (unsigned char *) PyMem_Malloc(datalen);
|
||||||
if (odata == NULL) {
|
if (odata == NULL) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1160,9 +1248,11 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
|
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyMem_Free(odata);
|
PyMem_Free(odata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyMem_Free(odata);
|
PyMem_Free(odata);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1193,6 +1283,7 @@ static PyObject*
|
||||||
binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
|
binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
Py_ssize_t in, out;
|
Py_ssize_t in, out;
|
||||||
|
Py_buffer pdata;
|
||||||
unsigned char *data, *odata;
|
unsigned char *data, *odata;
|
||||||
Py_ssize_t datalen = 0, odatalen = 0;
|
Py_ssize_t datalen = 0, odatalen = 0;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
|
@ -1206,9 +1297,11 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
int crlf = 0;
|
int crlf = 0;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|iii", kwlist, &data,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|iii", kwlist, &pdata,
|
||||||
&datalen, "etabs, &istext, &header))
|
"etabs, &istext, &header))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datalen = pdata.len;
|
||||||
|
|
||||||
/* See if this string is using CRLF line ends */
|
/* See if this string is using CRLF line ends */
|
||||||
/* XXX: this function has the side effect of converting all of
|
/* 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);
|
odata = (unsigned char *) PyMem_Malloc(odatalen);
|
||||||
if (odata == NULL) {
|
if (odata == NULL) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1360,9 +1454,11 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
|
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyMem_Free(odata);
|
PyMem_Free(odata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
PyMem_Free(odata);
|
PyMem_Free(odata);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -691,12 +691,15 @@ static PyObject *
|
||||||
BZ2File_write(BZ2FileObject *self, PyObject *args)
|
BZ2File_write(BZ2FileObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *ret = NULL;
|
PyObject *ret = NULL;
|
||||||
|
Py_buffer pbuf;
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
int len;
|
||||||
int bzerror;
|
int bzerror;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "y#:write", &buf, &len))
|
if (!PyArg_ParseTuple(args, "y*:write", &pbuf))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buf = pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
|
|
||||||
ACQUIRE_LOCK(self);
|
ACQUIRE_LOCK(self);
|
||||||
switch (self->mode) {
|
switch (self->mode) {
|
||||||
|
@ -728,6 +731,7 @@ BZ2File_write(BZ2FileObject *self, PyObject *args)
|
||||||
ret = Py_None;
|
ret = Py_None;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
RELEASE_LOCK(self);
|
RELEASE_LOCK(self);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1353,6 +1357,7 @@ and return what is left in the internal buffers.\n\
|
||||||
static PyObject *
|
static PyObject *
|
||||||
BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
|
BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pdata;
|
||||||
char *data;
|
char *data;
|
||||||
int datasize;
|
int datasize;
|
||||||
int bufsize = SMALLCHUNK;
|
int bufsize = SMALLCHUNK;
|
||||||
|
@ -1361,11 +1366,15 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
|
||||||
bz_stream *bzs = &self->bzs;
|
bz_stream *bzs = &self->bzs;
|
||||||
int bzerror;
|
int bzerror;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "y#:compress", &data, &datasize))
|
if (!PyArg_ParseTuple(args, "y*:compress", &pdata))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datasize = pdata.len;
|
||||||
|
|
||||||
if (datasize == 0)
|
if (datasize == 0) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return PyBytes_FromStringAndSize("", 0);
|
return PyBytes_FromStringAndSize("", 0);
|
||||||
|
}
|
||||||
|
|
||||||
ACQUIRE_LOCK(self);
|
ACQUIRE_LOCK(self);
|
||||||
if (!self->running) {
|
if (!self->running) {
|
||||||
|
@ -1412,10 +1421,12 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
RELEASE_LOCK(self);
|
RELEASE_LOCK(self);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
RELEASE_LOCK(self);
|
RELEASE_LOCK(self);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_XDECREF(ret);
|
Py_XDECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1642,6 +1653,7 @@ unused_data attribute.\n\
|
||||||
static PyObject *
|
static PyObject *
|
||||||
BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
|
BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pdata;
|
||||||
char *data;
|
char *data;
|
||||||
int datasize;
|
int datasize;
|
||||||
int bufsize = SMALLCHUNK;
|
int bufsize = SMALLCHUNK;
|
||||||
|
@ -1650,8 +1662,10 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
|
||||||
bz_stream *bzs = &self->bzs;
|
bz_stream *bzs = &self->bzs;
|
||||||
int bzerror;
|
int bzerror;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "y#:decompress", &data, &datasize))
|
if (!PyArg_ParseTuple(args, "y*:decompress", &pdata))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datasize = pdata.len;
|
||||||
|
|
||||||
ACQUIRE_LOCK(self);
|
ACQUIRE_LOCK(self);
|
||||||
if (!self->running) {
|
if (!self->running) {
|
||||||
|
@ -1711,10 +1725,12 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
RELEASE_LOCK(self);
|
RELEASE_LOCK(self);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
RELEASE_LOCK(self);
|
RELEASE_LOCK(self);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_XDECREF(ret);
|
Py_XDECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1853,6 +1869,7 @@ static PyObject *
|
||||||
bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
int compresslevel=9;
|
int compresslevel=9;
|
||||||
|
Py_buffer pdata;
|
||||||
char *data;
|
char *data;
|
||||||
int datasize;
|
int datasize;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
|
@ -1862,14 +1879,17 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
int bzerror;
|
int bzerror;
|
||||||
static char *kwlist[] = {"data", "compresslevel", 0};
|
static char *kwlist[] = {"data", "compresslevel", 0};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y#|i",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i",
|
||||||
kwlist, &data, &datasize,
|
kwlist, &pdata,
|
||||||
&compresslevel))
|
&compresslevel))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datasize = pdata.len;
|
||||||
|
|
||||||
if (compresslevel < 1 || compresslevel > 9) {
|
if (compresslevel < 1 || compresslevel > 9) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"compresslevel must be between 1 and 9");
|
"compresslevel must be between 1 and 9");
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1878,8 +1898,10 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
bufsize = datasize + (datasize/100+1) + 600;
|
bufsize = datasize + (datasize/100+1) + 600;
|
||||||
|
|
||||||
ret = PyBytes_FromStringAndSize(NULL, bufsize);
|
ret = PyBytes_FromStringAndSize(NULL, bufsize);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(bzs, 0, sizeof(bz_stream));
|
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);
|
bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
|
||||||
if (bzerror != BZ_OK) {
|
if (bzerror != BZ_OK) {
|
||||||
Util_CatchBZ2Error(bzerror);
|
Util_CatchBZ2Error(bzerror);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1904,6 +1927,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
} else if (bzerror != BZ_FINISH_OK) {
|
} else if (bzerror != BZ_FINISH_OK) {
|
||||||
BZ2_bzCompressEnd(bzs);
|
BZ2_bzCompressEnd(bzs);
|
||||||
Util_CatchBZ2Error(bzerror);
|
Util_CatchBZ2Error(bzerror);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1911,6 +1935,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
bufsize = Util_NewBufferSize(bufsize);
|
bufsize = Util_NewBufferSize(bufsize);
|
||||||
if (_PyBytes_Resize(&ret, bufsize) < 0) {
|
if (_PyBytes_Resize(&ret, bufsize) < 0) {
|
||||||
BZ2_bzCompressEnd(bzs);
|
BZ2_bzCompressEnd(bzs);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
|
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
|
||||||
|
@ -1925,6 +1950,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
}
|
}
|
||||||
BZ2_bzCompressEnd(bzs);
|
BZ2_bzCompressEnd(bzs);
|
||||||
|
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1938,6 +1964,7 @@ use an instance of BZ2Decompressor instead.\n\
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bz2_decompress(PyObject *self, PyObject *args)
|
bz2_decompress(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pdata;
|
||||||
char *data;
|
char *data;
|
||||||
int datasize;
|
int datasize;
|
||||||
int bufsize = SMALLCHUNK;
|
int bufsize = SMALLCHUNK;
|
||||||
|
@ -1946,15 +1973,21 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
bz_stream *bzs = &_bzs;
|
bz_stream *bzs = &_bzs;
|
||||||
int bzerror;
|
int bzerror;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "y#:decompress", &data, &datasize))
|
if (!PyArg_ParseTuple(args, "y*:decompress", &pdata))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datasize = pdata.len;
|
||||||
|
|
||||||
if (datasize == 0)
|
if (datasize == 0) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return PyBytes_FromStringAndSize("", 0);
|
return PyBytes_FromStringAndSize("", 0);
|
||||||
|
}
|
||||||
|
|
||||||
ret = PyBytes_FromStringAndSize(NULL, bufsize);
|
ret = PyBytes_FromStringAndSize(NULL, bufsize);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(bzs, 0, sizeof(bz_stream));
|
memset(bzs, 0, sizeof(bz_stream));
|
||||||
|
|
||||||
|
@ -1967,6 +2000,7 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
if (bzerror != BZ_OK) {
|
if (bzerror != BZ_OK) {
|
||||||
Util_CatchBZ2Error(bzerror);
|
Util_CatchBZ2Error(bzerror);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1979,6 +2013,7 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
} else if (bzerror != BZ_OK) {
|
} else if (bzerror != BZ_OK) {
|
||||||
BZ2_bzDecompressEnd(bzs);
|
BZ2_bzDecompressEnd(bzs);
|
||||||
Util_CatchBZ2Error(bzerror);
|
Util_CatchBZ2Error(bzerror);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1986,6 +2021,7 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
BZ2_bzDecompressEnd(bzs);
|
BZ2_bzDecompressEnd(bzs);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"couldn't find end of stream");
|
"couldn't find end of stream");
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1993,6 +2029,7 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
bufsize = Util_NewBufferSize(bufsize);
|
bufsize = Util_NewBufferSize(bufsize);
|
||||||
if (_PyBytes_Resize(&ret, bufsize) < 0) {
|
if (_PyBytes_Resize(&ret, bufsize) < 0) {
|
||||||
BZ2_bzDecompressEnd(bzs);
|
BZ2_bzDecompressEnd(bzs);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
|
bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
|
||||||
|
@ -2006,6 +2043,7 @@ bz2_decompress(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BZ2_bzDecompressEnd(bzs);
|
BZ2_bzDecompressEnd(bzs);
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,18 +608,24 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
|
||||||
MultibyteCodec_State state;
|
MultibyteCodec_State state;
|
||||||
MultibyteDecodeBuffer buf;
|
MultibyteDecodeBuffer buf;
|
||||||
PyObject *errorcb;
|
PyObject *errorcb;
|
||||||
|
Py_buffer pdata;
|
||||||
const char *data, *errors = NULL;
|
const char *data, *errors = NULL;
|
||||||
Py_ssize_t datalen, finalsize;
|
Py_ssize_t datalen, finalsize;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z:decode",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|z:decode",
|
||||||
codeckwarglist, &data, &datalen, &errors))
|
codeckwarglist, &pdata, &errors))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
data = pdata.buf;
|
||||||
|
datalen = pdata.len;
|
||||||
|
|
||||||
errorcb = internal_error_callback(errors);
|
errorcb = internal_error_callback(errors);
|
||||||
if (errorcb == NULL)
|
if (errorcb == NULL) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (datalen == 0) {
|
if (datalen == 0) {
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
ERROR_DECREF(errorcb);
|
ERROR_DECREF(errorcb);
|
||||||
return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
|
return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
|
||||||
}
|
}
|
||||||
|
@ -659,11 +665,13 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
|
||||||
if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
|
if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
|
||||||
goto errorexit;
|
goto errorexit;
|
||||||
|
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
Py_XDECREF(buf.excobj);
|
Py_XDECREF(buf.excobj);
|
||||||
ERROR_DECREF(errorcb);
|
ERROR_DECREF(errorcb);
|
||||||
return make_tuple(buf.outobj, datalen);
|
return make_tuple(buf.outobj, datalen);
|
||||||
|
|
||||||
errorexit:
|
errorexit:
|
||||||
|
PyBuffer_Release(&pdata);
|
||||||
ERROR_DECREF(errorcb);
|
ERROR_DECREF(errorcb);
|
||||||
Py_XDECREF(buf.excobj);
|
Py_XDECREF(buf.excobj);
|
||||||
Py_XDECREF(buf.outobj);
|
Py_XDECREF(buf.outobj);
|
||||||
|
|
|
@ -113,15 +113,18 @@ fcntl_ioctl(PyObject *self, PyObject *args)
|
||||||
unsigned int code;
|
unsigned int code;
|
||||||
int arg;
|
int arg;
|
||||||
int ret;
|
int ret;
|
||||||
|
Py_buffer pstr;
|
||||||
char *str;
|
char *str;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
int mutate_arg = 1;
|
int mutate_arg = 1;
|
||||||
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
|
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,
|
conv_descriptor, &fd, &code,
|
||||||
&str, &len, &mutate_arg)) {
|
&pstr, &mutate_arg)) {
|
||||||
char *arg;
|
char *arg;
|
||||||
|
str = pstr.buf;
|
||||||
|
len = pstr.len;
|
||||||
|
|
||||||
if (mutate_arg) {
|
if (mutate_arg) {
|
||||||
if (len <= IOCTL_BUFSZ) {
|
if (len <= IOCTL_BUFSZ) {
|
||||||
|
@ -135,6 +138,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (len > IOCTL_BUFSZ) {
|
if (len > IOCTL_BUFSZ) {
|
||||||
|
PyBuffer_Release(&pstr);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"ioctl string arg too long");
|
"ioctl string arg too long");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -156,6 +160,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
|
||||||
if (mutate_arg && (len < IOCTL_BUFSZ)) {
|
if (mutate_arg && (len < IOCTL_BUFSZ)) {
|
||||||
memcpy(str, buf, len);
|
memcpy(str, buf, len);
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pstr); /* No further access to str below this point */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
PyErr_SetFromErrno(PyExc_IOError);
|
PyErr_SetFromErrno(PyExc_IOError);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -169,9 +174,12 @@ fcntl_ioctl(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
if (PyArg_ParseTuple(args, "O&Is#:ioctl",
|
if (PyArg_ParseTuple(args, "O&Is*:ioctl",
|
||||||
conv_descriptor, &fd, &code, &str, &len)) {
|
conv_descriptor, &fd, &code, &pstr)) {
|
||||||
|
str = pstr.buf;
|
||||||
|
len = pstr.len;
|
||||||
if (len > IOCTL_BUFSZ) {
|
if (len > IOCTL_BUFSZ) {
|
||||||
|
PyBuffer_Release(&pstr);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"ioctl string arg too long");
|
"ioctl string arg too long");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -182,9 +190,11 @@ fcntl_ioctl(PyObject *self, PyObject *args)
|
||||||
ret = ioctl(fd, code, buf);
|
ret = ioctl(fd, code, buf);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
PyBuffer_Release(&pstr);
|
||||||
PyErr_SetFromErrno(PyExc_IOError);
|
PyErr_SetFromErrno(PyExc_IOError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
PyBuffer_Release(&pstr);
|
||||||
return PyBytes_FromStringAndSize(buf, len);
|
return PyBytes_FromStringAndSize(buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -651,7 +651,7 @@ static int
|
||||||
mmap_buffer_getbuf(mmap_object *self, Py_buffer *view, int flags)
|
mmap_buffer_getbuf(mmap_object *self, Py_buffer *view, int flags)
|
||||||
{
|
{
|
||||||
CHECK_VALID(-1);
|
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)
|
(self->access == ACCESS_READ), flags) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
self->exports++;
|
self->exports++;
|
||||||
|
@ -843,7 +843,7 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
|
||||||
if (vbuf.len != slicelen) {
|
if (vbuf.len != slicelen) {
|
||||||
PyErr_SetString(PyExc_IndexError,
|
PyErr_SetString(PyExc_IndexError,
|
||||||
"mmap slice assignment is wrong size");
|
"mmap slice assignment is wrong size");
|
||||||
PyObject_ReleaseBuffer(value, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,7 +862,7 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
|
||||||
self->data[cur] = ((char *)vbuf.buf)[i];
|
self->data[cur] = ((char *)vbuf.buf)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyObject_ReleaseBuffer(value, &vbuf);
|
PyBuffer_Release(&vbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -4894,15 +4894,16 @@ Write a string to a file descriptor.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_write(PyObject *self, PyObject *args)
|
posix_write(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuf;
|
||||||
int fd;
|
int fd;
|
||||||
Py_ssize_t size;
|
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;
|
return NULL;
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
size = write(fd, buffer, (size_t)size);
|
size = write(fd, pbuf.buf, (size_t)pbuf.len);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
return PyLong_FromSsize_t(size);
|
return PyLong_FromSsize_t(size);
|
||||||
|
|
|
@ -2251,15 +2251,19 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
int recvlen = 0, flags = 0;
|
int recvlen = 0, flags = 0;
|
||||||
ssize_t readlen;
|
ssize_t readlen;
|
||||||
|
Py_buffer pbuf;
|
||||||
char *buf;
|
char *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
/* Get the buffer's memory */
|
/* Get the buffer's memory */
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv_into", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recv_into", kwlist,
|
||||||
&buf, &buflen, &recvlen, &flags))
|
&pbuf, &recvlen, &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buf = pbuf.buf;
|
||||||
|
buflen = pbuf.len;
|
||||||
|
|
||||||
if (recvlen < 0) {
|
if (recvlen < 0) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"negative buffersize in recv_into");
|
"negative buffersize in recv_into");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2271,6 +2275,7 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
/* Check if the buffer is large enough */
|
/* Check if the buffer is large enough */
|
||||||
if (buflen < recvlen) {
|
if (buflen < recvlen) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"buffer too small for requested bytes");
|
"buffer too small for requested bytes");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2280,9 +2285,11 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||||
readlen = sock_recv_guts(s, buf, recvlen, flags);
|
readlen = sock_recv_guts(s, buf, recvlen, flags);
|
||||||
if (readlen < 0) {
|
if (readlen < 0) {
|
||||||
/* Return an error. */
|
/* Return an error. */
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
/* Return the number of bytes read. Note that we do not do anything
|
/* Return the number of bytes read. Note that we do not do anything
|
||||||
special here in the case that readlen < recvlen. */
|
special here in the case that readlen < recvlen. */
|
||||||
return PyLong_FromSsize_t(readlen);
|
return PyLong_FromSsize_t(readlen);
|
||||||
|
@ -2424,18 +2431,22 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||||
|
|
||||||
int recvlen = 0, flags = 0;
|
int recvlen = 0, flags = 0;
|
||||||
ssize_t readlen;
|
ssize_t readlen;
|
||||||
|
Py_buffer pbuf;
|
||||||
char *buf;
|
char *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
PyObject *addr = NULL;
|
PyObject *addr = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom_into",
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recvfrom_into",
|
||||||
kwlist, &buf, &buflen,
|
kwlist, &pbuf,
|
||||||
&recvlen, &flags))
|
&recvlen, &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buf = pbuf.buf;
|
||||||
|
buflen = pbuf.len;
|
||||||
assert(buf != 0 && buflen > 0);
|
assert(buf != 0 && buflen > 0);
|
||||||
|
|
||||||
if (recvlen < 0) {
|
if (recvlen < 0) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"negative buffersize in recvfrom_into");
|
"negative buffersize in recvfrom_into");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2447,11 +2458,13 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||||
|
|
||||||
readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
|
readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
|
||||||
if (readlen < 0) {
|
if (readlen < 0) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
/* Return an error */
|
/* Return an error */
|
||||||
Py_XDECREF(addr);
|
Py_XDECREF(addr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
/* Return the number of bytes read and the address. Note that we do
|
/* Return the number of bytes read and the address. Note that we do
|
||||||
not do anything special here in the case that readlen < recvlen. */
|
not do anything special here in the case that readlen < recvlen. */
|
||||||
return Py_BuildValue("lN", readlen, addr);
|
return Py_BuildValue("lN", readlen, addr);
|
||||||
|
@ -2470,12 +2483,17 @@ sock_send(PySocketSockObject *s, PyObject *args)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int len, n = -1, flags = 0, timeout;
|
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;
|
return NULL;
|
||||||
|
|
||||||
if (!IS_SELECTABLE(s))
|
if (!IS_SELECTABLE(s)) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return select_error();
|
return select_error();
|
||||||
|
}
|
||||||
|
buf = pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
timeout = internal_select(s, 1);
|
timeout = internal_select(s, 1);
|
||||||
|
@ -2487,6 +2505,8 @@ sock_send(PySocketSockObject *s, PyObject *args)
|
||||||
#endif
|
#endif
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2511,12 +2531,17 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int len, n = -1, flags = 0, timeout;
|
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;
|
return NULL;
|
||||||
|
buf = pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
|
|
||||||
if (!IS_SELECTABLE(s))
|
if (!IS_SELECTABLE(s)) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return select_error();
|
return select_error();
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
do {
|
do {
|
||||||
|
@ -2535,6 +2560,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
|
||||||
len -= n;
|
len -= n;
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
|
@ -2561,24 +2587,32 @@ to tell how much data has been sent.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sock_sendto(PySocketSockObject *s, PyObject *args)
|
sock_sendto(PySocketSockObject *s, PyObject *args)
|
||||||
{
|
{
|
||||||
|
Py_buffer pbuf;
|
||||||
PyObject *addro;
|
PyObject *addro;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
Py_ssize_t len;
|
||||||
sock_addr_t addrbuf;
|
sock_addr_t addrbuf;
|
||||||
int addrlen, len, n = -1, flags, timeout;
|
int addrlen, n = -1, flags, timeout;
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if (!PyArg_ParseTuple(args, "y#O:sendto", &buf, &len, &addro)) {
|
if (!PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro)) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
if (!PyArg_ParseTuple(args, "y#iO:sendto",
|
if (!PyArg_ParseTuple(args, "y*iO:sendto",
|
||||||
&buf, &len, &flags, &addro))
|
&pbuf, &flags, &addro))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
buf = pbuf.buf;
|
||||||
|
len = pbuf.len;
|
||||||
|
|
||||||
if (!IS_SELECTABLE(s))
|
if (!IS_SELECTABLE(s)) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return select_error();
|
return select_error();
|
||||||
|
}
|
||||||
|
|
||||||
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
|
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) {
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
timeout = internal_select(s, 1);
|
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);
|
n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
PyBuffer_Release(&pbuf);
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -118,18 +118,22 @@ static PyObject *
|
||||||
PyZlib_compress(PyObject *self, PyObject *args)
|
PyZlib_compress(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *ReturnVal = NULL;
|
PyObject *ReturnVal = NULL;
|
||||||
|
Py_buffer pinput;
|
||||||
Byte *input, *output;
|
Byte *input, *output;
|
||||||
int length, level=Z_DEFAULT_COMPRESSION, err;
|
int length, level=Z_DEFAULT_COMPRESSION, err;
|
||||||
z_stream zst;
|
z_stream zst;
|
||||||
|
|
||||||
/* require Python string object, optional 'level' arg */
|
/* 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;
|
return NULL;
|
||||||
|
input = pinput.buf;
|
||||||
|
length = pinput.len;
|
||||||
|
|
||||||
zst.avail_out = length + length/1000 + 12 + 1;
|
zst.avail_out = length + length/1000 + 12 + 1;
|
||||||
|
|
||||||
output = (Byte*)malloc(zst.avail_out);
|
output = (Byte*)malloc(zst.avail_out);
|
||||||
if (output == NULL) {
|
if (output == NULL) {
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
PyErr_SetString(PyExc_MemoryError,
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
"Can't allocate memory to compress data");
|
"Can't allocate memory to compress data");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -180,6 +184,7 @@ PyZlib_compress(PyObject *self, PyObject *args)
|
||||||
zlib_error(zst, err, "while finishing compression");
|
zlib_error(zst, err, "while finishing compression");
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
free(output);
|
free(output);
|
||||||
|
|
||||||
return ReturnVal;
|
return ReturnVal;
|
||||||
|
@ -195,15 +200,18 @@ static PyObject *
|
||||||
PyZlib_decompress(PyObject *self, PyObject *args)
|
PyZlib_decompress(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *result_str;
|
PyObject *result_str;
|
||||||
|
Py_buffer pinput;
|
||||||
Byte *input;
|
Byte *input;
|
||||||
int length, err;
|
int length, err;
|
||||||
int wsize=DEF_WBITS;
|
int wsize=DEF_WBITS;
|
||||||
Py_ssize_t r_strlen=DEFAULTALLOC;
|
Py_ssize_t r_strlen=DEFAULTALLOC;
|
||||||
z_stream zst;
|
z_stream zst;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|in:decompress",
|
if (!PyArg_ParseTuple(args, "s*|in:decompress",
|
||||||
&input, &length, &wsize, &r_strlen))
|
&pinput, &wsize, &r_strlen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
input = pinput.buf;
|
||||||
|
length = pinput.len;
|
||||||
|
|
||||||
if (r_strlen <= 0)
|
if (r_strlen <= 0)
|
||||||
r_strlen = 1;
|
r_strlen = 1;
|
||||||
|
@ -211,8 +219,10 @@ PyZlib_decompress(PyObject *self, PyObject *args)
|
||||||
zst.avail_in = length;
|
zst.avail_in = length;
|
||||||
zst.avail_out = r_strlen;
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
zst.zalloc = (alloc_func)NULL;
|
zst.zalloc = (alloc_func)NULL;
|
||||||
zst.zfree = (free_func)Z_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)
|
if (PyByteArray_Resize(result_str, zst.total_out) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
return result_str;
|
return result_str;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
Py_XDECREF(result_str);
|
Py_XDECREF(result_str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -396,14 +408,19 @@ PyZlib_objcompress(compobject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int err, inplen, length = DEFAULTALLOC;
|
int err, inplen, length = DEFAULTALLOC;
|
||||||
PyObject *RetVal;
|
PyObject *RetVal;
|
||||||
|
Py_buffer pinput;
|
||||||
Byte *input;
|
Byte *input;
|
||||||
unsigned long start_total_out;
|
unsigned long start_total_out;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen))
|
if (!PyArg_ParseTuple(args, "s*:compress", &pinput))
|
||||||
return NULL;
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ENTER_ZLIB
|
ENTER_ZLIB
|
||||||
|
|
||||||
|
@ -452,6 +469,7 @@ PyZlib_objcompress(compobject *self, PyObject *args)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
LEAVE_ZLIB
|
LEAVE_ZLIB
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
return RetVal;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,13 +490,17 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
|
||||||
int err, inplen, old_length, length = DEFAULTALLOC;
|
int err, inplen, old_length, length = DEFAULTALLOC;
|
||||||
int max_length = 0;
|
int max_length = 0;
|
||||||
PyObject *RetVal;
|
PyObject *RetVal;
|
||||||
|
Py_buffer pinput;
|
||||||
Byte *input;
|
Byte *input;
|
||||||
unsigned long start_total_out;
|
unsigned long start_total_out;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|i:decompress", &input,
|
if (!PyArg_ParseTuple(args, "s*|i:decompress", &pinput,
|
||||||
&inplen, &max_length))
|
&max_length))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
input = pinput.buf;
|
||||||
|
inplen = pinput.len;
|
||||||
if (max_length < 0) {
|
if (max_length < 0) {
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"max_length must be greater than zero");
|
"max_length must be greater than zero");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -487,8 +509,10 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
|
||||||
/* limit amount of data allocated to max_length */
|
/* limit amount of data allocated to max_length */
|
||||||
if (max_length && length > max_length)
|
if (max_length && length > 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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ENTER_ZLIB
|
ENTER_ZLIB
|
||||||
|
|
||||||
|
@ -577,7 +601,7 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
LEAVE_ZLIB
|
LEAVE_ZLIB
|
||||||
|
PyBuffer_Release(&pinput);
|
||||||
return RetVal;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,12 +940,13 @@ static PyObject *
|
||||||
PyZlib_crc32(PyObject *self, PyObject *args)
|
PyZlib_crc32(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
|
unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
|
||||||
Byte *buf;
|
Py_buffer pbuf;
|
||||||
int len, signed_val;
|
int signed_val;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &len, &crc32val))
|
if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val))
|
||||||
return NULL;
|
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);
|
return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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
|
static int
|
||||||
_IsFortranContiguous(Py_buffer *view)
|
_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(dest, &view_dest, PyBUF_FULL) != 0) return -1;
|
||||||
if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
|
if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
|
||||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
PyBuffer_Release(&view_dest);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view_dest.len < view_src.len) {
|
if (view_dest.len < view_src.len) {
|
||||||
PyErr_SetString(PyExc_BufferError,
|
PyErr_SetString(PyExc_BufferError,
|
||||||
"destination is too small to receive data from source");
|
"destination is too small to receive data from source");
|
||||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
PyBuffer_Release(&view_dest);
|
||||||
PyObject_ReleaseBuffer(src, &view_src);
|
PyBuffer_Release(&view_src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,8 +598,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
|
||||||
PyBuffer_IsContiguous(&view_src, 'F'))) {
|
PyBuffer_IsContiguous(&view_src, 'F'))) {
|
||||||
/* simplest copy is all that is needed */
|
/* simplest copy is all that is needed */
|
||||||
memcpy(view_dest.buf, view_src.buf, view_src.len);
|
memcpy(view_dest.buf, view_src.buf, view_src.len);
|
||||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
PyBuffer_Release(&view_dest);
|
||||||
PyObject_ReleaseBuffer(src, &view_src);
|
PyBuffer_Release(&view_src);
|
||||||
return 0;
|
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);
|
indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
|
||||||
if (indices == NULL) {
|
if (indices == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
PyBuffer_Release(&view_dest);
|
||||||
PyObject_ReleaseBuffer(src, &view_src);
|
PyBuffer_Release(&view_src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (k=0; k<view_src.ndim;k++) {
|
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);
|
memcpy(dptr, sptr, view_src.itemsize);
|
||||||
}
|
}
|
||||||
PyMem_Free(indices);
|
PyMem_Free(indices);
|
||||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
PyBuffer_Release(&view_dest);
|
||||||
PyObject_ReleaseBuffer(src, &view_src);
|
PyBuffer_Release(&view_src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +658,7 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
int readonly, int flags)
|
||||||
{
|
{
|
||||||
if (view == NULL) return 0;
|
if (view == NULL) return 0;
|
||||||
|
@ -679,6 +669,7 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view->obj = obj;
|
||||||
view->buf = buf;
|
view->buf = buf;
|
||||||
view->len = len;
|
view->len = len;
|
||||||
view->readonly = readonly;
|
view->readonly = readonly;
|
||||||
|
@ -698,6 +689,17 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
|
||||||
return 0;
|
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 *
|
||||||
PyObject_Format(PyObject *obj, PyObject *format_spec)
|
PyObject_Format(PyObject *obj, PyObject *format_spec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,7 +69,7 @@ bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
|
||||||
ptr = "";
|
ptr = "";
|
||||||
else
|
else
|
||||||
ptr = obj->ob_bytes;
|
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) {
|
if (ret >= 0) {
|
||||||
obj->ob_exports++;
|
obj->ob_exports++;
|
||||||
}
|
}
|
||||||
|
@ -248,9 +248,9 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (va.len != -1)
|
if (va.len != -1)
|
||||||
PyObject_ReleaseBuffer(a, &va);
|
PyBuffer_Release(&va);
|
||||||
if (vb.len != -1)
|
if (vb.len != -1)
|
||||||
PyObject_ReleaseBuffer(b, &vb);
|
PyBuffer_Release(&vb);
|
||||||
return (PyObject *)result;
|
return (PyObject *)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
|
||||||
mysize = Py_SIZE(self);
|
mysize = Py_SIZE(self);
|
||||||
size = mysize + vo.len;
|
size = mysize + vo.len;
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
PyObject_ReleaseBuffer(other, &vo);
|
PyBuffer_Release(&vo);
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
}
|
}
|
||||||
if (size < self->ob_alloc) {
|
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 */
|
self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
|
||||||
}
|
}
|
||||||
else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
|
else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
|
||||||
PyObject_ReleaseBuffer(other, &vo);
|
PyBuffer_Release(&vo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
|
memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
|
||||||
PyObject_ReleaseBuffer(other, &vo);
|
PyBuffer_Release(&vo);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (vbytes.len != -1)
|
if (vbytes.len != -1)
|
||||||
PyObject_ReleaseBuffer(values, &vbytes);
|
PyBuffer_Release(&vbytes);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,10 +767,10 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
|
||||||
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
|
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
|
||||||
if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
|
if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
PyObject_ReleaseBuffer(arg, &view);
|
PyBuffer_Release(&view);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
PyObject_ReleaseBuffer(arg, &view);
|
PyBuffer_Release(&view);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +954,7 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
||||||
other_size = _getbuffer(other, &other_bytes);
|
other_size = _getbuffer(other, &other_bytes);
|
||||||
if (other_size < 0) {
|
if (other_size < 0) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
PyObject_ReleaseBuffer(self, &self_bytes);
|
PyBuffer_Release(&self_bytes);
|
||||||
Py_INCREF(Py_NotImplemented);
|
Py_INCREF(Py_NotImplemented);
|
||||||
return Py_NotImplemented;
|
return Py_NotImplemented;
|
||||||
}
|
}
|
||||||
|
@ -989,8 +989,8 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
||||||
}
|
}
|
||||||
|
|
||||||
res = cmp ? Py_True : Py_False;
|
res = cmp ? Py_True : Py_False;
|
||||||
PyObject_ReleaseBuffer(self, &self_bytes);
|
PyBuffer_Release(&self_bytes);
|
||||||
PyObject_ReleaseBuffer(other, &other_bytes);
|
PyBuffer_Release(&other_bytes);
|
||||||
Py_INCREF(res);
|
Py_INCREF(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -998,6 +998,11 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
||||||
static void
|
static void
|
||||||
bytes_dealloc(PyByteArrayObject *self)
|
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) {
|
if (self->ob_bytes != 0) {
|
||||||
PyMem_Free(self->ob_bytes);
|
PyMem_Free(self->ob_bytes);
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1070,7 @@ bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
|
||||||
res = stringlib_rfind_slice(
|
res = stringlib_rfind_slice(
|
||||||
PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
|
PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
|
||||||
subbuf.buf, subbuf.len, start, end);
|
subbuf.buf, subbuf.len, start, end);
|
||||||
PyObject_ReleaseBuffer(subobj, &subbuf);
|
PyBuffer_Release(&subbuf);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,7 +1120,7 @@ bytes_count(PyByteArrayObject *self, PyObject *args)
|
||||||
count_obj = PyLong_FromSsize_t(
|
count_obj = PyLong_FromSsize_t(
|
||||||
stringlib_count(str + start, end - start, vsub.buf, vsub.len)
|
stringlib_count(str + start, end - start, vsub.buf, vsub.len)
|
||||||
);
|
);
|
||||||
PyObject_ReleaseBuffer(sub_obj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return count_obj;
|
return count_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1191,7 +1196,7 @@ bytes_contains(PyObject *self, PyObject *arg)
|
||||||
return -1;
|
return -1;
|
||||||
pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
|
pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
|
||||||
varg.buf, varg.len, 0);
|
varg.buf, varg.len, 0);
|
||||||
PyObject_ReleaseBuffer(arg, &varg);
|
PyBuffer_Release(&varg);
|
||||||
return pos >= 0;
|
return pos >= 0;
|
||||||
}
|
}
|
||||||
if (ival < 0 || ival >= 256) {
|
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);
|
rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
PyObject_ReleaseBuffer(substr, &vsubstr);
|
PyBuffer_Release(&vsubstr);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1421,9 +1426,9 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
|
||||||
PyByteArray_Resize(result, output - output_start);
|
PyByteArray_Resize(result, output - output_start);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
PyObject_ReleaseBuffer(tableobj, &vtable);
|
PyBuffer_Release(&vtable);
|
||||||
if (delobj != NULL)
|
if (delobj != NULL)
|
||||||
PyObject_ReleaseBuffer(delobj, &vdel);
|
PyBuffer_Release(&vdel);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2047,7 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
|
||||||
if (_getbuffer(from, &vfrom) < 0)
|
if (_getbuffer(from, &vfrom) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (_getbuffer(to, &vto) < 0) {
|
if (_getbuffer(to, &vto) < 0) {
|
||||||
PyObject_ReleaseBuffer(from, &vfrom);
|
PyBuffer_Release(&vfrom);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2050,8 +2055,8 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
|
||||||
vfrom.buf, vfrom.len,
|
vfrom.buf, vfrom.len,
|
||||||
vto.buf, vto.len, count);
|
vto.buf, vto.len, count);
|
||||||
|
|
||||||
PyObject_ReleaseBuffer(from, &vfrom);
|
PyBuffer_Release(&vfrom);
|
||||||
PyObject_ReleaseBuffer(to, &vto);
|
PyBuffer_Release(&vto);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2207,7 +2212,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (n == 1)
|
if (n == 1)
|
||||||
|
@ -2215,7 +2220,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
||||||
|
|
||||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2243,12 +2248,12 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
||||||
#endif
|
#endif
|
||||||
SPLIT_ADD(s, i, len);
|
SPLIT_ADD(s, i, len);
|
||||||
FIX_PREALLOC_SIZE(list);
|
FIX_PREALLOC_SIZE(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
onError:
|
onError:
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2439,7 +2444,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (n == 1)
|
else if (n == 1)
|
||||||
|
@ -2447,7 +2452,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
||||||
|
|
||||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,12 +2473,12 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
||||||
FIX_PREALLOC_SIZE(list);
|
FIX_PREALLOC_SIZE(list);
|
||||||
if (PyList_Reverse(list) < 0)
|
if (PyList_Reverse(list) < 0)
|
||||||
goto onError;
|
goto onError;
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
onError:
|
onError:
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2749,7 +2754,7 @@ bytes_strip(PyByteArrayObject *self, PyObject *args)
|
||||||
else
|
else
|
||||||
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
||||||
if (arg != Py_None)
|
if (arg != Py_None)
|
||||||
PyObject_ReleaseBuffer(arg, &varg);
|
PyBuffer_Release(&varg);
|
||||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
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);
|
left = lstrip_helper(myptr, mysize, argptr, argsize);
|
||||||
right = mysize;
|
right = mysize;
|
||||||
if (arg != Py_None)
|
if (arg != Py_None)
|
||||||
PyObject_ReleaseBuffer(arg, &varg);
|
PyBuffer_Release(&varg);
|
||||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2817,7 +2822,7 @@ bytes_rstrip(PyByteArrayObject *self, PyObject *args)
|
||||||
left = 0;
|
left = 0;
|
||||||
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
||||||
if (arg != Py_None)
|
if (arg != Py_None)
|
||||||
PyObject_ReleaseBuffer(arg, &varg);
|
PyBuffer_Release(&varg);
|
||||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -710,9 +710,9 @@ string_concat(PyObject *a, PyObject *b)
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (va.len != -1)
|
if (va.len != -1)
|
||||||
PyObject_ReleaseBuffer(a, &va);
|
PyBuffer_Release(&va);
|
||||||
if (vb.len != -1)
|
if (vb.len != -1)
|
||||||
PyObject_ReleaseBuffer(b, &vb);
|
PyBuffer_Release(&vb);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +781,7 @@ string_contains(PyObject *self, PyObject *arg)
|
||||||
return -1;
|
return -1;
|
||||||
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
|
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
|
||||||
varg.buf, varg.len, 0);
|
varg.buf, varg.len, 0);
|
||||||
PyObject_ReleaseBuffer(arg, &varg);
|
PyBuffer_Release(&varg);
|
||||||
return pos >= 0;
|
return pos >= 0;
|
||||||
}
|
}
|
||||||
if (ival < 0 || ival >= 256) {
|
if (ival < 0 || ival >= 256) {
|
||||||
|
@ -964,7 +964,7 @@ string_subscript(PyBytesObject* self, PyObject* item)
|
||||||
static int
|
static int
|
||||||
string_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags)
|
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);
|
1, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1160,7 +1160,7 @@ string_split(PyBytesObject *self, PyObject *args)
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (n == 1)
|
else if (n == 1)
|
||||||
|
@ -1168,7 +1168,7 @@ string_split(PyBytesObject *self, PyObject *args)
|
||||||
|
|
||||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,12 +1196,12 @@ string_split(PyBytesObject *self, PyObject *args)
|
||||||
#endif
|
#endif
|
||||||
SPLIT_ADD(s, i, len);
|
SPLIT_ADD(s, i, len);
|
||||||
FIX_PREALLOC_SIZE(list);
|
FIX_PREALLOC_SIZE(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
onError:
|
onError:
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,7 +1376,7 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (n == 1)
|
else if (n == 1)
|
||||||
|
@ -1384,7 +1384,7 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
||||||
|
|
||||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1406,12 +1406,12 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
||||||
FIX_PREALLOC_SIZE(list);
|
FIX_PREALLOC_SIZE(list);
|
||||||
if (PyList_Reverse(list) < 0)
|
if (PyList_Reverse(list) < 0)
|
||||||
goto onError;
|
goto onError;
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
onError:
|
onError:
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
PyBuffer_Release(&vsub);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1690,7 +1690,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj)
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject_ReleaseBuffer(sepobj, &vsep);
|
PyBuffer_Release(&vsep);
|
||||||
|
|
||||||
if (i == 0 && j == len && PyBytes_CheckExact(self)) {
|
if (i == 0 && j == len && PyBytes_CheckExact(self)) {
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
|
@ -2945,11 +2945,11 @@ string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval,
|
if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval,
|
||||||
&view, view.len, 'C') < 0)
|
&view, view.len, 'C') < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
PyObject_ReleaseBuffer(x, &view);
|
PyBuffer_Release(&view);
|
||||||
return new;
|
return new;
|
||||||
fail:
|
fail:
|
||||||
Py_XDECREF(new);
|
Py_XDECREF(new);
|
||||||
PyObject_ReleaseBuffer(x, &view);
|
PyBuffer_Release(&view);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,19 +6,21 @@
|
||||||
static int
|
static int
|
||||||
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
|
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;
|
*view = self->view;
|
||||||
if (self->base == NULL)
|
}
|
||||||
|
if (self->view.obj == NULL)
|
||||||
return 0;
|
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);
|
PyBUF_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
|
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
|
||||||
{
|
{
|
||||||
if (self->base != NULL)
|
PyBuffer_Release(&self->view);
|
||||||
PyObject_ReleaseBuffer(self->base, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(memory_doc,
|
PyDoc_STRVAR(memory_doc,
|
||||||
|
@ -36,6 +38,8 @@ PyMemoryView_FromMemory(Py_buffer *info)
|
||||||
if (mview == NULL) return NULL;
|
if (mview == NULL) return NULL;
|
||||||
mview->base = NULL;
|
mview->base = NULL;
|
||||||
mview->view = *info;
|
mview->view = *info;
|
||||||
|
if (info->obj)
|
||||||
|
Py_INCREF(mview->view.obj);
|
||||||
return (PyObject *)mview;
|
return (PyObject *)mview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +260,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
||||||
}
|
}
|
||||||
bytes = PyByteArray_FromStringAndSize(NULL, view->len);
|
bytes = PyByteArray_FromStringAndSize(NULL, view->len);
|
||||||
if (bytes == NULL) {
|
if (bytes == NULL) {
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
dest = PyByteArray_AS_STRING(bytes);
|
dest = PyByteArray_AS_STRING(bytes);
|
||||||
|
@ -271,7 +275,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
||||||
else {
|
else {
|
||||||
if (_indirect_copy_nd(dest, view, fort) < 0) {
|
if (_indirect_copy_nd(dest, view, fort) < 0) {
|
||||||
Py_DECREF(bytes);
|
Py_DECREF(bytes);
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,12 +285,12 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
||||||
mem->base = PyTuple_Pack(2, obj, bytes);
|
mem->base = PyTuple_Pack(2, obj, bytes);
|
||||||
Py_DECREF(bytes);
|
Py_DECREF(bytes);
|
||||||
if (mem->base == NULL) {
|
if (mem->base == NULL) {
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject_ReleaseBuffer(obj, view);
|
PyBuffer_Release(view);
|
||||||
/* steal the reference */
|
/* steal the reference */
|
||||||
mem->base = bytes;
|
mem->base = bytes;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +411,7 @@ static PyMethodDef memory_methods[] = {
|
||||||
static void
|
static void
|
||||||
memory_dealloc(PyMemoryViewObject *self)
|
memory_dealloc(PyMemoryViewObject *self)
|
||||||
{
|
{
|
||||||
if (self->base != NULL) {
|
if (self->view.obj != NULL) {
|
||||||
if (PyTuple_Check(self->base)) {
|
if (PyTuple_Check(self->base)) {
|
||||||
/* Special case when first element is generic object
|
/* Special case when first element is generic object
|
||||||
with buffer interface and the second element is a
|
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
|
be "locked" and was locked and will be unlocked
|
||||||
again after this call.
|
again after this call.
|
||||||
*/
|
*/
|
||||||
PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0),
|
PyBuffer_Release(&(self->view));
|
||||||
&(self->view));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject_ReleaseBuffer(self->base, &(self->view));
|
PyBuffer_Release(&(self->view));
|
||||||
}
|
}
|
||||||
Py_CLEAR(self->base);
|
Py_CLEAR(self->base);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +456,7 @@ memory_str(PyMemoryViewObject *self)
|
||||||
|
|
||||||
res = PyByteArray_FromStringAndSize(NULL, view.len);
|
res = PyByteArray_FromStringAndSize(NULL, view.len);
|
||||||
PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C');
|
PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C');
|
||||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
PyBuffer_Release(&view);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +469,7 @@ memory_length(PyMemoryViewObject *self)
|
||||||
|
|
||||||
if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
|
if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
PyBuffer_Release(&view);
|
||||||
return view.len;
|
return view.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1198,7 +1198,7 @@ PyObject *PyUnicode_Decode(const char *s,
|
||||||
|
|
||||||
/* Decode via the codec registry */
|
/* Decode via the codec registry */
|
||||||
buffer = NULL;
|
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;
|
goto onError;
|
||||||
buffer = PyMemoryView_FromMemory(&info);
|
buffer = PyMemoryView_FromMemory(&info);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
|
|
|
@ -814,13 +814,13 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
|
||||||
|
|
||||||
*retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
|
*retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
|
||||||
if (*retDataBuf==NULL){
|
if (*retDataBuf==NULL){
|
||||||
PyObject_ReleaseBuffer(value, &view);
|
PyBuffer_Release(&view);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*retDataSize = view.len;
|
*retDataSize = view.len;
|
||||||
memcpy(*retDataBuf, view.buf, view.len);
|
memcpy(*retDataBuf, view.buf, view.len);
|
||||||
PyObject_ReleaseBuffer(value, &view);
|
PyBuffer_Release(&view);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
119
Python/getargs.c
119
Python/getargs.c
|
@ -44,6 +44,7 @@ static char *converttuple(PyObject *, const char **, va_list *, int,
|
||||||
static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
|
static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
|
||||||
size_t, PyObject **);
|
size_t, PyObject **);
|
||||||
static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
|
static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
|
||||||
|
static int getbuffer(PyObject *, Py_buffer *, char**);
|
||||||
|
|
||||||
static int vgetargskeywords(PyObject *, PyObject *,
|
static int vgetargskeywords(PyObject *, PyObject *,
|
||||||
const char *, char **, va_list *, int);
|
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! */
|
need to be cleaned up! */
|
||||||
|
|
||||||
case 's': {/* text string */
|
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 **);
|
void **p = (void **)va_arg(*p_va, char **);
|
||||||
FETCH_SIZE;
|
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 */
|
case 'y': {/* any buffer-like object, but not PyUnicode */
|
||||||
void **p = (void **)va_arg(*p_va, char **);
|
void **p = (void **)va_arg(*p_va, char **);
|
||||||
char *buf;
|
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)
|
if (count < 0)
|
||||||
return converterr(buf, arg, msgbuf, bufsize);
|
return converterr(buf, arg, msgbuf, bufsize);
|
||||||
if (*format == '#') {
|
else if (*format == '#') {
|
||||||
FETCH_SIZE;
|
FETCH_SIZE;
|
||||||
STORE_SIZE(count);
|
STORE_SIZE(count);
|
||||||
format++;
|
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 */
|
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 **);
|
void **p = (void **)va_arg(*p_va, char **);
|
||||||
FETCH_SIZE;
|
FETCH_SIZE;
|
||||||
|
|
||||||
|
@ -1189,6 +1235,26 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
int temp=-1;
|
int temp=-1;
|
||||||
Py_buffer view;
|
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 ||
|
if (pb == NULL ||
|
||||||
pb->bf_getbuffer == NULL ||
|
pb->bf_getbuffer == NULL ||
|
||||||
((temp = (*pb->bf_getbuffer)(arg, &view,
|
((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);
|
STORE_SIZE(count);
|
||||||
format++;
|
format++;
|
||||||
}
|
}
|
||||||
if (pb->bf_releasebuffer != NULL)
|
|
||||||
(*pb->bf_releasebuffer)(arg, &view);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,10 +1301,11 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
count = view.len;
|
count = view.len;
|
||||||
*p = view.buf;
|
*p = view.buf;
|
||||||
/* XXX : shouldn't really release buffer, but it should be O.K.
|
if (pb->bf_releasebuffer)
|
||||||
*/
|
return converterr(
|
||||||
if (pb->bf_releasebuffer != NULL)
|
"string or pinned buffer",
|
||||||
(*pb->bf_releasebuffer)(arg, &view);
|
arg, msgbuf, bufsize);
|
||||||
|
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
return converterr("(unspecified)", arg, msgbuf, bufsize);
|
return converterr("(unspecified)", arg, msgbuf, bufsize);
|
||||||
{
|
{
|
||||||
|
@ -1269,7 +1334,8 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
|
||||||
*errmsg = NULL;
|
*errmsg = NULL;
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
if (pb == NULL ||
|
if (pb == NULL ||
|
||||||
pb->bf_getbuffer == NULL) {
|
pb->bf_getbuffer == NULL ||
|
||||||
|
pb->bf_releasebuffer != NULL) {
|
||||||
*errmsg = "bytes or read-only buffer";
|
*errmsg = "bytes or read-only buffer";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1285,6 +1351,35 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
|
||||||
return count;
|
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
|
/* Support for keyword arguments donated by
|
||||||
Geoff Philbrick <philbric@delphi.hks.com> */
|
Geoff Philbrick <philbric@delphi.hks.com> */
|
||||||
|
|
||||||
|
@ -1624,6 +1719,8 @@ skipitem(const char **p_format, va_list *p_va, int flags)
|
||||||
else
|
else
|
||||||
(void) va_arg(*p_va, int *);
|
(void) va_arg(*p_va, int *);
|
||||||
format++;
|
format++;
|
||||||
|
} else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
|
||||||
|
format++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1168,11 +1168,14 @@ static PyObject *
|
||||||
marshal_loads(PyObject *self, PyObject *args)
|
marshal_loads(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
RFILE rf;
|
RFILE rf;
|
||||||
|
Py_buffer p;
|
||||||
char *s;
|
char *s;
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
PyObject* result;
|
PyObject* result;
|
||||||
if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
|
if (!PyArg_ParseTuple(args, "s*:loads", &p))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
s = p.buf;
|
||||||
|
n = p.len;
|
||||||
rf.fp = NULL;
|
rf.fp = NULL;
|
||||||
rf.ptr = s;
|
rf.ptr = s;
|
||||||
rf.end = s + n;
|
rf.end = s + n;
|
||||||
|
@ -1180,6 +1183,7 @@ marshal_loads(PyObject *self, PyObject *args)
|
||||||
rf.depth = 0;
|
rf.depth = 0;
|
||||||
result = read_object(&rf);
|
result = read_object(&rf);
|
||||||
Py_DECREF(rf.strings);
|
Py_DECREF(rf.strings);
|
||||||
|
PyBuffer_Release(&p);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue