chiark / gitweb /
tidy up conflict
authorMatthew Vernon <matthew@debian.org>
Sat, 21 Nov 2015 12:03:44 +0000 (12:03 +0000)
committerMatthew Vernon <matthew@debian.org>
Sat, 21 Nov 2015 12:03:44 +0000 (12:03 +0000)
20 files changed:
debian/changelog
debian/patches/794589-information-disclosure.patch [new file with mode: 0644]
debian/patches/Disable_JIT_on_sparc64.patch [new file with mode: 0644]
debian/patches/Fix-bad-compilation-for-patterns-like-1-1-with-forwa.patch [new file with mode: 0644]
debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch [new file with mode: 0644]
debian/patches/Fix-buffer-overflow-for-named-recursive-back-referen.patch [new file with mode: 0644]
debian/patches/Fix-compile-time-loop-for-recursive-reference-within.patch [new file with mode: 0644]
debian/patches/Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch [new file with mode: 0644]
debian/patches/series
pcre_compile.c
pcre_exec.c
sljit/sljitConfigInternal.h
testdata/testinput1
testdata/testinput11
testdata/testinput2
testdata/testoutput1
testdata/testoutput11-16
testdata/testoutput11-32
testdata/testoutput11-8
testdata/testoutput2

index 190252c9ae89eaa67a5ada6aaf3f8049e7dc63b5..4343549a8c22a989983dc3c8da4878731fe4a2d0 100644 (file)
@@ -1,3 +1,39 @@
+pcre3 (2:8.35-7.4) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Fix copy-and-paste error in Disable_JIT_on_sparc64.patch.
+
+ -- John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>  Mon, 02 Nov 2015 18:51:13 +0100
+
+pcre3 (2:8.35-7.3) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Add Disable_JIT_on_sparc64.patch to disable JIT on sparc64. The patch
+    no_jit_x32_powerpcspe.patch to disable JIT on powerpcspe was already
+    added in 2:8.35-6 (Closes: #765079).
+
+ -- John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>  Mon, 02 Nov 2015 15:13:16 +0100
+
+pcre3 (2:8.35-7.2) unstable; urgency=low
+
+  * Non-maintainer upload (with maintainer's permission).
+  * Add Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch.
+    Fixes "PCRE Library Stack Overflow Vulnerability" (Upstream bug 1503)
+  * Add Fix-compile-time-loop-for-recursive-reference-within.patch.
+    Fixes "PCRE Call Stack Overflow Vulnerability" (Upstream bug 1515)
+  * Add 794589-information-disclosure.patch.
+    Fixes "pcre_exec does not fill offsets for certain regexps" leading to
+    information disclosure. (Closes: #794589)
+  * Add Fix-bad-compile-for-groups-like-2-0-1999.patch.
+    CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795)
+  * Add Fix-bad-compilation-for-patterns-like-1-1-with-forwa.patch.
+    CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285)
+  * Add Fix-buffer-overflow-for-named-recursive-back-referen.patch.
+    CVE-2015-3210: heap buffer overflow in pcre_compile2() /
+    compile_regex(). (Closes: #787433)
+
+ -- Salvatore Bonaccorso <carnil@debian.org>  Fri, 11 Sep 2015 20:04:19 +0200
+
 pcre3 (2:8.35-7.1) unstable; urgency=medium
 
   * Rename libpcrecpp0 to libpcrecpp0v5. Addresses: #791236.
diff --git a/debian/patches/794589-information-disclosure.patch b/debian/patches/794589-information-disclosure.patch
new file mode 100644 (file)
index 0000000..b3aba7f
--- /dev/null
@@ -0,0 +1,30 @@
+Description: pcre_exec does not fill offsets for certain regexps
+Origin: upstream, http://vcs.pcre.org/pcre/code/trunk/pcre_exec.c?r1=1502&r2=1510
+Bug: https://bugs.exim.org/show_bug.cgi?id=1537
+Bug-Debian: https://bugs.debian.org/794589
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.37
+
+--- a/pcre_exec.c
++++ b/pcre_exec.c
+@@ -1467,7 +1467,18 @@ for (;;)
+       md->offset_vector[offset] =
+         md->offset_vector[md->offset_end - number];
+       md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
+-      if (offset_top <= offset) offset_top = offset + 2;
++
++      /* If this group is at or above the current highwater mark, ensure that
++      any groups between the current high water mark and this group are marked
++      unset and then update the high water mark. */
++
++      if (offset >= offset_top)
++        {
++        register int *iptr = md->offset_vector + offset_top;
++        register int *iend = md->offset_vector + offset;
++        while (iptr < iend) *iptr++ = -1;
++        offset_top = offset + 2;
++        }
+       }
+     ecode += 1 + IMM2_SIZE;
+     break;
diff --git a/debian/patches/Disable_JIT_on_sparc64.patch b/debian/patches/Disable_JIT_on_sparc64.patch
new file mode 100644 (file)
index 0000000..aacf883
--- /dev/null
@@ -0,0 +1,23 @@
+Description: Disable JIT on sparc64 as it needs explicit porting
+ The test suite currently fails on sparc64 when the JIT is enabled
+ as the JIT has not been ported to sparc64 yet. Thus, disable JIT
+ until it has been explicitly ported to sparc64.
+ .
+
+Index: pcre3-8.35/sljit/sljitConfigInternal.h
+===================================================================
+--- pcre3-8.35.orig/sljit/sljitConfigInternal.h
++++ pcre3-8.35/sljit/sljitConfigInternal.h
+@@ -125,7 +125,11 @@
+ #elif defined(__mips64)
+ #define SLJIT_CONFIG_MIPS_64 1
+ #elif defined(__sparc__) || defined(__sparc)
+-#define SLJIT_CONFIG_SPARC_32 1
++# if defined(__arch64__)
++#  define SLJIT_CONFIG_UNSUPPORTED 1
++# else
++#  define SLJIT_CONFIG_SPARC_32 1
++# endif
+ #elif defined(__tilegx__)
+ #define SLJIT_CONFIG_TILEGX 1
+ #else
diff --git a/debian/patches/Fix-bad-compilation-for-patterns-like-1-1-with-forwa.patch b/debian/patches/Fix-bad-compilation-for-patterns-like-1-1-with-forwa.patch
new file mode 100644 (file)
index 0000000..ed5b5c1
--- /dev/null
@@ -0,0 +1,145 @@
+Description: CVE-2015-2326: heap buffer overflow in pcre_compile2()
+ Fix bad compilation for patterns like /((?+1)(\1))/ with
+ forward reference subroutine and recursive back reference within the same
+ group.
+Origin: upstream, http://vcs.pcre.org/pcre?view=revision&revision=1529
+Bug: http://bugs.exim.org/show_bug.cgi?id=1592
+Bug-Debian: https://bugs.debian.org/783285
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.36
+
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -8027,6 +8027,7 @@ int length;
+ unsigned int orig_bracount;
+ unsigned int max_bracount;
+ branch_chain bc;
++size_t save_hwm_offset;
+ /* If set, call the external function that checks for stack availability. */
+@@ -8044,6 +8045,8 @@ bc.current_branch = code;
+ firstchar = reqchar = 0;
+ firstcharflags = reqcharflags = REQ_UNSET;
++save_hwm_offset = cd->hwm - cd->start_workspace;
++
+ /* Accumulate the length for use in the pre-compile phase. Start with the
+ length of the BRA and KET and any extra bytes that are required at the
+ beginning. We accumulate in a local variable to save frequent testing of
+@@ -8246,7 +8249,7 @@ for (;;)
+         {
+         *code = OP_END;
+         adjust_recurse(start_bracket, 1 + LINK_SIZE,
+-          (options & PCRE_UTF8) != 0, cd, cd->hwm - cd->start_workspace);
++          (options & PCRE_UTF8) != 0, cd, save_hwm_offset);
+         memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+           IN_UCHARS(code - start_bracket));
+         *start_bracket = OP_ONCE;
+--- a/testdata/testinput11
++++ b/testdata/testinput11
+@@ -134,4 +134,6 @@ is required for these tests. --/
+ /(((a\2)|(a*)\g<-1>))*a?/B
++/((?+1)(\1))/B
++
+ /-- End of testinput11 --/
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4066,4 +4066,6 @@ backtracking verbs. --/
+ "((?2){0,1999}())?"
++/((?+1)(\1))/BZ
++
+ /-- End of testinput2 --/
+--- a/testdata/testoutput11-16
++++ b/testdata/testoutput11-16
+@@ -733,4 +733,19 @@ Memory allocation (code space): 14
+  41     End
+ ------------------------------------------------------------------
++/((?+1)(\1))/B
++------------------------------------------------------------------
++  0  20 Bra
++  2  16 Once
++  4  12 CBra 1
++  7   9 Recurse
++  9   5 CBra 2
++ 12     \1
++ 14   5 Ket
++ 16  12 Ket
++ 18  16 Ket
++ 20  20 Ket
++ 22     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput11-32
++++ b/testdata/testoutput11-32
+@@ -733,4 +733,19 @@ Memory allocation (code space): 28
+  41     End
+ ------------------------------------------------------------------
++/((?+1)(\1))/B
++------------------------------------------------------------------
++  0  20 Bra
++  2  16 Once
++  4  12 CBra 1
++  7   9 Recurse
++  9   5 CBra 2
++ 12     \1
++ 14   5 Ket
++ 16  12 Ket
++ 18  16 Ket
++ 20  20 Ket
++ 22     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput11-8
++++ b/testdata/testoutput11-8
+@@ -733,4 +733,19 @@ Memory allocation (code space): 10
+  60     End
+ ------------------------------------------------------------------
++/((?+1)(\1))/B
++------------------------------------------------------------------
++  0  31 Bra
++  3  25 Once
++  6  19 CBra 1
++ 11  14 Recurse
++ 14   8 CBra 2
++ 19     \1
++ 22   8 Ket
++ 25  19 Ket
++ 28  25 Ket
++ 31  31 Ket
++ 34     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14175,4 +14175,19 @@ Failed: parentheses are too deeply neste
+ "((?2){0,1999}())?"
++/((?+1)(\1))/BZ
++------------------------------------------------------------------
++        Bra
++        Once
++        CBra 1
++        Recurse
++        CBra 2
++        \1
++        Ket
++        Ket
++        Ket
++        Ket
++        End
++------------------------------------------------------------------
++
+ /-- End of testinput2 --/
diff --git a/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch b/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch
new file mode 100644 (file)
index 0000000..f019be6
--- /dev/null
@@ -0,0 +1,209 @@
+Description: CVE-2015-2325: heap buffer overflow in compile_branch()
+ Fix bad compile for groups like "((?2){0,1999}())?".
+Origin: backport, http://vcs.pcre.org/pcre?view=revision&revision=1528
+Bug: http://bugs.exim.org/show_bug.cgi?id=1591
+Bug-Debian: https://bugs.debian.org/781795
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.37
+
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -3933,14 +3933,14 @@ Arguments:
+   adjust     the amount by which the group is to be moved
+   utf        TRUE in UTF-8 / UTF-16 / UTF-32 mode
+   cd         contains pointers to tables etc.
+-  save_hwm   the hwm forward reference pointer at the start of the group
++  save_hwm_offset   the hwm forward reference offset at the start of the group
+ Returns:     nothing
+ */
+ static void
+ adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
+-  pcre_uchar *save_hwm)
++  size_t save_hwm_offset)
+ {
+ pcre_uchar *ptr = group;
+@@ -3952,7 +3952,8 @@ while ((ptr = (pcre_uchar *)find_recurse
+   /* See if this recursion is on the forward reference list. If so, adjust the
+   reference. */
+-  for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
++  for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm; 
++       hc += LINK_SIZE)
+     {
+     offset = (int)GET(hc, 0);
+     if (cd->start_code + offset == ptr + 1)
+@@ -4397,7 +4398,7 @@ const pcre_uchar *tempptr;
+ const pcre_uchar *nestptr = NULL;
+ pcre_uchar *previous = NULL;
+ pcre_uchar *previous_callout = NULL;
+-pcre_uchar *save_hwm = NULL;
++size_t save_hwm_offset = 0;
+ pcre_uint8 classbits[32];
+ /* We can fish out the UTF-8 setting once and for all into a BOOL, but we
+@@ -5909,7 +5910,7 @@ for (;; ptr++)
+         if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
+           {
+           *code = OP_END;
+-          adjust_recurse(previous, 1, utf, cd, save_hwm);
++          adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
+           memmove(previous + 1, previous, IN_UCHARS(len));
+           code++;
+           if (repeat_max == 0)
+@@ -5933,7 +5934,7 @@ for (;; ptr++)
+           {
+           int offset;
+           *code = OP_END;
+-          adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
++          adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
+           memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
+           code += 2 + LINK_SIZE;
+           *previous++ = OP_BRAZERO + repeat_type;
+@@ -5996,26 +5997,25 @@ for (;; ptr++)
+             for (i = 1; i < repeat_min; i++)
+               {
+               pcre_uchar *hc;
+-              pcre_uchar *this_hwm = cd->hwm;
++              size_t this_hwm_offset = cd->hwm - cd->start_workspace;
+               memcpy(code, previous, IN_UCHARS(len));
+               while (cd->hwm > cd->start_workspace + cd->workspace_size -
+-                     WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
++                     WORK_SIZE_SAFETY_MARGIN -
++                     (this_hwm_offset - save_hwm_offset))
+                 {
+-                int save_offset = save_hwm - cd->start_workspace;
+-                int this_offset = this_hwm - cd->start_workspace;
+                 *errorcodeptr = expand_workspace(cd);
+                 if (*errorcodeptr != 0) goto FAILED;
+-                save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+-                this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+                 }
+-              for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
++              for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
++                   hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
++                   hc += LINK_SIZE)
+                 {
+                 PUT(cd->hwm, 0, GET(hc, 0) + len);
+                 cd->hwm += LINK_SIZE;
+                 }
+-              save_hwm = this_hwm;
++              save_hwm_offset = this_hwm_offset;
+               code += len;
+               }
+             }
+@@ -6060,7 +6060,7 @@ for (;; ptr++)
+         else for (i = repeat_max - 1; i >= 0; i--)
+           {
+           pcre_uchar *hc;
+-          pcre_uchar *this_hwm = cd->hwm;
++          size_t this_hwm_offset = cd->hwm - cd->start_workspace;
+           *code++ = OP_BRAZERO + repeat_type;
+@@ -6082,22 +6082,21 @@ for (;; ptr++)
+           copying them. */
+           while (cd->hwm > cd->start_workspace + cd->workspace_size -
+-                 WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
++                 WORK_SIZE_SAFETY_MARGIN -
++                 (this_hwm_offset - save_hwm_offset))
+             {
+-            int save_offset = save_hwm - cd->start_workspace;
+-            int this_offset = this_hwm - cd->start_workspace;
+             *errorcodeptr = expand_workspace(cd);
+             if (*errorcodeptr != 0) goto FAILED;
+-            save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+-            this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+             }
+-          for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
++          for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
++               hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
++               hc += LINK_SIZE)
+             {
+             PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
+             cd->hwm += LINK_SIZE;
+             }
+-          save_hwm = this_hwm;
++          save_hwm_offset = this_hwm_offset;
+           code += len;
+           }
+@@ -6193,7 +6192,7 @@ for (;; ptr++)
+               {
+               int nlen = (int)(code - bracode);
+               *code = OP_END;
+-              adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
++              adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+               memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
+               code += 1 + LINK_SIZE;
+               nlen += 1 + LINK_SIZE;
+@@ -6327,7 +6326,7 @@ for (;; ptr++)
+         else
+           {
+           *code = OP_END;
+-          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
++          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+           memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+           code += 1 + LINK_SIZE;
+           len += 1 + LINK_SIZE;
+@@ -6376,7 +6375,7 @@ for (;; ptr++)
+         default:
+         *code = OP_END;
+-        adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
++        adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+         memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+         code += 1 + LINK_SIZE;
+         len += 1 + LINK_SIZE;
+@@ -6408,7 +6407,7 @@ for (;; ptr++)
+     newoptions = options;
+     skipbytes = 0;
+     bravalue = OP_CBRA;
+-    save_hwm = cd->hwm;
++    save_hwm_offset = cd->hwm - cd->start_workspace;
+     reset_bracount = FALSE;
+     /* First deal with various "verbs" that can be introduced by '*'. */
+@@ -7701,7 +7700,7 @@ for (;; ptr++)
+         const pcre_uchar *p;
+         pcre_uint32 cf;
+-        save_hwm = cd->hwm;   /* Normally this is set when '(' is read */
++        save_hwm_offset = cd->hwm - cd->start_workspace;   /* Normally this is set when '(' is read */
+         terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+           CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+@@ -8247,7 +8246,7 @@ for (;;)
+         {
+         *code = OP_END;
+         adjust_recurse(start_bracket, 1 + LINK_SIZE,
+-          (options & PCRE_UTF8) != 0, cd, cd->hwm);
++          (options & PCRE_UTF8) != 0, cd, cd->hwm - cd->start_workspace);
+         memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+           IN_UCHARS(code - start_bracket));
+         *start_bracket = OP_ONCE;
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4064,4 +4064,6 @@ backtracking verbs. --/
+ /(((((a)))))/Q
++"((?2){0,1999}())?"
++
+ /-- End of testinput2 --/
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14173,4 +14173,6 @@ Failed: parentheses are too deeply neste
+ /(((((a)))))/Q
+ ** Missing 0 or 1 after /Q
++"((?2){0,1999}())?"
++
+ /-- End of testinput2 --/
diff --git a/debian/patches/Fix-buffer-overflow-for-named-recursive-back-referen.patch b/debian/patches/Fix-buffer-overflow-for-named-recursive-back-referen.patch
new file mode 100644 (file)
index 0000000..3c4132b
--- /dev/null
@@ -0,0 +1,59 @@
+Description: CVE-2015-3210: heap buffer overflow in pcre_compile2() / compile_regex()
+ Fix buffer overflow for named recursive back reference when
+ the name is duplicated.
+Origin: upstream, http://vcs.pcre.org/pcre?view=revision&revision=1558
+Bug: https://bugs.exim.org/show_bug.cgi?id=1636
+Bug-Debian: https://bugs.debian.org/787433
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: not-yet (8.38)
+
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -7082,14 +7082,26 @@ for (;; ptr++)
+           number. If the name is not found, set the value to 0 for a forward
+           reference. */
++          recno = 0;
+           ng = cd->named_groups;
+           for (i = 0; i < cd->names_found; i++, ng++)
+             {
+             if (namelen == ng->length &&
+                 STRNCMP_UC_UC(name, ng->name, namelen) == 0)
+-              break;
++              {
++              open_capitem *oc;
++              recno = ng->number;
++              if (is_recurse) break;
++              for (oc = cd->open_caps; oc != NULL; oc = oc->next)         
++                {          
++                if (oc->number == recno)                                     
++                  {               
++                  oc->flag = TRUE;                                      
++                  break;
++                  }                                                         
++                }                          
++              }    
+             }
+-          recno = (i < cd->names_found)? ng->number : 0;
+           /* Count named back references. */
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4068,4 +4068,6 @@ backtracking verbs. --/
+ /((?+1)(\1))/BZ
++"(?J)(?'d'(?'d'\g{d}))"
++
+ /-- End of testinput2 --/
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14190,4 +14190,6 @@ Failed: parentheses are too deeply neste
+         End
+ ------------------------------------------------------------------
++"(?J)(?'d'(?'d'\g{d}))"
++
+ /-- End of testinput2 --/
diff --git a/debian/patches/Fix-compile-time-loop-for-recursive-reference-within.patch b/debian/patches/Fix-compile-time-loop-for-recursive-reference-within.patch
new file mode 100644 (file)
index 0000000..a38be27
--- /dev/null
@@ -0,0 +1,86 @@
+Description: PCRE Call Stack Overflow Vulnerability
+ Fix compile-time loop for recursive reference within a group
+ with an indefinite repeat.
+Origin: backport, http://vcs.pcre.org/pcre?view=revision&revision=1498
+Bug: https://bugs.exim.org/show_bug.cgi?id=1515
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.36
+
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -2367,6 +2367,7 @@ for (code = first_significant_code(code
+   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
+@@ -2381,24 +2382,20 @@ for (code = first_significant_code(code
+       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. */
+--- a/testdata/testinput1
++++ b/testdata/testinput1
+@@ -4937,6 +4937,12 @@ however, we need the complication for Pe
+ /((?(R1)a+|(?1)b))/
+     aaaabcde
++    
++/((?(R)a|(?1)))*/
++    aaa
++
++/((?(R)a|(?1)))+/
++    aaa
+ /a(*:any 
+ name)/K
+--- 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
diff --git a/debian/patches/Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch b/debian/patches/Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch
new file mode 100644 (file)
index 0000000..a8c15f3
--- /dev/null
@@ -0,0 +1,175 @@
+Description: PCRE Library Stack Overflow Vulnerability
+ Fix compiler crash/misbehaviour for zero-repeated groups that
+ include a recursive back reference.
+Origin: backport, http://vcs.pcre.org/pcre?view=revision&revision=1495
+Bug: https://bugs.exim.org/show_bug.cgi?id=1503
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.36
+---
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -8241,12 +8241,16 @@ for (;;)
+     /* If it was a capturing subpattern, check to see if it contained any
+     recursive back references. If so, we must wrap it in atomic brackets.
+-    In any event, remove the block from the chain. */
++    Because we are moving code along, we must ensure that any pending recursive
++    references are updated. In any event, remove the block from the chain. */
+     if (capnumber > 0)
+       {
+       if (cd->open_caps->flag)
+         {
++        *code = OP_END;
++        adjust_recurse(start_bracket, 1 + LINK_SIZE,
++          (options & PCRE_UTF8) != 0, cd, cd->hwm);
+         memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+           IN_UCHARS(code - start_bracket));
+         *start_bracket = OP_ONCE;
+--- a/testdata/testinput11
++++ b/testdata/testinput11
+@@ -132,4 +132,6 @@ is required for these tests. --/
+ /abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
++/(((a\2)|(a*)\g<-1>))*a?/B
++
+ /-- End of testinput11 --/
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4035,6 +4035,8 @@ backtracking verbs. --/
+ /(?(R&6yh)abc)/
++/(((a\2)|(a*)\g<-1>))*a?/BZ
++
+ /-- Test the ugly "start or end of word" compatibility syntax --/
+ /[[:<:]]red[[:>:]]/BZ
+--- a/testdata/testoutput11-16
++++ b/testdata/testoutput11-16
+@@ -709,4 +709,28 @@ Memory allocation (code space): 14
+  62     End
+ ------------------------------------------------------------------
++/(((a\2)|(a*)\g<-1>))*a?/B
++------------------------------------------------------------------
++  0  39 Bra
++  2     Brazero
++  3  32 SCBra 1
++  6  27 Once
++  8  12 CBra 2
++ 11   7 CBra 3
++ 14     a
++ 16     \2
++ 18   7 Ket
++ 20  11 Alt
++ 22   5 CBra 4
++ 25     a*
++ 27   5 Ket
++ 29  22 Recurse
++ 31  23 Ket
++ 33  27 Ket
++ 35  32 KetRmax
++ 37     a?+
++ 39  39 Ket
++ 41     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput11-32
++++ b/testdata/testoutput11-32
+@@ -709,4 +709,28 @@ Memory allocation (code space): 28
+  62     End
+ ------------------------------------------------------------------
++/(((a\2)|(a*)\g<-1>))*a?/B
++------------------------------------------------------------------
++  0  39 Bra
++  2     Brazero
++  3  32 SCBra 1
++  6  27 Once
++  8  12 CBra 2
++ 11   7 CBra 3
++ 14     a
++ 16     \2
++ 18   7 Ket
++ 20  11 Alt
++ 22   5 CBra 4
++ 25     a*
++ 27   5 Ket
++ 29  22 Recurse
++ 31  23 Ket
++ 33  27 Ket
++ 35  32 KetRmax
++ 37     a?+
++ 39  39 Ket
++ 41     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput11-8
++++ b/testdata/testoutput11-8
+@@ -709,4 +709,28 @@ Memory allocation (code space): 10
+  76     End
+ ------------------------------------------------------------------
++/(((a\2)|(a*)\g<-1>))*a?/B
++------------------------------------------------------------------
++  0  57 Bra
++  3     Brazero
++  4  48 SCBra 1
++  9  40 Once
++ 12  18 CBra 2
++ 17  10 CBra 3
++ 22     a
++ 24     \2
++ 27  10 Ket
++ 30  16 Alt
++ 33   7 CBra 4
++ 38     a*
++ 40   7 Ket
++ 43  33 Recurse
++ 46  34 Ket
++ 49  40 Ket
++ 52  48 KetRmax
++ 55     a?+
++ 57  57 Ket
++ 60     End
++------------------------------------------------------------------
++
+ /-- End of testinput11 --/
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14093,6 +14093,30 @@ Failed: malformed number or name after (
+ /(?(R&6yh)abc)/
+ Failed: group name must start with a non-digit at offset 5
++/(((a\2)|(a*)\g<-1>))*a?/BZ
++------------------------------------------------------------------
++        Bra
++        Brazero
++        SCBra 1
++        Once
++        CBra 2
++        CBra 3
++        a
++        \2
++        Ket
++        Alt
++        CBra 4
++        a*
++        Ket
++        Recurse
++        Ket
++        Ket
++        KetRmax
++        a?+
++        Ket
++        End
++------------------------------------------------------------------
++
+ /-- Test the ugly "start or end of word" compatibility syntax --/
+ /[[:<:]]red[[:>:]]/BZ
index c30b0d0876369cc141e437fab4d18443959b4995..6bdf0051b84e5e7bd258b39292129cf3e87764a0 100644 (file)
@@ -7,3 +7,10 @@ Fix-silly-quantifier-size-check.patch
 cve-2014-8964.patch
 no_jit_x32_powerpcspe.patch
 fix_find_fixedlength.patch
+Fix-compiler-crash-misbehaviour-for-zero-repeated-gr.patch
+Fix-compile-time-loop-for-recursive-reference-within.patch
+794589-information-disclosure.patch
+Fix-bad-compile-for-groups-like-2-0-1999.patch
+Fix-bad-compilation-for-patterns-like-1-1-with-forwa.patch
+Fix-buffer-overflow-for-named-recursive-back-referen.patch
+Disable_JIT_on_sparc64.patch
index c76ca1418d97679764ff32c4370cc74a3f06e741..08caf8ed72f964ee3f8fce43bf91eb19649598d5 100644 (file)
@@ -2367,6 +2367,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
@@ -2381,24 +2382,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. */
@@ -3936,14 +3933,14 @@ Arguments:
   adjust     the amount by which the group is to be moved
   utf        TRUE in UTF-8 / UTF-16 / UTF-32 mode
   cd         contains pointers to tables etc.
-  save_hwm   the hwm forward reference pointer at the start of the group
+  save_hwm_offset   the hwm forward reference offset at the start of the group
 
 Returns:     nothing
 */
 
 static void
 adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
-  pcre_uchar *save_hwm)
+  size_t save_hwm_offset)
 {
 pcre_uchar *ptr = group;
 
@@ -3955,7 +3952,8 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
   /* See if this recursion is on the forward reference list. If so, adjust the
   reference. */
 
-  for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
+  for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm; 
+       hc += LINK_SIZE)
     {
     offset = (int)GET(hc, 0);
     if (cd->start_code + offset == ptr + 1)
@@ -4400,7 +4398,7 @@ const pcre_uchar *tempptr;
 const pcre_uchar *nestptr = NULL;
 pcre_uchar *previous = NULL;
 pcre_uchar *previous_callout = NULL;
-pcre_uchar *save_hwm = NULL;
+size_t save_hwm_offset = 0;
 pcre_uint8 classbits[32];
 
 /* We can fish out the UTF-8 setting once and for all into a BOOL, but we
@@ -5912,7 +5910,7 @@ for (;; ptr++)
         if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
           {
           *code = OP_END;
-          adjust_recurse(previous, 1, utf, cd, save_hwm);
+          adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
           memmove(previous + 1, previous, IN_UCHARS(len));
           code++;
           if (repeat_max == 0)
@@ -5936,7 +5934,7 @@ for (;; ptr++)
           {
           int offset;
           *code = OP_END;
-          adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
+          adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
           memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
           code += 2 + LINK_SIZE;
           *previous++ = OP_BRAZERO + repeat_type;
@@ -5999,26 +5997,25 @@ for (;; ptr++)
             for (i = 1; i < repeat_min; i++)
               {
               pcre_uchar *hc;
-              pcre_uchar *this_hwm = cd->hwm;
+              size_t this_hwm_offset = cd->hwm - cd->start_workspace;
               memcpy(code, previous, IN_UCHARS(len));
 
               while (cd->hwm > cd->start_workspace + cd->workspace_size -
-                     WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+                     WORK_SIZE_SAFETY_MARGIN -
+                     (this_hwm_offset - save_hwm_offset))
                 {
-                int save_offset = save_hwm - cd->start_workspace;
-                int this_offset = this_hwm - cd->start_workspace;
                 *errorcodeptr = expand_workspace(cd);
                 if (*errorcodeptr != 0) goto FAILED;
-                save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
-                this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
                 }
 
-              for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+              for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
+                   hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
+                   hc += LINK_SIZE)
                 {
                 PUT(cd->hwm, 0, GET(hc, 0) + len);
                 cd->hwm += LINK_SIZE;
                 }
-              save_hwm = this_hwm;
+              save_hwm_offset = this_hwm_offset;
               code += len;
               }
             }
@@ -6063,7 +6060,7 @@ for (;; ptr++)
         else for (i = repeat_max - 1; i >= 0; i--)
           {
           pcre_uchar *hc;
-          pcre_uchar *this_hwm = cd->hwm;
+          size_t this_hwm_offset = cd->hwm - cd->start_workspace;
 
           *code++ = OP_BRAZERO + repeat_type;
 
@@ -6085,22 +6082,21 @@ for (;; ptr++)
           copying them. */
 
           while (cd->hwm > cd->start_workspace + cd->workspace_size -
-                 WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+                 WORK_SIZE_SAFETY_MARGIN -
+                 (this_hwm_offset - save_hwm_offset))
             {
-            int save_offset = save_hwm - cd->start_workspace;
-            int this_offset = this_hwm - cd->start_workspace;
             *errorcodeptr = expand_workspace(cd);
             if (*errorcodeptr != 0) goto FAILED;
-            save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
-            this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
             }
 
-          for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+          for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
+               hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
+               hc += LINK_SIZE)
             {
             PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
             cd->hwm += LINK_SIZE;
             }
-          save_hwm = this_hwm;
+          save_hwm_offset = this_hwm_offset;
           code += len;
           }
 
@@ -6196,7 +6192,7 @@ for (;; ptr++)
               {
               int nlen = (int)(code - bracode);
               *code = OP_END;
-              adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
+              adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
               memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
               code += 1 + LINK_SIZE;
               nlen += 1 + LINK_SIZE;
@@ -6330,7 +6326,7 @@ for (;; ptr++)
         else
           {
           *code = OP_END;
-          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
+          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
           memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
           code += 1 + LINK_SIZE;
           len += 1 + LINK_SIZE;
@@ -6379,7 +6375,7 @@ for (;; ptr++)
 
         default:
         *code = OP_END;
-        adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
+        adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
         memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
         code += 1 + LINK_SIZE;
         len += 1 + LINK_SIZE;
@@ -6411,7 +6407,7 @@ for (;; ptr++)
     newoptions = options;
     skipbytes = 0;
     bravalue = OP_CBRA;
-    save_hwm = cd->hwm;
+    save_hwm_offset = cd->hwm - cd->start_workspace;
     reset_bracount = FALSE;
 
     /* First deal with various "verbs" that can be introduced by '*'. */
@@ -7086,14 +7082,26 @@ for (;; ptr++)
           number. If the name is not found, set the value to 0 for a forward
           reference. */
 
+          recno = 0;
           ng = cd->named_groups;
           for (i = 0; i < cd->names_found; i++, ng++)
             {
             if (namelen == ng->length &&
                 STRNCMP_UC_UC(name, ng->name, namelen) == 0)
-              break;
+              {
+              open_capitem *oc;
+              recno = ng->number;
+              if (is_recurse) break;
+              for (oc = cd->open_caps; oc != NULL; oc = oc->next)         
+                {          
+                if (oc->number == recno)                                     
+                  {               
+                  oc->flag = TRUE;                                      
+                  break;
+                  }                                                         
+                }                          
+              }    
             }
-          recno = (i < cd->names_found)? ng->number : 0;
 
           /* Count named back references. */
 
@@ -7704,7 +7712,7 @@ for (;; ptr++)
         const pcre_uchar *p;
         pcre_uint32 cf;
 
-        save_hwm = cd->hwm;   /* Normally this is set when '(' is read */
+        save_hwm_offset = cd->hwm - cd->start_workspace;   /* Normally this is set when '(' is read */
         terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
           CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
 
@@ -8031,6 +8039,7 @@ int length;
 unsigned int orig_bracount;
 unsigned int max_bracount;
 branch_chain bc;
+size_t save_hwm_offset;
 
 /* If set, call the external function that checks for stack availability. */
 
@@ -8048,6 +8057,8 @@ bc.current_branch = code;
 firstchar = reqchar = 0;
 firstcharflags = reqcharflags = REQ_UNSET;
 
+save_hwm_offset = cd->hwm - cd->start_workspace;
+
 /* Accumulate the length for use in the pre-compile phase. Start with the
 length of the BRA and KET and any extra bytes that are required at the
 beginning. We accumulate in a local variable to save frequent testing of
@@ -8241,12 +8252,16 @@ for (;;)
 
     /* If it was a capturing subpattern, check to see if it contained any
     recursive back references. If so, we must wrap it in atomic brackets.
-    In any event, remove the block from the chain. */
+    Because we are moving code along, we must ensure that any pending recursive
+    references are updated. In any event, remove the block from the chain. */
 
     if (capnumber > 0)
       {
       if (cd->open_caps->flag)
         {
+        *code = OP_END;
+        adjust_recurse(start_bracket, 1 + LINK_SIZE,
+          (options & PCRE_UTF8) != 0, cd, save_hwm_offset);
         memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
           IN_UCHARS(code - start_bracket));
         *start_bracket = OP_ONCE;
index a6ef1c1fae3d7b258b802fa17cf720a168b94297..0270d60598531388c27c11cbbca80d8062fa0604 100644 (file)
@@ -1467,7 +1467,18 @@ for (;;)
       md->offset_vector[offset] =
         md->offset_vector[md->offset_end - number];
       md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
-      if (offset_top <= offset) offset_top = offset + 2;
+
+      /* If this group is at or above the current highwater mark, ensure that
+      any groups between the current high water mark and this group are marked
+      unset and then update the high water mark. */
+
+      if (offset >= offset_top)
+        {
+        register int *iptr = md->offset_vector + offset_top;
+        register int *iend = md->offset_vector + offset;
+        while (iptr < iend) *iptr++ = -1;
+        offset_top = offset + 2;
+        }
       }
     ecode += 1 + IMM2_SIZE;
     break;
index 8219e7354e7876d75fc53a9150e224d145b802bf..16175f09834f8f86fd7894538916cfc7367cf5dc 100644 (file)
 #elif defined(__mips64)
 #define SLJIT_CONFIG_MIPS_64 1
 #elif defined(__sparc__) || defined(__sparc)
-#define SLJIT_CONFIG_SPARC_32 1
+# if defined(__arch64__)
+#  define SLJIT_CONFIG_UNSUPPORTED 1
+# else
+#  define SLJIT_CONFIG_SPARC_32 1
+# endif
 #elif defined(__tilegx__)
 #define SLJIT_CONFIG_TILEGX 1
 #else
index 7b36360d044d6b8a4bb713775004e9b7d181e526..fbca11e29961dd94d3d2ee1363473990ec986f06 100644 (file)
@@ -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
index 391ada7aa8c8f98154ad22dbd43b422e91fa2186..65a4b030f6c4618bbd44d0df729a3132e50c7b2b 100644 (file)
@@ -132,4 +132,8 @@ is required for these tests. --/
 
 /abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
 
+/(((a\2)|(a*)\g<-1>))*a?/B
+
+/((?+1)(\1))/B
+
 /-- End of testinput11 --/
index da6e61499cd9f078d6fea2df64f7b4fd76674dcf..90f1795e82b178bb985507f3f9fccc3594e7fbde 100644 (file)
@@ -4035,6 +4035,8 @@ backtracking verbs. --/
 
 /(?(R&6yh)abc)/
 
+/(((a\2)|(a*)\g<-1>))*a?/BZ
+
 /-- Test the ugly "start or end of word" compatibility syntax --/
 
 /[[:<:]]red[[:>:]]/BZ
@@ -4062,4 +4064,10 @@ backtracking verbs. --/
 
 /(((((a)))))/Q
 
+"((?2){0,1999}())?"
+
+/((?+1)(\1))/BZ
+
+"(?J)(?'d'(?'d'\g{d}))"
+
 /-- End of testinput2 --/
index 4dafc0496abd7266396bbbdcc2b29169db7d6e71..09e2a8223e5f4276a87f75a4162c5972976a9386 100644 (file)
@@ -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
index f1ad8887b4d6ceebcbb9c4e84d4b6d383b3cb455..d4ba39e2f2e9603a80d7c59fcb9b8d9702054037 100644 (file)
@@ -709,4 +709,43 @@ Memory allocation (code space): 14
  62     End
 ------------------------------------------------------------------
 
+/(((a\2)|(a*)\g<-1>))*a?/B
+------------------------------------------------------------------
+  0  39 Bra
+  2     Brazero
+  3  32 SCBra 1
+  6  27 Once
+  8  12 CBra 2
+ 11   7 CBra 3
+ 14     a
+ 16     \2
+ 18   7 Ket
+ 20  11 Alt
+ 22   5 CBra 4
+ 25     a*
+ 27   5 Ket
+ 29  22 Recurse
+ 31  23 Ket
+ 33  27 Ket
+ 35  32 KetRmax
+ 37     a?+
+ 39  39 Ket
+ 41     End
+------------------------------------------------------------------
+
+/((?+1)(\1))/B
+------------------------------------------------------------------
+  0  20 Bra
+  2  16 Once
+  4  12 CBra 1
+  7   9 Recurse
+  9   5 CBra 2
+ 12     \1
+ 14   5 Ket
+ 16  12 Ket
+ 18  16 Ket
+ 20  20 Ket
+ 22     End
+------------------------------------------------------------------
+
 /-- End of testinput11 --/
index 266e55d06727a145b1e4018d1f895e112edd0398..85f4e1d905d7dacf597f3ace3e77c354276991fd 100644 (file)
@@ -709,4 +709,43 @@ Memory allocation (code space): 28
  62     End
 ------------------------------------------------------------------
 
+/(((a\2)|(a*)\g<-1>))*a?/B
+------------------------------------------------------------------
+  0  39 Bra
+  2     Brazero
+  3  32 SCBra 1
+  6  27 Once
+  8  12 CBra 2
+ 11   7 CBra 3
+ 14     a
+ 16     \2
+ 18   7 Ket
+ 20  11 Alt
+ 22   5 CBra 4
+ 25     a*
+ 27   5 Ket
+ 29  22 Recurse
+ 31  23 Ket
+ 33  27 Ket
+ 35  32 KetRmax
+ 37     a?+
+ 39  39 Ket
+ 41     End
+------------------------------------------------------------------
+
+/((?+1)(\1))/B
+------------------------------------------------------------------
+  0  20 Bra
+  2  16 Once
+  4  12 CBra 1
+  7   9 Recurse
+  9   5 CBra 2
+ 12     \1
+ 14   5 Ket
+ 16  12 Ket
+ 18  16 Ket
+ 20  20 Ket
+ 22     End
+------------------------------------------------------------------
+
 /-- End of testinput11 --/
index d4a21334e3684215fd1ea8c89423cff025ca73b8..1d604115ab18e74c4861c7d86bbd8c78ac5a5b8e 100644 (file)
@@ -709,4 +709,43 @@ Memory allocation (code space): 10
  76     End
 ------------------------------------------------------------------
 
+/(((a\2)|(a*)\g<-1>))*a?/B
+------------------------------------------------------------------
+  0  57 Bra
+  3     Brazero
+  4  48 SCBra 1
+  9  40 Once
+ 12  18 CBra 2
+ 17  10 CBra 3
+ 22     a
+ 24     \2
+ 27  10 Ket
+ 30  16 Alt
+ 33   7 CBra 4
+ 38     a*
+ 40   7 Ket
+ 43  33 Recurse
+ 46  34 Ket
+ 49  40 Ket
+ 52  48 KetRmax
+ 55     a?+
+ 57  57 Ket
+ 60     End
+------------------------------------------------------------------
+
+/((?+1)(\1))/B
+------------------------------------------------------------------
+  0  31 Bra
+  3  25 Once
+  6  19 CBra 1
+ 11  14 Recurse
+ 14   8 CBra 2
+ 19     \1
+ 22   8 Ket
+ 25  19 Ket
+ 28  25 Ket
+ 31  31 Ket
+ 34     End
+------------------------------------------------------------------
+
 /-- End of testinput11 --/
index cfb446ece60f1e2a8d2a7c829f42dda198ff88cf..16e5c6804af3955552b52d76d5f3b068d6156ddb 100644 (file)
@@ -14093,6 +14093,30 @@ Failed: malformed number or name after (?( at offset 4
 /(?(R&6yh)abc)/
 Failed: group name must start with a non-digit at offset 5
 
+/(((a\2)|(a*)\g<-1>))*a?/BZ
+------------------------------------------------------------------
+        Bra
+        Brazero
+        SCBra 1
+        Once
+        CBra 2
+        CBra 3
+        a
+        \2
+        Ket
+        Alt
+        CBra 4
+        a*
+        Ket
+        Recurse
+        Ket
+        Ket
+        KetRmax
+        a?+
+        Ket
+        End
+------------------------------------------------------------------
+
 /-- Test the ugly "start or end of word" compatibility syntax --/
 
 /[[:<:]]red[[:>:]]/BZ
@@ -14149,4 +14173,23 @@ Failed: parentheses are too deeply nested (stack check) at offset 0
 /(((((a)))))/Q
 ** Missing 0 or 1 after /Q
 
+"((?2){0,1999}())?"
+
+/((?+1)(\1))/BZ
+------------------------------------------------------------------
+        Bra
+        Once
+        CBra 1
+        Recurse
+        CBra 2
+        \1
+        Ket
+        Ket
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+"(?J)(?'d'(?'d'\g{d}))"
+
 /-- End of testinput2 --/