diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-08-12 14:49:50 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-08-12 14:49:50 (GMT) |
commit | f91d46a17d85da323895950852093117bc21f860 (patch) | |
tree | c6a3e68cf22a6a102f9c1dc780438f0307b6588f /Modules | |
parent | aa8efbf08469c3667ed22362c0e10b83ae124c0b (diff) | |
download | cpython-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.c | 267 | ||||
-rw-r--r-- | Modules/_fileio.c | 15 | ||||
-rw-r--r-- | Modules/_multiprocessing/connection.h | 22 | ||||
-rw-r--r-- | Modules/bz2module.c | 58 | ||||
-rw-r--r-- | Modules/posixmodule.c | 7 | ||||
-rw-r--r-- | Modules/socketmodule.c | 42 |
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; |