summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-10-12 06:18:04 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-10-12 06:18:04 +0000
commite5bb060c98b5ad52c98c24e45fe81ce3737ba5f4 (patch)
treec3f6ebcd1d5a7607642c9f0f5b2006c140a577c0 /numpy
parentcf3eb93b05da716e16b87c30d7b5e08c22115330 (diff)
downloadnumpy-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.py3
-rw-r--r--numpy/core/src/multiarraymodule.c73
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},