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*.
........
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index 96dfd56..5026c05 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -252,20 +252,20 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 *