Merged revisions 65654 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r65654 | martin.v.loewis | 2008-08-12 16:49:50 +0200 (Tue, 12 Aug 2008) | 6 lines

  Issue #3139: Make buffer-interface thread-safe wrt. PyArg_ParseTuple,
  by denying s# to parse objects that have a releasebuffer procedure,
  and introducing s*.

  More module might need to get converted to use s*.
........
This commit is contained in:
Martin v. Löwis 2008-08-13 15:53:07 +00:00
parent 688356f59f
commit 423be95dcf
32 changed files with 721 additions and 390 deletions

View file

@ -252,20 +252,20 @@ static PyObject *
utf_7_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
if (!PyArg_ParseTuple(args, "t#|zi:utf_7_decode",
&data, &size, &errors, &final))
return NULL;
consumed = size;
if (!PyArg_ParseTuple(args, "s*|zi:utf_7_decode",
&pbuf, &errors, &final))
return NULL;
consumed = pbuf.len;
decoded = PyUnicode_DecodeUTF7Stateful(data, size, errors,
final ? NULL : &consumed);
decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors,
final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -275,24 +275,20 @@ static PyObject *
utf_8_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_8_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size;
decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
consumed = pbuf.len;
decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors,
final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -302,24 +298,20 @@ static PyObject *
utf_16_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -329,53 +321,45 @@ static PyObject *
utf_16_le_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_le_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
}
static PyObject *
utf_16_be_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_16_be_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -393,24 +377,20 @@ static PyObject *
utf_16_ex_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;
if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
&data, &size, &errors, &byteorder, &final))
if (!PyArg_ParseTuple(args, "s*|zii:utf_16_ex_decode",
&pbuf, &errors, &byteorder, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@ -422,24 +402,20 @@ static PyObject *
utf_32_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded;
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -449,53 +425,43 @@ static PyObject *
utf_32_le_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = -1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
PyObject *decoded;
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_le_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_le_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
&byteorder, final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
}
static PyObject *
utf_32_be_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 1;
int final = 0;
Py_ssize_t consumed;
PyObject *decoded = NULL;
PyObject *decoded;
if (!PyArg_ParseTuple(args, "t#|zi:utf_32_be_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:utf_32_be_decode",
&pbuf, &errors, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
&byteorder, final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, consumed);
@ -513,24 +479,20 @@ static PyObject *
utf_32_ex_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
int byteorder = 0;
PyObject *unicode, *tuple;
int final = 0;
Py_ssize_t consumed;
if (!PyArg_ParseTuple(args, "t#|zii:utf_32_ex_decode",
&data, &size, &errors, &byteorder, &final))
if (!PyArg_ParseTuple(args, "s*|zii:utf_32_ex_decode",
&pbuf, &errors, &byteorder, &final))
return NULL;
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
consumed = size; /* This is overwritten unless final is true. */
unicode = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
consumed = pbuf.len; /* This is overwritten unless final is true. */
unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors,
&byteorder, final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (unicode == NULL)
return NULL;
tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
@ -542,83 +504,88 @@ static PyObject *
unicode_escape_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
PyObject *unicode;
if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
&data, &size, &errors))
if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode",
&pbuf, &errors))
return NULL;
return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
size);
unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors);
PyBuffer_Release(&pbuf);
return codec_tuple(unicode, pbuf.len);
}
static PyObject *
raw_unicode_escape_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
const char *errors = NULL;
PyObject *unicode;
if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
&data, &size, &errors))
if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode",
&pbuf, &errors))
return NULL;
return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
size);
unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors);
PyBuffer_Release(&pbuf);
return codec_tuple(unicode, pbuf.len);
}
static PyObject *
latin_1_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
PyObject *unicode;
const char *errors = NULL;
if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
&data, &size, &errors))
if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode",
&pbuf, &errors))
return NULL;
return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
size);
unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors);
PyBuffer_Release(&pbuf);
return codec_tuple(unicode, pbuf.len);
}
static PyObject *
ascii_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
PyObject *unicode;
const char *errors = NULL;
if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
&data, &size, &errors))
if (!PyArg_ParseTuple(args, "s*|z:ascii_decode",
&pbuf, &errors))
return NULL;
return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
size);
unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors);
PyBuffer_Release(&pbuf);
return codec_tuple(unicode, pbuf.len);
}
static PyObject *
charmap_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size;
Py_buffer pbuf;
PyObject *unicode;
const char *errors = NULL;
PyObject *mapping = NULL;
if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
&data, &size, &errors, &mapping))
if (!PyArg_ParseTuple(args, "s*|zO:charmap_decode",
&pbuf, &errors, &mapping))
return NULL;
if (mapping == Py_None)
mapping = NULL;
return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
size);
unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors);
PyBuffer_Release(&pbuf);
return codec_tuple(unicode, pbuf.len);
}
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
@ -627,21 +594,23 @@ static PyObject *
mbcs_decode(PyObject *self,
PyObject *args)
{
const char *data;
Py_ssize_t size, consumed;
Py_buffer pbuf;
const char *errors = NULL;
int final = 0;
PyObject *decoded;
Py_ssize_t consumed;
PyObject *decoded = NULL;
if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
&data, &size, &errors, &final))
if (!PyArg_ParseTuple(args, "s*|zi:mbcs_decode",
&pbuf, &errors, &final))
return NULL;
consumed = pbuf.len;
decoded = PyUnicode_DecodeMBCSStateful(
data, size, errors, final ? NULL : &consumed);
if (!decoded)
decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors,
final ? NULL : &consumed);
PyBuffer_Release(&pbuf);
if (decoded == NULL)
return NULL;
return codec_tuple(decoded, final ? size : consumed);
return codec_tuple(decoded, consumed);
}
#endif /* MS_WINDOWS */
@ -652,15 +621,21 @@ static PyObject *
readbuffer_encode(PyObject *self,
PyObject *args)
{
Py_buffer pdata;
const char *data;
Py_ssize_t size;
const char *errors = NULL;
PyObject *result;
if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
&data, &size, &errors))
if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode",
&pdata, &errors))
return NULL;
data = pdata.buf;
size = pdata.len;
return codec_tuple(PyBytes_FromStringAndSize(data, size), size);
result = PyBytes_FromStringAndSize(data, size);
PyBuffer_Release(&pdata);
return codec_tuple(result, size);
}
static PyObject *