Subject: bug#29446: GNU grep 3.1 fails test suite when PCRE lacks JIT

From: Paul Eggert <[email-masked]>
Date: Sat, 25 Nov 2017 20:15:51 -0800

I'd rather fix the problem than skip the test. I installed the attached into the 
master branch on Savannah: does it fix the problem for you?

PS. Please use the name "Adélie GNU/Linux" when referring to that distribution, 
to give proper credit to the GNU project. Thanks.
From d069525b20e65ef86fb680ba830db634487f111e Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sat, 25 Nov 2017 20:08:45 -0800
Subject: [PATCH] =?UTF-8?q?grep:=20port=20better=20to=20Ad=C3=A9lie=20GNU/?=
 =?UTF-8?q?Linux=2064-bit=20ppc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by A. Wilcox (Bug#29446).
* src/pcresearch.c (PCRE_EXTRA_MATCH_LIMIT_RECURSION)
(PCRE_STUDY_EXTRA_NEEDED): Default to 0.
(jit_exec): If we run up against the recursion limit,
double it (if possible) and try again.
(Pcompile): Also specify PCRE_STUDY_EXTRA_NEEDED so that
pc->extra is not null.
---
 src/pcresearch.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/pcresearch.c b/src/pcresearch.c
index 43f91d0..96b7fc6 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -29,9 +29,15 @@
    in pcre_exec.  */
 enum { NSUB = 300 };
 
+# ifndef PCRE_EXTRA_MATCH_LIMIT_RECURSION
+#  define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0
+# endif
 # ifndef PCRE_STUDY_JIT_COMPILE
 #  define PCRE_STUDY_JIT_COMPILE 0
 # endif
+# ifndef PCRE_STUDY_EXTRA_NEEDED
+#  define PCRE_STUDY_EXTRA_NEEDED 0
+# endif
 
 struct pcre_comp
 {
@@ -83,6 +89,21 @@ jit_exec (struct pcre_comp *pc, char const *subject, int search_bytes,
         }
 # endif
 
+# if PCRE_EXTRA_MATCH_LIMIT_RECURSION
+      if (e == PCRE_ERROR_RECURSIONLIMIT
+          && (PCRE_STUDY_EXTRA_NEEDED || pc->extra)
+          && pc->extra->match_limit_recursion <= ULONG_MAX / 2)
+        {
+          pc->extra->match_limit_recursion *= 2;
+          if (pc->extra->match_limit_recursion == 0)
+            {
+              pc->extra->match_limit_recursion = (1 << 24) - 1;
+              pc->extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+            }
+          continue;
+        }
+# endif
+
       return e;
     }
 }
@@ -158,7 +179,8 @@ Pcompile (char *pattern, size_t size, reg_syntax_t ignored)
   if (!pc->cre)
     die (EXIT_TROUBLE, 0, "%s", ep);
 
-  pc->extra = pcre_study (pc->cre, PCRE_STUDY_JIT_COMPILE, &ep);
+  int pcre_study_flags = PCRE_STUDY_EXTRA_NEEDED | PCRE_STUDY_JIT_COMPILE;
+  pc->extra = pcre_study (pc->cre, pcre_study_flags, &ep);
   if (ep)
     die (EXIT_TROUBLE, 0, "%s", ep);
 
-- 
2.7.4