summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2008-08-12 14:49:50 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2008-08-12 14:49:50 (GMT)
commitf91d46a17d85da323895950852093117bc21f860 (patch)
treec6a3e68cf22a6a102f9c1dc780438f0307b6588f /Modules
parentaa8efbf08469c3667ed22362c0e10b83ae124c0b (diff)
downloadcpython-f91d46a17d85da323895950852093117bc21f860.zip
cpython-f91d46a17d85da323895950852093117bc21f860.tar.gz
cpython-f91d46a17d85da323895950852093117bc21f860.tar.bz2
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*.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_codecsmodule.c267
-rw-r--r--Modules/_fileio.c15
-rw-r--r--Modules/_multiprocessing/connection.h22
-rw-r--r--Modules/bz2module.c58
-rw-r--r--Modules/posixmodule.c7
-rw-r--r--Modules/socketmodule.c42
6 files changed, 227 insertions, 184 deletions
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index d4eb0d5..9250e3e 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -232,20 +232,20 @@ static PyObject *
utf_7_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_7_decode",
- &data, &size, &errors, &final))
- return NULL;
- consumed = size;
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_7_decode",
+ &pbuf, &errors, &final))
+ return NULL;
+ consumed = pbuf.len;
- decoded = PyUnicode_DecodeUTF7Stateful(data, size, errors,
- final ? NULL : &consumed);
+ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors,
+ final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -255,24 +255,20 @@ static PyObject *
utf_8_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_8_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size;
-
- decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
+ consumed = pbuf.len;
+
+ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors,
final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -282,24 +278,20 @@ static PyObject *
utf_16_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -309,53 +301,45 @@ static PyObject *
utf_16_le_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_le_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
-
}
static PyObject *
utf_16_be_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_16_be_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -373,24 +357,20 @@ static PyObject *
utf_16_ex_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;
- if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
- &data, &size, &errors, &byteorder, &final))
+ if (!PyArg_ParseTuple(args, "s*|zii:utf_16_ex_decode",
+ &pbuf, &errors, &byteorder, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@@ -402,24 +382,20 @@ static PyObject *
utf_32_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -429,53 +405,43 @@ static PyObject *
utf_32_le_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
- PyObject *decoded = NULL;
+ PyObject *decoded;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_le_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_le_decode",
+ &pbuf, &errors, &final))
return NULL;
-
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
- &byteorder, final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
-
}
static PyObject *
utf_32_be_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
- PyObject *decoded = NULL;
+ PyObject *decoded;
- if (!PyArg_ParseTuple(args, "t#|zi:utf_32_be_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:utf_32_be_decode",
+ &pbuf, &errors, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
- &byteorder, final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@@ -493,24 +459,20 @@ static PyObject *
utf_32_ex_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;
- if (!PyArg_ParseTuple(args, "t#|zii:utf_32_ex_decode",
- &data, &size, &errors, &byteorder, &final))
+ if (!PyArg_ParseTuple(args, "s*|zii:utf_32_ex_decode",
+ &pbuf, &errors, &byteorder, &final))
return NULL;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError, "negative argument");
- return 0;
- }
- consumed = size; /* This is overwritten unless final is true. */
- unicode = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
- final ? NULL : &consumed);
+ consumed = pbuf.len; /* This is overwritten unless final is true. */
+ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
+ &byteorder, final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@@ -522,83 +484,88 @@ static PyObject *
unicode_escape_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
+ PyObject *unicode;
- if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode",
+ &pbuf, &errors))
return NULL;
- return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}
static PyObject *
raw_unicode_escape_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
const char *errors = NULL;
+ PyObject *unicode;
- if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode",
+ &pbuf, &errors))
return NULL;
- return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}
static PyObject *
latin_1_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;
- if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode",
+ &pbuf, &errors))
return NULL;
- return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}
static PyObject *
ascii_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;
- if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:ascii_decode",
+ &pbuf, &errors))
return NULL;
- return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
- size);
+ unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}
static PyObject *
charmap_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size;
+ Py_buffer pbuf;
+ PyObject *unicode;
const char *errors = NULL;
PyObject *mapping = NULL;
- if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
- &data, &size, &errors, &mapping))
+ if (!PyArg_ParseTuple(args, "s*|zO:charmap_decode",
+ &pbuf, &errors, &mapping))
return NULL;
if (mapping == Py_None)
mapping = NULL;
- return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
- size);
+ unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors);
+ PyBuffer_Release(&pbuf);
+ return codec_tuple(unicode, pbuf.len);
}
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
@@ -607,21 +574,23 @@ static PyObject *
mbcs_decode(PyObject *self,
PyObject *args)
{
- const char *data;
- Py_ssize_t size, consumed;
+ Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
- PyObject *decoded;
+ Py_ssize_t consumed;
+ PyObject *decoded = NULL;
- if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
- &data, &size, &errors, &final))
+ if (!PyArg_ParseTuple(args, "s*|zi:mbcs_decode",
+ &pbuf, &errors, &final))
return NULL;
+ consumed = pbuf.len;
- decoded = PyUnicode_DecodeMBCSStateful(
- data, size, errors, final ? NULL : &consumed);
- if (!decoded)
+ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors,
+ final ? NULL : &consumed);
+ PyBuffer_Release(&pbuf);
+ if (decoded == NULL)
return NULL;
- return codec_tuple(decoded, final ? size : consumed);
+ return codec_tuple(decoded, consumed);
}
#endif /* MS_WINDOWS */
diff --git a/Modules/_fileio.c b/Modules/_fileio.c
index 21608f1..58462dd 100644
--- a/Modules/_fileio.c
+++ b/Modules/_fileio.c
@@ -357,7 +357,7 @@ fileio_seekable(PyFileIOObject *self)
static PyObject *
fileio_readinto(PyFileIOObject *self, PyObject *args)
{
- char *ptr;
+ Py_buffer pbuf;
Py_ssize_t n;
if (self->fd < 0)
@@ -365,13 +365,14 @@ fileio_readinto(PyFileIOObject *self, PyObject *args)
if (!self->readable)
return err_mode("reading");
- if (!PyArg_ParseTuple(args, "w#", &ptr, &n))
+ if (!PyArg_ParseTuple(args, "w*", &pbuf))
return NULL;
Py_BEGIN_ALLOW_THREADS
errno = 0;
- n = read(self->fd, ptr, n);
+ n = read(self->fd, pbuf.buf, pbuf.len);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (n < 0) {
if (errno == EAGAIN)
Py_RETURN_NONE;
@@ -489,22 +490,24 @@ fileio_read(PyFileIOObject *self, PyObject *args)
static PyObject *
fileio_write(PyFileIOObject *self, PyObject *args)
{
+ Py_buffer pbuf;
Py_ssize_t n;
- char *ptr;
if (self->fd < 0)
return err_closed();
if (!self->writable)
return err_mode("writing");
- if (!PyArg_ParseTuple(args, "s#", &ptr, &n))
+ if (!PyArg_ParseTuple(args, "s*", &pbuf))
return NULL;
Py_BEGIN_ALLOW_THREADS
errno = 0;
- n = write(self->fd, ptr, n);
+ n = write(self->fd, pbuf.buf, pbuf.len);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
+
if (n < 0) {
if (errno == EAGAIN)
Py_RETURN_NONE;
diff --git a/Modules/_multiprocessing/connection.h b/Modules/_multiprocessing/connection.h
index 4b475c6..66a3e8a 100644
--- a/Modules/_multiprocessing/connection.h
+++ b/Modules/_multiprocessing/connection.h
@@ -187,21 +187,25 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
char *freeme = NULL, *buffer = NULL;
Py_ssize_t res, length, offset = 0;
PyObject *result = NULL;
+ Py_buffer pbuf;
- if (!PyArg_ParseTuple(args, "w#|" F_PY_SSIZE_T,
- &buffer, &length, &offset))
+ CHECK_READABLE(self);
+
+ if (!PyArg_ParseTuple(args, "w*|" F_PY_SSIZE_T,
+ &pbuf, &offset))
return NULL;
- CHECK_READABLE(self);
+ buffer = pbuf.buf;
+ length = pbuf.len;
if (offset < 0) {
PyErr_SetString(PyExc_ValueError, "negative offset");
- return NULL;
+ goto _error;
}
if (offset > length) {
PyErr_SetString(PyExc_ValueError, "offset too large");
- return NULL;
+ goto _error;
}
res = conn_recv_string(self, buffer+offset, length-offset,
@@ -231,11 +235,17 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
PyErr_SetObject(BufferTooShort, result);
Py_DECREF(result);
}
- return NULL;
+ goto _error;
}
}
+_cleanup:
+ PyBuffer_Release(&pbuf);
return result;
+
+_error:
+ result = NULL;
+ goto _cleanup;
}
/*
diff --git a/Modules/bz2module.c b/Modules/bz2module.c
index 3929219..b5542bf 100644
--- a/Modules/bz2module.c
+++ b/Modules/bz2module.c
@@ -792,12 +792,15 @@ static PyObject *
BZ2File_write(BZ2FileObject *self, PyObject *args)
{
PyObject *ret = NULL;
+ Py_buffer pbuf;
char *buf;
int len;
int bzerror;
- if (!PyArg_ParseTuple(args, "s#:write", &buf, &len))
+ if (!PyArg_ParseTuple(args, "s*:write", &pbuf))
return NULL;
+ buf = pbuf.buf;
+ len = pbuf.len;
ACQUIRE_LOCK(self);
switch (self->mode) {
@@ -831,6 +834,7 @@ BZ2File_write(BZ2FileObject *self, PyObject *args)
ret = Py_None;
cleanup:
+ PyBuffer_Release(&pbuf);
RELEASE_LOCK(self);
return ret;
}
@@ -1549,6 +1553,7 @@ and return what is left in the internal buffers.\n\
static PyObject *
BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -1557,11 +1562,15 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
bz_stream *bzs = &self->bzs;
int bzerror;
- if (!PyArg_ParseTuple(args, "s#:compress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "s*:compress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;
- if (datasize == 0)
+ if (datasize == 0) {
+ PyBuffer_Release(&pdata);
return PyString_FromString("");
+ }
ACQUIRE_LOCK(self);
if (!self->running) {
@@ -1606,10 +1615,12 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
_PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
return ret;
error:
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
@@ -1833,6 +1844,7 @@ unused_data attribute.\n\
static PyObject *
BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -1841,8 +1853,10 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
bz_stream *bzs = &self->bzs;
int bzerror;
- if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;
ACQUIRE_LOCK(self);
if (!self->running) {
@@ -1899,10 +1913,12 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
_PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
return ret;
error:
RELEASE_LOCK(self);
+ PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
@@ -2041,6 +2057,7 @@ static PyObject *
bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
{
int compresslevel=9;
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize;
@@ -2050,14 +2067,17 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
int bzerror;
static char *kwlist[] = {"data", "compresslevel", 0};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i",
- kwlist, &data, &datasize,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i",
+ kwlist, &pdata,
&compresslevel))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;
if (compresslevel < 1 || compresslevel > 9) {
PyErr_SetString(PyExc_ValueError,
"compresslevel must be between 1 and 9");
+ PyBuffer_Release(&pdata);
return NULL;
}
@@ -2066,8 +2086,10 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
bufsize = datasize + (datasize/100+1) + 600;
ret = PyString_FromStringAndSize(NULL, bufsize);
- if (!ret)
+ if (!ret) {
+ PyBuffer_Release(&pdata);
return NULL;
+ }
memset(bzs, 0, sizeof(bz_stream));
@@ -2079,6 +2101,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2092,6 +2115,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
} else if (bzerror != BZ_FINISH_OK) {
BZ2_bzCompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2099,6 +2123,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
bufsize = Util_NewBufferSize(bufsize);
if (_PyString_Resize(&ret, bufsize) < 0) {
BZ2_bzCompressEnd(bzs);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2111,6 +2136,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
BZ2_bzCompressEnd(bzs);
+ PyBuffer_Release(&pdata);
return ret;
}
@@ -2124,6 +2150,7 @@ use an instance of BZ2Decompressor instead.\n\
static PyObject *
bz2_decompress(PyObject *self, PyObject *args)
{
+ Py_buffer pdata;
char *data;
int datasize;
int bufsize = SMALLCHUNK;
@@ -2132,15 +2159,21 @@ bz2_decompress(PyObject *self, PyObject *args)
bz_stream *bzs = &_bzs;
int bzerror;
- if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+ if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
return NULL;
+ data = pdata.buf;
+ datasize = pdata.len;
- if (datasize == 0)
+ if (datasize == 0) {
+ PyBuffer_Release(&pdata);
return PyString_FromString("");
+ }
ret = PyString_FromStringAndSize(NULL, bufsize);
- if (!ret)
+ if (!ret) {
+ PyBuffer_Release(&pdata);
return NULL;
+ }
memset(bzs, 0, sizeof(bz_stream));
@@ -2153,6 +2186,7 @@ bz2_decompress(PyObject *self, PyObject *args)
if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror);
Py_DECREF(ret);
+ PyBuffer_Release(&pdata);
return NULL;
}
@@ -2165,6 +2199,7 @@ bz2_decompress(PyObject *self, PyObject *args)
} else if (bzerror != BZ_OK) {
BZ2_bzDecompressEnd(bzs);
Util_CatchBZ2Error(bzerror);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2172,6 +2207,7 @@ bz2_decompress(PyObject *self, PyObject *args)
BZ2_bzDecompressEnd(bzs);
PyErr_SetString(PyExc_ValueError,
"couldn't find end of stream");
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2179,6 +2215,7 @@ bz2_decompress(PyObject *self, PyObject *args)
bufsize = Util_NewBufferSize(bufsize);
if (_PyString_Resize(&ret, bufsize) < 0) {
BZ2_bzDecompressEnd(bzs);
+ PyBuffer_Release(&pdata);
Py_DECREF(ret);
return NULL;
}
@@ -2190,6 +2227,7 @@ bz2_decompress(PyObject *self, PyObject *args)
if (bzs->avail_out != 0)
_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
BZ2_bzDecompressEnd(bzs);
+ PyBuffer_Release(&pdata);
return ret;
}
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index f18e154..8104ccd 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6334,15 +6334,16 @@ Write a string to a file descriptor.");
static PyObject *
posix_write(PyObject *self, PyObject *args)
{
+ Py_buffer pbuf;
int fd;
Py_ssize_t size;
- char *buffer;
- if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
+ if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
return NULL;
Py_BEGIN_ALLOW_THREADS
- size = write(fd, buffer, (size_t)size);
+ size = write(fd, pbuf.buf, (size_t)pbuf.len);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (size < 0)
return posix_error();
return PyInt_FromSsize_t(size);
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index e4c8ac8..deff28a 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -2647,12 +2647,17 @@ sock_send(PySocketSockObject *s, PyObject *args)
{
char *buf;
int len, n = -1, flags = 0, timeout;
+ Py_buffer pbuf;
- if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
+ if (!PyArg_ParseTuple(args, "s*|i:send", &pbuf, &flags))
return NULL;
- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }
+ buf = pbuf.buf;
+ len = pbuf.len;
Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 1);
@@ -2664,6 +2669,8 @@ sock_send(PySocketSockObject *s, PyObject *args)
#endif
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
+
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;
@@ -2688,12 +2695,17 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
{
char *buf;
int len, n = -1, flags = 0, timeout;
+ Py_buffer pbuf;
- if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags))
+ if (!PyArg_ParseTuple(args, "s*|i:sendall", &pbuf, &flags))
return NULL;
+ buf = pbuf.buf;
+ len = pbuf.len;
- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }
Py_BEGIN_ALLOW_THREADS
do {
@@ -2712,6 +2724,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
len -= n;
} while (len > 0);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
@@ -2738,24 +2751,32 @@ to tell how much data has been sent.");
static PyObject *
sock_sendto(PySocketSockObject *s, PyObject *args)
{
+ Py_buffer pbuf;
PyObject *addro;
char *buf;
+ Py_ssize_t len;
sock_addr_t addrbuf;
- int addrlen, len, n = -1, flags, timeout;
+ int addrlen, n = -1, flags, timeout;
flags = 0;
- if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) {
+ if (!PyArg_ParseTuple(args, "s*O:sendto", &pbuf, &addro)) {
PyErr_Clear();
- if (!PyArg_ParseTuple(args, "s#iO:sendto",
- &buf, &len, &flags, &addro))
+ if (!PyArg_ParseTuple(args, "s*iO:sendto",
+ &pbuf, &flags, &addro))
return NULL;
}
+ buf = pbuf.buf;
+ len = pbuf.len;
- if (!IS_SELECTABLE(s))
+ if (!IS_SELECTABLE(s)) {
+ PyBuffer_Release(&pbuf);
return select_error();
+ }
- if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) {
+ PyBuffer_Release(&pbuf);
return NULL;
+ }
Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 1);
@@ -2763,6 +2784,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;