summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2010-03-02 19:11:17 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2010-03-02 19:11:17 +0000
commit7b3e9efea8a44394eb40c2b5e98c1b5e1251bac6 (patch)
tree27e5553ba35c5234d2cece07dbaf3859a127756d
parent4fc29039d120ebe3e1f8d3c8bcfb741e42870fbc (diff)
downloadpcre-7b3e9efea8a44394eb40c2b5e98c1b5e1251bac6.tar.gz
Fix DEFINE bug for forward reference with a possessive quantifier.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@496 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog5
-rw-r--r--pcre_compile.c11
-rw-r--r--testdata/testinput24
-rw-r--r--testdata/testoutput240
4 files changed, 59 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 08e47b2..1199be2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,11 @@ Version 8.02 01-Mar-2010
4. On systems that do not have stdint.h (e.g. Solaris), check for and include
inttypes.h instead. This fixes a bug that was introduced by change 8.01/8.
+
+5. A pattern such as (?&t)*+(?(DEFINE)(?<t>.)) which has a possessive
+ quantifier applied to a forward-referencing subroutine call, could compile
+ incorrect code or give the error "internal error: previously-checked
+ referenced subpattern not found".
Version 8.01 19-Jan-2010
diff --git a/pcre_compile.c b/pcre_compile.c
index beae0e4..6ca1862 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -4430,7 +4430,12 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
+ /* Because we are moving code along, we must ensure that any
+ pending recursive references are updated. */
+
default:
+ *code = OP_END;
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf8, cd, save_hwm);
memmove(tempcode + 1+LINK_SIZE, tempcode, len);
code += 1 + LINK_SIZE;
len += 1 + LINK_SIZE;
@@ -5149,6 +5154,11 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
*errorcodeptr = ERR15;
goto FAILED;
}
+
+ /* Fudge the value of "called" so that when it is inserted as an
+ offset below, what it actually inserted is the reference number
+ of the group. */
+
called = cd->start_code + recno;
PUTINC(cd->hwm, 0, code + 2 + LINK_SIZE - cd->start_code);
}
@@ -6804,7 +6814,6 @@ if (reqbyte >= 0 &&
case when building a production library. */
#ifdef PCRE_DEBUG
-
printf("Length = %d top_bracket = %d top_backref = %d\n",
length, re->top_bracket, re->top_backref);
diff --git a/testdata/testinput2 b/testdata/testinput2
index 1c1a72d..5233183 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -3203,5 +3203,9 @@ a random value. /Ix
/^(ab(c\1)d|x){2}$/BZ
xabcxd
+
+/^(?&t)*+(?(DEFINE)(?<t>.))$/BZ
+
+/^(?&t)*(?(DEFINE)(?<t>.))$/BZ
/-- End of testinput2 --/
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index 4b27de0..8271ca6 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -10596,5 +10596,45 @@ No match
0: xabcxd
1: abcxd
2: cx
+
+/^(?&t)*+(?(DEFINE)(?<t>.))$/BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ Once
+ Brazero
+ Once
+ Recurse
+ KetRmax
+ Ket
+ Cond
+ Cond def
+ CBra 1
+ Any
+ Ket
+ Ket
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/^(?&t)*(?(DEFINE)(?<t>.))$/BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ Brazero
+ Once
+ Recurse
+ KetRmax
+ Cond
+ Cond def
+ CBra 1
+ Any
+ Ket
+ Ket
+ $
+ Ket
+ End
+------------------------------------------------------------------
/-- End of testinput2 --/