]> Savannah Git Hosting - gnulib.git/commitdiff
dfa: fix dfa-heap-overrun failure
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 14 Sep 2020 01:20:01 +0000 (18:20 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 14 Sep 2020 01:41:32 +0000 (18:41 -0700)
* lib/dfa.c (reorder_tokens): When setting
map[d->follows[i].elems[j].index], instead of incorrectly assuming
that (i < d->follows[i].elems[j].index), use two loops, one to set
the map array and the other to use it.  The incorrect assumption
caused some elements to be missed, and this in turn caused grep's
dfa-heap-overrun test to fail on Solaris 10 sparc when compiled
with GCC.  I found this bug while investigating
https://buildfarm.opencsw.org/buildbot/builders/ggrep-solaris10-sparc/builds/183
and I think the bug also occurs on GNU/Linux but with more-subtle
symptoms.  The bug predates the recent dfa.c changes; perhaps the
recent changes make the bug more likely.

ChangeLog
lib/dfa.c

index a5c14c45e2f06e7b4a4457c68cea3b958188914a..1b5720761d7554121ae7dbf2aea1d96d1619ec1e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2020-09-13  Paul Eggert  <eggert@cs.ucla.edu>
+
+       dfa: fix dfa-heap-overrun failure
+       * lib/dfa.c (reorder_tokens): When setting
+       map[d->follows[i].elems[j].index], instead of incorrectly assuming
+       that (i < d->follows[i].elems[j].index), use two loops, one to set
+       the map array and the other to use it.  The incorrect assumption
+       caused some elements to be missed, and this in turn caused grep's
+       dfa-heap-overrun test to fail on Solaris 10 sparc when compiled
+       with GCC.  I found this bug while investigating
+       https://buildfarm.opencsw.org/buildbot/builders/ggrep-solaris10-sparc/builds/183
+       and I think the bug also occurs on GNU/Linux but with more-subtle
+       symptoms.  The bug predates the recent dfa.c changes; perhaps the
+       recent changes make the bug more likely.
+
 2020-09-13  Bruno Haible  <bruno@clisp.org>
 
        parse-datetime: Make the build rule work with parallel 'make'.
index 0f0764887bf20353f26ef3a4e41ab4ee3db6e2c1..4992bcaf21098ee012389be9f96d6c64b60de54e 100644 (file)
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -2519,6 +2519,11 @@ reorder_tokens (struct dfa *d)
   else
     multibyte_prop = NULL;
 
+  for (idx_t i = 0; i < d->tindex; i++)
+    for (idx_t j = 0; j < d->follows[i].nelem; j++)
+      if (map[d->follows[i].elems[j].index] == -1)
+        map[d->follows[i].elems[j].index] = nleaves++;
+
   for (idx_t i = 0; i < d->tindex; i++)
     {
       if (map[i] == -1)
@@ -2537,12 +2542,7 @@ reorder_tokens (struct dfa *d)
         multibyte_prop[map[i]] = d->multibyte_prop[i];
 
       for (idx_t j = 0; j < d->follows[i].nelem; j++)
-        {
-          if (map[d->follows[i].elems[j].index] == -1)
-            map[d->follows[i].elems[j].index] = nleaves++;
-
-          d->follows[i].elems[j].index = map[d->follows[i].elems[j].index];
-        }
+        d->follows[i].elems[j].index = map[d->follows[i].elems[j].index];
 
       qsort (d->follows[i].elems, d->follows[i].nelem,
              sizeof *d->follows[i].elems, compare);