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/Objects/memoryobject.c b/Objects/memoryobject.c
index 79d7db1..b36c3a7 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -6,19 +6,21 @@
 static int
 memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
 {
-        if (view != NULL)
+        if (view != NULL) {
+		if (self->view.obj)
+			Py_INCREF(self->view.obj);
 		*view = self->view;
-	if (self->base == NULL)
+	}
+	if (self->view.obj == NULL)
 		return 0;
-        return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
+        return self->view.obj->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
                                                                PyBUF_FULL);
 }
 
 static void
 memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
 {
-	if (self->base != NULL)
-		PyObject_ReleaseBuffer(self->base, NULL);
+	PyBuffer_Release(&self->view);
 }
 
 PyDoc_STRVAR(memory_doc,
@@ -36,6 +38,8 @@
 	if (mview == NULL) return NULL;
 	mview->base = NULL;
 	mview->view = *info;
+	if (info->obj)
+		Py_INCREF(mview->view.obj);
 	return (PyObject *)mview;
 }
 
@@ -256,7 +260,7 @@
         }
         bytes = PyByteArray_FromStringAndSize(NULL, view->len);
         if (bytes == NULL) {
-                PyObject_ReleaseBuffer(obj, view);
+                PyBuffer_Release(view);
                 return NULL;
         }
         dest = PyByteArray_AS_STRING(bytes);
@@ -271,7 +275,7 @@
         else {
                 if (_indirect_copy_nd(dest, view, fort) < 0) {
                         Py_DECREF(bytes);
-                        PyObject_ReleaseBuffer(obj, view);
+                        PyBuffer_Release(view);
                         return NULL;
                 }
         }
@@ -281,12 +285,12 @@
                 mem->base = PyTuple_Pack(2, obj, bytes);
                 Py_DECREF(bytes);
 		if (mem->base == NULL) {
-			PyObject_ReleaseBuffer(obj, view);
+			PyBuffer_Release(view);
 			return NULL;
 		}
         }
         else {
-                PyObject_ReleaseBuffer(obj, view);
+                PyBuffer_Release(view);
                 /* steal the reference */
                 mem->base = bytes;
         }
@@ -407,7 +411,7 @@
 static void
 memory_dealloc(PyMemoryViewObject *self)
 {
-        if (self->base != NULL) {
+        if (self->view.obj != NULL) {
             if (PyTuple_Check(self->base)) {
                 /* Special case when first element is generic object
                    with buffer interface and the second element is a
@@ -424,11 +428,10 @@
                    be "locked" and was locked and will be unlocked
                    again after this call.
                 */
-                PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0),
-                                       &(self->view));
+                PyBuffer_Release(&(self->view));
             }
             else {
-                PyObject_ReleaseBuffer(self->base, &(self->view));
+                PyBuffer_Release(&(self->view));
             }
             Py_CLEAR(self->base);
         }
@@ -453,7 +456,7 @@
 
 	res = PyByteArray_FromStringAndSize(NULL, view.len);
         PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C');
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyBuffer_Release(&view);
         return res;
 }
 
@@ -466,7 +469,7 @@
 
         if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
                 return -1;
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyBuffer_Release(&view);
 	return view.len;
 }