|
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; |