[pcre] Fix compile-time loop for recursive reference within a group with an indefinite repeat

Petr Pisar ppisar at fedoraproject.org
Mon Aug 11 11:33:32 UTC 2014


commit 2eeee2e33c53a41ce90705b1ae62b91bedb9cf65
Author: Petr Písař <ppisar at redhat.com>
Date:   Mon Aug 11 10:13:52 2014 +0200

    Fix compile-time loop for recursive reference within a group with an indefinite repeat

 ...-time-loop-for-recursive-reference-within.patch |  100 ++++++++++++++++++++
 pcre.spec                                          |   10 ++-
 2 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/pcre-8.35-Fix-compile-time-loop-for-recursive-reference-within.patch b/pcre-8.35-Fix-compile-time-loop-for-recursive-reference-within.patch
new file mode 100644
index 0000000..900ff5e
--- /dev/null
+++ b/pcre-8.35-Fix-compile-time-loop-for-recursive-reference-within.patch
@@ -0,0 +1,100 @@
+From fd411b0b71fc1d0bd1977d0a86e5711599f875d8 Mon Sep 17 00:00:00 2001
+From: ph10 <ph10 at 2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date: Fri, 8 Aug 2014 15:22:51 +0000
+Subject: [PATCH] Fix compile-time loop for recursive reference within a group
+ with an indefinite repeat.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1498 2f5784b3-3f2a-0410-8824-cb99058d5e15
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+
+Petr Pisar: Ported to 8.35.
+
+diff --git a/pcre_compile.c b/pcre_compile.c
+index 8276d0f..4bb05b9 100644
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -2374,6 +2374,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
+   if (c == OP_RECURSE)
+     {
+     const pcre_uchar *scode = cd->start_code + GET(code, 1);
++    const pcre_uchar *endgroup = scode;
+     BOOL empty_branch;
+ 
+     /* Test for forward reference or uncompleted reference. This is disabled
+@@ -2388,24 +2389,20 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
+       if (GET(scode, 1) == 0) return TRUE;    /* Unclosed */
+       }
+ 
+-    /* If we are scanning a completed pattern, there are no forward references
+-    and all groups are complete. We need to detect whether this is a recursive
+-    call, as otherwise there will be an infinite loop. If it is a recursion,
+-    just skip over it. Simple recursions are easily detected. For mutual
+-    recursions we keep a chain on the stack. */
++    /* If the reference is to a completed group, we need to detect whether this
++    is a recursive call, as otherwise there will be an infinite loop. If it is
++    a recursion, just skip over it. Simple recursions are easily detected. For
++    mutual recursions we keep a chain on the stack. */
+ 
++    do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
++    if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
+     else
+-      {
++      {  
+       recurse_check *r = recurses;
+-      const pcre_uchar *endgroup = scode;
+-
+-      do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
+-      if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
+-
+       for (r = recurses; r != NULL; r = r->prev)
+         if (r->group == scode) break;
+       if (r != NULL) continue;   /* Mutual recursion */
+-      }
++      } 
+ 
+     /* Completed reference; scan the referenced group, remembering it on the
+     stack chain to detect mutual recursions. */
+diff --git a/testdata/testinput1 b/testdata/testinput1
+index 6fd62ba..123e3d3 100644
+--- a/testdata/testinput1
++++ b/testdata/testinput1
+@@ -4937,6 +4937,12 @@ however, we need the complication for Perl. ---/
+ 
+ /((?(R1)a+|(?1)b))/
+     aaaabcde
++    
++/((?(R)a|(?1)))*/
++    aaa
++
++/((?(R)a|(?1)))+/
++    aaa
+ 
+ /a(*:any 
+ name)/K
+diff --git a/testdata/testoutput1 b/testdata/testoutput1
+index eeddf0f..5e71900 100644
+--- a/testdata/testoutput1
++++ b/testdata/testoutput1
+@@ -8234,6 +8234,16 @@ MK: M
+     aaaabcde
+  0: aaaab
+  1: aaaab
++    
++/((?(R)a|(?1)))*/
++    aaa
++ 0: aaa
++ 1: a
++
++/((?(R)a|(?1)))+/
++    aaa
++ 0: aaa
++ 1: a
+ 
+ /a(*:any 
+ name)/K
+-- 
+1.9.3
+
diff --git a/pcre.spec b/pcre.spec
index 1e94bb0..816b7c1 100644
--- a/pcre.spec
+++ b/pcre.spec
@@ -2,7 +2,7 @@
 #%%global rcversion RC1
 Name: pcre
 Version: 8.35
-Release: %{?rcversion:0.}5%{?rcversion:.%rcversion}%{?dist}
+Release: %{?rcversion:0.}6%{?rcversion:.%rcversion}%{?dist}
 %global myversion %{version}%{?rcversion:-%rcversion}
 Summary: Perl-compatible regular expression library
 Group: System Environment/Libraries
@@ -35,6 +35,9 @@ Patch7: pcre-8.35-Fixed-several-memory-leaks-in-pcregrep.patch
 # Fix compiler crash for zero-repeated groups with a recursive back reference,
 # bug #1119272, upstream bug #1503, in upstream after 8.35
 Patch8: pcre-8.35-Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch
+# Fix compile-time loop for recursive reference within a group with an
+# indefinite repeat, bug #1128577, upstream bug #1515, in upstream after 8.35
+Patch9: pcre-8.35-Fix-compile-time-loop-for-recursive-reference-within.patch
 BuildRequires: readline-devel
 # New libtool to get rid of rpath
 BuildRequires: autoconf, automake, libtool
@@ -83,6 +86,7 @@ Utilities demonstrating PCRE capabilities like pcregrep or pcretest.
 %patch6 -p1 -b .empty_zero_repeat_group
 %patch7 -p1 -b .pcregrep_leak
 %patch8 -p1 -b .compiler_crash_zero_group
+%patch9 -p1 -b .compiler_loop_recursive_reference
 # Because of rpath patch
 libtoolize --copy --force && autoreconf -vif
 # One contributor's name is non-UTF-8
@@ -153,6 +157,10 @@ make %{?_smp_mflags} check VERBOSE=yes
 %{_mandir}/man1/pcretest.*
 
 %changelog
+* Mon Aug 11 2014 Petr Pisar <ppisar at redhat.com> - 8.35-6
+- Fix compile-time loop for recursive reference within a group with an
+  indefinite repeat (bug #1128577)
+
 * Wed Jul 30 2014 Tom Callaway <spot at fedoraproject.org> - 8.35-5
 - fix license handling
 


More information about the scm-commits mailing list