summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2010-05-08 16:34:28 +0000
committerPauli Virtanen <pav@iki.fi>2010-05-08 16:34:28 +0000
commit8a6767f5ad921d49f6d69e0ee2da39ba9209020c (patch)
tree3cbbbe738db9b90e1a9347d04aec7dd1121996f2
parent217a7b2459186dff21b73a239c0daaec1ee35b44 (diff)
downloadnumpy-8a6767f5ad921d49f6d69e0ee2da39ba9209020c.tar.gz
BUG: core: ensure we have GIL before calling PyOS_string_to_double (fixes #1345)
In Python >= 2.7, the PyOS_ascii_strtod has been deprecated and replaced with PyOS_string_to_double. However, the latter may raise Python exceptions, which requires that GIL is held when calling it.
-rw-r--r--numpy/core/src/multiarray/numpyos.c38
-rw-r--r--numpy/core/tests/test_regression.py4
2 files changed, 32 insertions, 10 deletions
diff --git a/numpy/core/src/multiarray/numpyos.c b/numpy/core/src/multiarray/numpyos.c
index f30b15b66..2384b5161 100644
--- a/numpy/core/src/multiarray/numpyos.c
+++ b/numpy/core/src/multiarray/numpyos.c
@@ -420,6 +420,32 @@ NumPyOS_ascii_strncasecmp(const char* s1, const char* s2, size_t len)
return 0;
}
+/*
+ * _NumPyOS_ascii_strtod_plain:
+ *
+ * PyOS_ascii_strtod work-alike, with no enhanced features,
+ * for forward compatibility with Python >= 2.7
+ */
+static double
+NumPyOS_ascii_strtod_plain(const char *s, char** endptr)
+{
+ double result;
+#if PY_VERSION_HEX >= 0x02070000
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API
+ result = PyOS_string_to_double(s, endptr, NULL);
+ if (PyErr_Occurred()) {
+ if (endptr) {
+ *endptr = (char*)s;
+ }
+ PyErr_Clear();
+ }
+ NPY_DISABLE_C_API
+#else
+ result = PyOS_ascii_strtod(s, endptr);
+#endif
+ return result;
+}
/*
* NumPyOS_ascii_strtod:
@@ -508,11 +534,7 @@ NumPyOS_ascii_strtod(const char *s, char** endptr)
}
memcpy(buffer, s, n);
buffer[n] = '\0';
-#if PY_VERSION_HEX >= 0x02070000
- result = PyOS_string_to_double(buffer, &q, NULL);
-#else
- result = PyOS_ascii_strtod(buffer, &q);
-#endif
+ result = NumPyOS_ascii_strtod_plain(buffer, &q);
if (endptr != NULL) {
*endptr = (char*)(s + (q - buffer));
}
@@ -521,11 +543,7 @@ NumPyOS_ascii_strtod(const char *s, char** endptr)
}
/* End of ##2 */
-#if PY_VERSION_HEX >= 0x02070000
- return PyOS_string_to_double(s, endptr, NULL);
-#else
- return PyOS_ascii_strtod(s, endptr);
-#endif
+ return NumPyOS_ascii_strtod_plain(s, endptr);
}
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index cf54d9629..9efebbac9 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1298,5 +1298,9 @@ class TestRegression(TestCase):
assert np.alltrue(a == np.array([0,1,2,3,4,5,6,7,8,9]))
assert np.alltrue(b == np.array([0,1,2,3,4,5,6,7,8,9]))
+ def test_fromstring_crash(self):
+ # Ticket #1345: the following should not cause a crash
+ np.fromstring(asbytes('aa, aa, 1.0'), sep=',')
+
if __name__ == "__main__":
run_module_suite()