[Numpy-svn] r3315 - in trunk/numpy/core: . src

numpy-svn at scipy.org numpy-svn at scipy.org
Thu Oct 12 01:18:12 CDT 2006


Author: oliphant
Date: 2006-10-12 01:18:04 -0500 (Thu, 12 Oct 2006)
New Revision: 3315

Modified:
   trunk/numpy/core/numeric.py
   trunk/numpy/core/src/multiarraymodule.c
Log:
Fix
asbuffer -> int_asbuffer so that it checks for read (and write) ability to the memory to be used as a buffer by catching SIG_SEGV

Modified: trunk/numpy/core/numeric.py
===================================================================
--- trunk/numpy/core/numeric.py	2006-10-11 23:52:53 UTC (rev 3314)
+++ trunk/numpy/core/numeric.py	2006-10-12 06:18:04 UTC (rev 3315)
@@ -1,7 +1,7 @@
 __all__ = ['newaxis', 'ndarray', 'flatiter', 'ufunc',
            'arange', 'array', 'zeros', 'empty', 'broadcast', 'dtype',
            'fromstring', 'fromfile', 'frombuffer','newbuffer',
-           'getbuffer', 'where', 'argwhere',
+           'getbuffer', 'int_asbuffer', 'where', 'argwhere',
            'concatenate', 'fastCopyAndTranspose', 'lexsort',
            'set_numeric_ops', 'can_cast',
            'asarray', 'asanyarray', 'ascontiguousarray', 'asfortranarray',
@@ -113,6 +113,7 @@
 frombuffer = multiarray.frombuffer
 newbuffer = multiarray.newbuffer
 getbuffer = multiarray.getbuffer
+int_asbuffer = multiarray.int_asbuffer
 where = multiarray.where
 concatenate = multiarray.concatenate
 fastCopyAndTranspose = multiarray._fastCopyAndTranspose

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2006-10-11 23:52:53 UTC (rev 3314)
+++ trunk/numpy/core/src/multiarraymodule.c	2006-10-12 06:18:04 UTC (rev 3315)
@@ -17,9 +17,6 @@
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 #include "structmember.h"
-/*#include <string.h>
-#include <math.h>
-*/
 
 #define _MULTIARRAYMODULE
 #define NPY_NO_PREFIX
@@ -6538,26 +6535,86 @@
 		return PyBuffer_FromReadWriteObject(obj, offset, size);
 }
 
+#ifndef _MSC_VER
+#include <setjmp.h>
+jmp_buf _NPY_SIGSEGV_BUF;
+static void
+_SigSegv_Handler(int signum)
+{
+        longjmp(_NPY_SIGSEGV_BUF, signum);
+}
+#endif
+
+#define _test_code() {                                   \
+                test = *((char*)memptr);                 \
+                if (!ro) {                               \
+                        *((char *)memptr) = '\0';        \
+                        *((char *)memptr) = test;        \
+                }                                        \
+                test = *((char*)memptr+size-1);          \
+                if (!ro) {                               \
+                        *((char *)memptr+size-1) = '\0'; \
+                        *((char *)memptr+size-1) = test; \
+                }                                        \
+        }
+
 static PyObject *
 as_buffer(PyObject *dummy, PyObject *args, PyObject *kwds)
 {
         PyObject *mem;
         Py_ssize_t size;
-        Bool ro=FALSE;
+        Bool ro=FALSE, check=TRUE;
         void *memptr;
-        static char *kwlist[] = {"mem", "size", "readonly", NULL};
+        static char *kwlist[] = {"mem", "size", "readonly", "check", NULL};
         if (!PyArg_ParseTupleAndKeywords(args, kwds, "O" \
-                                         NPY_SSIZE_T_PYFMT "|O&", kwlist,
+                                         NPY_SSIZE_T_PYFMT "|O&O&", kwlist,
                                          &mem, &size, PyArray_BoolConverter,
-                                         &ro)) return NULL;
+                                         &ro, PyArray_BoolConverter,
+                                         &check)) return NULL;
         memptr = PyLong_AsVoidPtr(mem);
         if (memptr == NULL) return NULL;
+
+        if (check) {
+                /* Try to dereference the start and end of the memory region */
+                /* Catch segfault and report error if it occurs */
+                char test;
+                int err=0;
+#ifdef _MSC_VER
+                __try {
+                        _test_code();
+                }
+                __except(1) {
+                        err = 1;
+                }
+#else 
+                PyOS_sighandler_t _npy_sig_save;
+                _npy_sig_save = PyOS_setsig(SIGSEGV, _SigSegv_Handler);
+                
+                if (setjmp(_NPY_SIGSEGV_BUF) == 0) {
+                        _test_code();
+                }
+                else {
+                        err = 1;
+                }
+                PyOS_setsig(SIGSEGV, _npy_sig_save);
+#endif
+                if (err) {
+                        PyErr_SetString(PyExc_ValueError, 
+                                        "cannot use memory location as " \
+                                        "a buffer.");
+                        return NULL;                        
+                }
+        }
+
+
         if (ro) {
                 return PyBuffer_FromMemory(memptr, size);
         }
         return PyBuffer_FromReadWriteMemory(memptr, size);
 }
 
+#undef _test_code
+
 static PyObject *
 format_longfloat(PyObject *dummy, PyObject *args, PyObject *kwds)
 {
@@ -6767,7 +6824,7 @@
 	 METH_VARARGS, NULL},
 	{"getbuffer", (PyCFunction)buffer_buffer,
 	 METH_VARARGS | METH_KEYWORDS, NULL},
-        {"asbuffer", (PyCFunction)as_buffer,
+        {"int_asbuffer", (PyCFunction)as_buffer,
          METH_VARARGS | METH_KEYWORDS, NULL},
         {"format_longfloat", (PyCFunction)format_longfloat,
          METH_VARARGS | METH_KEYWORDS, NULL},



More information about the Numpy-svn mailing list