Subject: bug#17328: dfa.c will fail if used on more than one DFA

From: Norihiro Tanaka <[email-masked]>
Date: Thu, 24 Apr 2014 09:16:19 +0900

I confirmed memory leak by below after omit-static-variables.

$ yes abcdabc | head -50000000 >k
$ env LC_ALL=ja_JP.eucJP src/grep -v abcd.bc k

I send the patch to fix it.
From 45467bea1f26a916608387225a339d8dd0216ece Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email-masked]>
Date: Thu, 24 Apr 2014 08:24:34 +0900
Subject: [PATCH] dfa: fix memory leak after omit-static-variables

src/dfa.c (dfaexec): Fix memory leak after omit-static-variables.
---
 src/dfa.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/dfa.c b/src/dfa.c
index 42a9736..539c276 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -427,6 +427,8 @@ struct dfa
                                    on demand.  */
   int *mb_match_lens;           /* Array of length reduced by ANYCHAR and/or
                                    MBCSET.  */
+  bool mb_alloc;                /* True if mb_match_lens and elements of
+                                   mb_follows is allocated.  */
 };
 
 /* Some macros for user access to dfa internals.  */
@@ -3245,8 +3247,13 @@ dfaexec (struct dfa *d, char const *begin, char *end,
   if (d->mb_cur_max > 1)
     {
       memset (&d->mbs, 0, sizeof d->mbs);
-      d->mb_match_lens = xnmalloc (d->nleaves, sizeof *d->mb_match_lens);
-      alloc_position_set (&d->mb_follows, d->nleaves);
+
+      if (!d->mb_alloc)
+        {
+          d->mb_match_lens = xnmalloc (d->nleaves, sizeof *d->mb_match_lens);
+          alloc_position_set (&d->mb_follows, d->nleaves);
+          d->mb_alloc = true;
+        }
     }
 
   for (;;)
@@ -3420,8 +3427,13 @@ free_mbdata (struct dfa *d)
     }
 
   free (d->mbcsets);
-  free (d->mb_follows.elems);
-  free (d->mb_match_lens);
+
+  if (d->mb_alloc)
+    {
+      free (d->mb_follows.elems);
+      free (d->mb_match_lens);
+      d->mb_alloc = false;
+    }
 }
 
 /* Initialize the components of a dfa that the other routines don't
-- 
1.9.2