diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-10-12 06:18:04 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-10-12 06:18:04 +0000 |
commit | e5bb060c98b5ad52c98c24e45fe81ce3737ba5f4 (patch) | |
tree | c3f6ebcd1d5a7607642c9f0f5b2006c140a577c0 /numpy | |
parent | cf3eb93b05da716e16b87c30d7b5e08c22115330 (diff) | |
download | numpy-e5bb060c98b5ad52c98c24e45fe81ce3737ba5f4.tar.gz |
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
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/numeric.py | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 73 |
2 files changed, 67 insertions, 9 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 8a5797e8b..0a211ff61 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -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 @@ fromfile = multiarray.fromfile frombuffer = multiarray.frombuffer newbuffer = multiarray.newbuffer getbuffer = multiarray.getbuffer +int_asbuffer = multiarray.int_asbuffer where = multiarray.where concatenate = multiarray.concatenate fastCopyAndTranspose = multiarray._fastCopyAndTranspose diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index 3daf764c4..707f3aace 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -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 @@ buffer_buffer(PyObject *dummy, PyObject *args, PyObject *kwds) 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 @@ static struct PyMethodDef array_module_methods[] = { 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}, |