Line 0
Link Here
|
|
|
1 |
Index: pcre_internal.h |
2 |
=================================================================== |
3 |
--- pcre_internal.h (revision 1584) |
4 |
+++ pcre_internal.h (revision 1585) |
5 |
@@ -2454,6 +2454,7 @@ |
6 |
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ |
7 |
BOOL check_lookbehind; /* Lookbehinds need later checking */ |
8 |
BOOL dupnames; /* Duplicate names exist */ |
9 |
+ BOOL dupgroups; /* Duplicate groups exist: (?| found */ |
10 |
BOOL iscondassert; /* Next assert is a condition */ |
11 |
int nltype; /* Newline type */ |
12 |
int nllen; /* Newline string length */ |
13 |
Index: pcre_compile.c |
14 |
=================================================================== |
15 |
--- pcre_compile.c (revision 1584) |
16 |
+++ pcre_compile.c (revision 1585) |
17 |
@@ -6668,6 +6668,7 @@ |
18 |
/* ------------------------------------------------------------ */ |
19 |
case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ |
20 |
reset_bracount = TRUE; |
21 |
+ cd->dupgroups = TRUE; /* Record (?| encountered */ |
22 |
/* Fall through */ |
23 |
|
24 |
/* ------------------------------------------------------------ */ |
25 |
@@ -7178,7 +7179,8 @@ |
26 |
if (lengthptr != NULL) |
27 |
{ |
28 |
named_group *ng; |
29 |
- |
30 |
+ recno = 0; |
31 |
+ |
32 |
if (namelen == 0) |
33 |
{ |
34 |
*errorcodeptr = ERR62; |
35 |
@@ -7195,32 +7197,6 @@ |
36 |
goto FAILED; |
37 |
} |
38 |
|
39 |
- /* The name table does not exist in the first pass; instead we must |
40 |
- scan the list of names encountered so far in order to get the |
41 |
- number. If the name is not found, set the value to 0 for a forward |
42 |
- reference. */ |
43 |
- |
44 |
- recno = 0; |
45 |
- ng = cd->named_groups; |
46 |
- for (i = 0; i < cd->names_found; i++, ng++) |
47 |
- { |
48 |
- if (namelen == ng->length && |
49 |
- STRNCMP_UC_UC(name, ng->name, namelen) == 0) |
50 |
- { |
51 |
- open_capitem *oc; |
52 |
- recno = ng->number; |
53 |
- if (is_recurse) break; |
54 |
- for (oc = cd->open_caps; oc != NULL; oc = oc->next) |
55 |
- { |
56 |
- if (oc->number == recno) |
57 |
- { |
58 |
- oc->flag = TRUE; |
59 |
- break; |
60 |
- } |
61 |
- } |
62 |
- } |
63 |
- } |
64 |
- |
65 |
/* Count named back references. */ |
66 |
|
67 |
if (!is_recurse) cd->namedrefcount++; |
68 |
@@ -7242,7 +7218,44 @@ |
69 |
issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance |
70 |
only mode, we finesse the bug by allowing more memory always. */ |
71 |
|
72 |
- /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE; |
73 |
+ *lengthptr += 2 + 2*LINK_SIZE; |
74 |
+ |
75 |
+ /* It is even worse than that. The current reference may be to an |
76 |
+ existing named group with a different number (so apparently not |
77 |
+ recursive) but which later on is also attached to a group with the |
78 |
+ current number. This can only happen if $(| has been previous |
79 |
+ encountered. In that case, we allow yet more memory, just in case. |
80 |
+ (Again, this is fixed "properly" in PCRE2. */ |
81 |
+ |
82 |
+ if (cd->dupgroups) *lengthptr += 2 + 2*LINK_SIZE; |
83 |
+ |
84 |
+ /* Otherwise, check for recursion here. The name table does not exist |
85 |
+ in the first pass; instead we must scan the list of names encountered |
86 |
+ so far in order to get the number. If the name is not found, leave |
87 |
+ the value of recno as 0 for a forward reference. */ |
88 |
+ |
89 |
+ else |
90 |
+ { |
91 |
+ ng = cd->named_groups; |
92 |
+ for (i = 0; i < cd->names_found; i++, ng++) |
93 |
+ { |
94 |
+ if (namelen == ng->length && |
95 |
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0) |
96 |
+ { |
97 |
+ open_capitem *oc; |
98 |
+ recno = ng->number; |
99 |
+ if (is_recurse) break; |
100 |
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next) |
101 |
+ { |
102 |
+ if (oc->number == recno) |
103 |
+ { |
104 |
+ oc->flag = TRUE; |
105 |
+ break; |
106 |
+ } |
107 |
+ } |
108 |
+ } |
109 |
+ } |
110 |
+ } |
111 |
} |
112 |
|
113 |
/* In the real compile, search the name table. We check the name |
114 |
@@ -7289,8 +7302,6 @@ |
115 |
for (i++; i < cd->names_found; i++) |
116 |
{ |
117 |
if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break; |
118 |
- |
119 |
- |
120 |
count++; |
121 |
cslot += cd->name_entry_size; |
122 |
} |
123 |
@@ -9239,6 +9250,7 @@ |
124 |
cd->name_entry_size = 0; |
125 |
cd->name_table = NULL; |
126 |
cd->dupnames = FALSE; |
127 |
+cd->dupgroups = FALSE; |
128 |
cd->namedrefcount = 0; |
129 |
cd->start_code = cworkspace; |
130 |
cd->hwm = cworkspace; |
131 |
@@ -9273,7 +9285,7 @@ |
132 |
|
133 |
DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, |
134 |
(int)(cd->hwm - cworkspace))); |
135 |
- |
136 |
+ |
137 |
if (length > MAX_PATTERN_SIZE) |
138 |
{ |
139 |
errorcode = ERR20; |