chiark / gitweb /
pcre3 (2:8.35-7.4) unstable; urgency=medium
[pcre3.git] / debian / patches / Fix-compile-time-loop-for-recursive-reference-within.patch
1 Description: PCRE Call Stack Overflow Vulnerability
2  Fix compile-time loop for recursive reference within a group
3  with an indefinite repeat.
4 Origin: backport, http://vcs.pcre.org/pcre?view=revision&revision=1498
5 Bug: https://bugs.exim.org/show_bug.cgi?id=1515
6 Forwarded: not-needed
7 Last-Update: 2015-09-10
8 Applied-Upstream: 8.36
9
10 --- a/pcre_compile.c
11 +++ b/pcre_compile.c
12 @@ -2367,6 +2367,7 @@ for (code = first_significant_code(code
13    if (c == OP_RECURSE)
14      {
15      const pcre_uchar *scode = cd->start_code + GET(code, 1);
16 +    const pcre_uchar *endgroup = scode;
17      BOOL empty_branch;
18  
19      /* Test for forward reference or uncompleted reference. This is disabled
20 @@ -2381,24 +2382,20 @@ for (code = first_significant_code(code
21        if (GET(scode, 1) == 0) return TRUE;    /* Unclosed */
22        }
23  
24 -    /* If we are scanning a completed pattern, there are no forward references
25 -    and all groups are complete. We need to detect whether this is a recursive
26 -    call, as otherwise there will be an infinite loop. If it is a recursion,
27 -    just skip over it. Simple recursions are easily detected. For mutual
28 -    recursions we keep a chain on the stack. */
29 +    /* If the reference is to a completed group, we need to detect whether this
30 +    is a recursive call, as otherwise there will be an infinite loop. If it is
31 +    a recursion, just skip over it. Simple recursions are easily detected. For
32 +    mutual recursions we keep a chain on the stack. */
33  
34 +    do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
35 +    if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
36      else
37 -      {
38 +      {  
39        recurse_check *r = recurses;
40 -      const pcre_uchar *endgroup = scode;
41 -
42 -      do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
43 -      if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
44 -
45        for (r = recurses; r != NULL; r = r->prev)
46          if (r->group == scode) break;
47        if (r != NULL) continue;   /* Mutual recursion */
48 -      }
49 +      } 
50  
51      /* Completed reference; scan the referenced group, remembering it on the
52      stack chain to detect mutual recursions. */
53 --- a/testdata/testinput1
54 +++ b/testdata/testinput1
55 @@ -4937,6 +4937,12 @@ however, we need the complication for Pe
56  
57  /((?(R1)a+|(?1)b))/
58      aaaabcde
59 +    
60 +/((?(R)a|(?1)))*/
61 +    aaa
62 +
63 +/((?(R)a|(?1)))+/
64 +    aaa
65  
66  /a(*:any 
67  name)/K
68 --- a/testdata/testoutput1
69 +++ b/testdata/testoutput1
70 @@ -8234,6 +8234,16 @@ MK: M
71      aaaabcde
72   0: aaaab
73   1: aaaab
74 +    
75 +/((?(R)a|(?1)))*/
76 +    aaa
77 + 0: aaa
78 + 1: a
79 +
80 +/((?(R)a|(?1)))+/
81 +    aaa
82 + 0: aaa
83 + 1: a
84  
85  /a(*:any 
86  name)/K