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/bz2module.c | |
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/bz2module.c')
-rw-r--r-- | Modules/bz2module.c | 58 |
1 files changed, 48 insertions, 10 deletions
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; } |