https://bugs.exim.org/show_bug.cgi?id=1638 Index: pcre_compile.c =================================================================== --- a/pcre_compile.c (revision 1558) +++ b/pcre_compile.c (revision 1562) @@ -1799,7 +1799,7 @@ case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += PRIV(OP_lengths)[*cc]; + cc += 1 + LINK_SIZE; break; /* Skip over things that don't match chars */ @@ -7187,15 +7187,15 @@ 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; + for (oc = cd->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; break; - } - } - } + } + } + } } /* Count named back references. */ @@ -7207,6 +7207,19 @@ 16-bit data item. */ *lengthptr += IMM2_SIZE; + + /* If this is a forward reference and we are within a (?|...) group, + the reference may end up as the number of a group which we are + currently inside, that is, it could be a recursive reference. In the + real compile this will be picked up and the reference wrapped with + OP_ONCE to make it atomic, so we must space in case this occurs. */ + + /* In fact, this can happen for a non-forward reference because + another group with the same number might be created later. This + issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance + only mode, we finesse the bug by allowing more memory always. */ + + /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE; } /* In the real compile, search the name table. We check the name