summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2008-07-16 21:01:31 +0000
committerPauli Virtanen <pav@iki.fi>2008-07-16 21:01:31 +0000
commitb788f2518a9b7ed30f8886a31d6a759ba9bba303 (patch)
treefbf45f88a2943bbaca268486315ef748e086b7ef /numpy
parentf48abc5a5b88e22dbbad44b1cb130543231ffa13 (diff)
downloadnumpy-b788f2518a9b7ed30f8886a31d6a759ba9bba303.tar.gz
Fix ticket #837. Avoid infinite loop in fromfile/fromstring by ensuring that *_skip_separator always consumes at least one character or fails.
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarraymodule.c33
-rw-r--r--numpy/core/tests/test_multiarray.py11
2 files changed, 37 insertions, 7 deletions
diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c
index 74f0c77ac..7a5a76123 100644
--- a/numpy/core/src/multiarraymodule.c
+++ b/numpy/core/src/multiarraymodule.c
@@ -6051,7 +6051,8 @@ swab_separator(char *sep)
/* Assuming that the separator is the next bit in the string (file), skip it.
Single spaces in the separator are matched to arbitrary-long sequences
- of whitespace in the input.
+ of whitespace in the input. If the separator consists only of spaces,
+ it matches one or more whitespace characters.
If we can't match the separator, return -2.
If we hit the end of the string (file), return -1.
@@ -6069,10 +6070,17 @@ fromstr_skip_separator(char **s, const char *sep, const char *end)
result = -1;
break;
} else if (*sep == '\0') {
- /* matched separator */
- result = 0;
- break;
+ if (string != *s) {
+ /* matched separator */
+ result = 0;
+ break;
+ } else {
+ /* separator was whitespace wildcard that didn't match */
+ result = -2;
+ break;
+ }
} else if (*sep == ' ') {
+ /* whitespace wildcard */
if (!isspace(c)) {
sep++;
continue;
@@ -6093,20 +6101,31 @@ static int
fromfile_skip_separator(FILE **fp, const char *sep, void *stream_data)
{
int result = 0;
+ const char *sep_start = sep;
while (1) {
int c = fgetc(*fp);
if (c == EOF) {
result = -1;
break;
} else if (*sep == '\0') {
- /* matched separator */
ungetc(c, *fp);
- result = 0;
- break;
+ if (sep != sep_start) {
+ /* matched separator */
+ result = 0;
+ break;
+ } else {
+ /* separator was whitespace wildcard that didn't match */
+ result = -2;
+ break;
+ }
} else if (*sep == ' ') {
+ /* whitespace wildcard */
if (!isspace(c)) {
sep++;
+ sep_start++;
ungetc(c, *fp);
+ } else if (sep == sep_start) {
+ sep_start--;
}
} else if (*sep != c) {
ungetc(c, *fp);
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 663dff294..6c91e1ecb 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -143,6 +143,10 @@ class TestFromstring(TestCase):
assert_array_equal(a, [1.,2.,3.,4.])
assert_array_equal(a,b)
+ def test_malformed(self):
+ a = fromstring('1.234 1,234', sep=' ')
+ assert_array_equal(a, [1.234, 1.])
+
class TestZeroRank(TestCase):
def setUp(self):
@@ -814,6 +818,13 @@ class TestFromToFile(TestCase):
y = np.fromfile(filename,dtype=self.dtype)
assert_array_equal(y,self.x.flat)
+ def test_malformed(self):
+ filename = tempfile.mktemp()
+ f = open(filename,'w')
+ f.write("1.234 1,234")
+ f.close()
+ y = np.fromfile(filename, sep=' ')
+ assert_array_equal(y, [1.234, 1.])
class TestFromBuffer(TestCase):
def tst_basic(self,buffer,expected,kwargs):