[Numpy-svn] r5438 - in trunk/numpy/core: src tests

numpy-svn@scip... numpy-svn@scip...
Wed Jul 16 16:01:44 CDT 2008


Author: ptvirtan
Date: 2008-07-16 16:01:31 -0500 (Wed, 16 Jul 2008)
New Revision: 5438

Modified:
   trunk/numpy/core/src/multiarraymodule.c
   trunk/numpy/core/tests/test_multiarray.py
Log:
Fix ticket #837. Avoid infinite loop in fromfile/fromstring by ensuring that *_skip_separator always consumes at least one character or fails.

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2008-07-16 20:24:32 UTC (rev 5437)
+++ trunk/numpy/core/src/multiarraymodule.c	2008-07-16 21:01:31 UTC (rev 5438)
@@ -6051,7 +6051,8 @@
 /* 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 @@
             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 @@
 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);

Modified: trunk/numpy/core/tests/test_multiarray.py
===================================================================
--- trunk/numpy/core/tests/test_multiarray.py	2008-07-16 20:24:32 UTC (rev 5437)
+++ trunk/numpy/core/tests/test_multiarray.py	2008-07-16 21:01:31 UTC (rev 5438)
@@ -143,7 +143,11 @@
         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):
         self.d = array(0), array('x', object)
@@ -814,6 +818,13 @@
         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):



More information about the Numpy-svn mailing list