[Python-3000-checkins] r57193 - in python/branches/py3k: Include/bytesobject.h Include/object.h Lib/test/exception_hierarchy.txt Modules/arraymodule.c Objects/abstract.c Objects/bufferobject.c Objects/bytesobject.c Objects/exceptions.c Objects/memoryobject.c

neal.norwitz python-3000-checkins at python.org
Sun Aug 19 06:23:54 CEST 2007


Author: neal.norwitz
Date: Sun Aug 19 06:23:20 2007
New Revision: 57193

Modified:
   python/branches/py3k/Include/bytesobject.h
   python/branches/py3k/Include/object.h
   python/branches/py3k/Lib/test/exception_hierarchy.txt
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Objects/abstract.c
   python/branches/py3k/Objects/bufferobject.c
   python/branches/py3k/Objects/bytesobject.c
   python/branches/py3k/Objects/exceptions.c
   python/branches/py3k/Objects/memoryobject.c
Log:
Code review of the new buffer protocol.  Mostly add questions that should
be answered with the comments removed.

There are many places that require checks when doing arithmetic for memory
sizes when allocating memory.  Otherwise, overflow is possible with
a subsequent crash.

Fix SF #1777057 which was a result of not initializing the new BufferError
properly.  Had to update the test for exceptions for BufferError too.



Modified: python/branches/py3k/Include/bytesobject.h
==============================================================================
--- python/branches/py3k/Include/bytesobject.h	(original)
+++ python/branches/py3k/Include/bytesobject.h	Sun Aug 19 06:23:20 2007
@@ -21,6 +21,7 @@
 /* Object layout */
 typedef struct {
     PyObject_VAR_HEAD
+    /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
     int ob_exports; /* how many buffer exports */
     Py_ssize_t ob_alloc; /* How many bytes allocated */
     char *ob_bytes;

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h	(original)
+++ python/branches/py3k/Include/object.h	Sun Aug 19 06:23:20 2007
@@ -147,7 +147,7 @@
         Py_ssize_t len;
         Py_ssize_t itemsize;  
         int readonly;
-        int ndim; 
+        int ndim; /* XXX(nnorwitz): should be Py_ssize_t??? */
         char *format;
         Py_ssize_t *shape;
         Py_ssize_t *strides;

Modified: python/branches/py3k/Lib/test/exception_hierarchy.txt
==============================================================================
--- python/branches/py3k/Lib/test/exception_hierarchy.txt	(original)
+++ python/branches/py3k/Lib/test/exception_hierarchy.txt	Sun Aug 19 06:23:20 2007
@@ -10,6 +10,7 @@
       |    +-- ZeroDivisionError
       +-- AssertionError
       +-- AttributeError
+      +-- BufferError
       +-- EnvironmentError
       |    +-- IOError
       |    +-- OSError

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Sun Aug 19 06:23:20 2007
@@ -42,10 +42,8 @@
 
 #ifdef Py_UNICODE_WIDE
 #define PyArr_UNI 'w'
-/*static const char *PyArr_UNISTR = "w"; */
 #else
 #define PyArr_UNI 'u'
-/*static const char *PyArr_UNISTR = "u"; */
 #endif
 
 #define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
@@ -1773,6 +1771,8 @@
         view->internal = NULL;
         if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
                 view->internal = malloc(3);
+		/* XXX(nnorwitz): need to check for malloc failure.
+			Should probably use PyObject_Malloc. */
                 view->format = view->internal;
                 view->format[0] = (char)(self->ob_descr->typecode);
                 view->format[1] = '\0';

Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c	(original)
+++ python/branches/py3k/Objects/abstract.c	Sun Aug 19 06:23:20 2007
@@ -471,6 +471,7 @@
 
         /* Otherwise a more elaborate scheme is needed */
         
+	/* XXX(nnorwitz): need to check for overflow! */
         indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
         if (indices == NULL) {
                 PyErr_NoMemory();
@@ -521,6 +522,7 @@
 
         /* Otherwise a more elaborate scheme is needed */
         
+	/* XXX(nnorwitz): need to check for overflow! */
         indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
         if (indices == NULL) {
                 PyErr_NoMemory();
@@ -594,6 +596,7 @@
 
         /* Otherwise a more elaborate copy scheme is needed */
         
+	/* XXX(nnorwitz): need to check for overflow! */
         indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
         if (indices == NULL) {
                 PyErr_NoMemory();
@@ -606,6 +609,7 @@
         }        
         elements = 1;
         for (k=0; k<view_src.ndim; k++) {
+		/* XXX(nnorwitz): can this overflow? */
                 elements *= view_src.shape[k];
         }
         while (elements--) {

Modified: python/branches/py3k/Objects/bufferobject.c
==============================================================================
--- python/branches/py3k/Objects/bufferobject.c	(original)
+++ python/branches/py3k/Objects/bufferobject.c	Sun Aug 19 06:23:20 2007
@@ -64,7 +64,7 @@
                         (*bp->bf_releasebuffer)(self->b_base, view);
                 }
         }
-        return;
+	/* XXX(nnorwitz): do we need to release view here?  it leaks. */
 }
 
 static PyObject *
@@ -401,6 +401,7 @@
                 return NULL;
         }
 
+	/* XXX(nnorwitz): need to check for overflow! */
  	ob = PyBytes_FromStringAndSize(NULL, view.len+view2.len);
 	if ( ob == NULL ) {
                 PyObject_ReleaseBuffer((PyObject *)self, &view);
@@ -427,6 +428,7 @@
 		count = 0;
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
 		return NULL;
+	/* XXX(nnorwitz): need to check for overflow! */
 	ob = PyBytes_FromStringAndSize(NULL, view.len * count);
 	if ( ob == NULL )
 		return NULL;
@@ -474,6 +476,7 @@
 		right = view.len;
 	if ( right < left )
 		right = left;
+	/* XXX(nnorwitz): is it possible to access unitialized memory? */
 	ob = PyBytes_FromStringAndSize((char *)view.buf + left,
                                        right - left);
         PyObject_ReleaseBuffer((PyObject *)self, &view);

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Sun Aug 19 06:23:20 2007
@@ -507,6 +507,7 @@
             memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
                     Py_Size(self) - hi);
         }
+	/* XXX(nnorwitz): need to verify this can't overflow! */
         if (PyBytes_Resize((PyObject *)self,
                            Py_Size(self) + needed - avail) < 0) {
                 res = -1;

Modified: python/branches/py3k/Objects/exceptions.c
==============================================================================
--- python/branches/py3k/Objects/exceptions.c	(original)
+++ python/branches/py3k/Objects/exceptions.c	Sun Aug 19 06:23:20 2007
@@ -1694,6 +1694,7 @@
     PRE_INIT(ZeroDivisionError)
     PRE_INIT(SystemError)
     PRE_INIT(ReferenceError)
+    PRE_INIT(BufferError)
     PRE_INIT(MemoryError)
     PRE_INIT(Warning)
     PRE_INIT(UserWarning)
@@ -1753,6 +1754,7 @@
     POST_INIT(ZeroDivisionError)
     POST_INIT(SystemError)
     POST_INIT(ReferenceError)
+    POST_INIT(BufferError)
     POST_INIT(MemoryError)
     POST_INIT(Warning)
     POST_INIT(UserWarning)

Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c	(original)
+++ python/branches/py3k/Objects/memoryobject.c	Sun Aug 19 06:23:20 2007
@@ -26,6 +26,7 @@
 PyObject *
 PyMemoryView_FromMemory(PyBuffer *info)
 {
+	/* XXX(nnorwitz): need to implement something here? */
         return NULL;
 }
 
@@ -59,7 +60,7 @@
 memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
 {
         PyObject *obj;
-        if (!PyArg_ParseTuple(args, "O", &obj)) return NULL;
+        if (!PyArg_UnpackTuple(args, "memoryview", 1, 1, &obj)) return NULL;
 
         return PyMemoryView_FromObject(obj);        
 }
@@ -136,6 +137,7 @@
         void (*func)(int, Py_ssize_t *, Py_ssize_t *);
         
         
+        /* XXX(nnorwitz): need to check for overflow! */
         indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
         if (indices == NULL) {
                 PyErr_NoMemory();
@@ -260,6 +262,7 @@
                 /* return a shadowed memory-view object */
                 view->buf = dest;
                 mem->base = PyTuple_Pack(2, obj, bytes);
+		/* XXX(nnorwitz): need to verify alloc was successful. */
                 Py_DECREF(bytes);
         }
         else {
@@ -373,17 +376,15 @@
 
 
 static PyObject *
-memory_tobytes(PyMemoryViewObject *mem, PyObject *args)
+memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
 {
-        if (!PyArg_ParseTuple(args, "")) return NULL;
         /* Create new Bytes object for data */
         return PyBytes_FromObject((PyObject *)mem);
 }
 
 static PyObject *
-memory_tolist(PyMemoryViewObject *mem, PyObject *args)
+memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
 {
-        if (!PyArg_ParseTuple(args, "")) return NULL;        
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
 }
@@ -391,8 +392,8 @@
 
 
 static PyMethodDef memory_methods[] = {
-        {"tobytes", (PyCFunction)memory_tobytes, 1, NULL},
-        {"tolist", (PyCFunction)memory_tolist, 1, NULL},
+        {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+        {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
         {NULL,          NULL}           /* sentinel */
 };
 
@@ -400,7 +401,6 @@
 static void
 memory_dealloc(PyMemoryViewObject *self)
 {
-
         if (PyTuple_Check(self->base)) {
                 /* Special case when first element is generic object
                    with buffer interface and the second element is a
@@ -423,21 +423,18 @@
         else {
                 PyObject_ReleaseBuffer(self->base, &(self->view));
         }
-        Py_DECREF(self->base);
+        Py_CLEAR(self->base);
         PyObject_DEL(self);
 }
 
 static PyObject *
 memory_repr(PyMemoryViewObject *self)
 {
-
-	if ( self->base == NULL )
-		return PyUnicode_FromFormat("<memory at %p>",
-					   self);
+	/* XXX(nnorwitz): the code should be different or remove condition. */
+	if (self->base == NULL)
+		return PyUnicode_FromFormat("<memory at %p>", self);
 	else
-		return PyUnicode_FromFormat(
-			"<memory at %p>",
-			self);
+		return PyUnicode_FromFormat("<memory at %p>", self);
 }
 
 


More information about the Python-3000-checkins mailing list