summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-11-15 10:28:09 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-11-15 10:28:09 +0000
commit0262eef3593e8a8a9d0c918a5f4a72ed67742d5f (patch)
tree296b059faec17ebb558e3696f65d3d490268b21d
parent71b0b00cc74b921fd44c9396ff16d60f85dc7301 (diff)
downloadpcre-0262eef3593e8a8a9d0c918a5f4a72ed67742d5f.tar.gz
Fix (?&) non-diagnosis bug and missing length check for (?&a) etc.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@268 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog5
-rw-r--r--pcre_compile.c17
-rw-r--r--pcre_internal.h2
-rw-r--r--pcreposix.c3
-rw-r--r--testdata/testinput26
-rw-r--r--testdata/testoutput29
6 files changed, 37 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8eef26c..7ca7f72 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,11 @@ Version 7.5 12-Nov-07
4. PCRECPP_STATIC was referenced in pcrecpp_internal.h, but nowhere was it
defined or documented. It seems to have been a typo for PCRE_STATIC, so
I have changed it.
+
+5. The construct (?&) was not diagnosed as a syntax error (it referenced the
+ first named subpattern) and a construct such as (?&a) would reference the
+ first named subpattern whose name started with "a" (in other words, the
+ length check was missing).
Version 7.4 21-Sep-07
diff --git a/pcre_compile.c b/pcre_compile.c
index cd51b4d..d160e1d 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -300,7 +300,8 @@ static const char error_texts[] =
"(*VERB) with an argument is not supported\0"
/* 60 */
"(*VERB) not recognized\0"
- "number is too big";
+ "number is too big\0"
+ "subpattern name expected after (?&";
/* Table to identify digits and hex digits. This is used when compiling
@@ -4535,6 +4536,11 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
if (lengthptr != NULL)
{
+ if (namelen == 0)
+ {
+ *errorcodeptr = ERR62;
+ goto FAILED;
+ }
if (*ptr != terminator)
{
*errorcodeptr = ERR42;
@@ -4548,14 +4554,19 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
recno = 0;
}
- /* In the real compile, seek the name in the table */
+ /* In the real compile, seek the name in the table. We check the name
+ first, and then check that we have reached the end of the name in the
+ table. That way, if the name that is longer than any in the table,
+ the comparison will fail without reading beyond the table entry. */
else
{
slot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
{
- if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
+ if (strncmp((char *)name, (char *)slot+2, namelen) == 0 &&
+ slot[2+namelen] == 0)
+ break;
slot += cd->name_entry_size;
}
diff --git a/pcre_internal.h b/pcre_internal.h
index 417c4bd..ca8749a 100644
--- a/pcre_internal.h
+++ b/pcre_internal.h
@@ -871,7 +871,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
- ERR60, ERR61 };
+ ERR60, ERR61, ERR62 };
/* The real format of the start of the pcre block; the index of names and the
code vector run on as long as necessary after the end. We store an explicit
diff --git a/pcreposix.c b/pcreposix.c
index 0f73774..545fbf9 100644
--- a/pcreposix.c
+++ b/pcreposix.c
@@ -124,7 +124,8 @@ static const int eint[] = {
REG_INVARG, /* inconsistent NEWLINE options */
REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */
REG_BADPAT, /* (?+ or (?- must be followed by a non-zero number */
- REG_BADPAT /* number is too big */
+ REG_BADPAT, /* number is too big */
+ REG_BADPAT /* subpattern name expected after (?& */
};
/* Table of texts corresponding to POSIX error codes */
diff --git a/testdata/testinput2 b/testdata/testinput2
index e0018b6..572bcf3 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -2535,4 +2535,10 @@ a random value. /Ix
/(*CRLF)(*BSR_ANYCRLF)(*CR)ab/I
+/(?<a>)(?&)/
+
+/(?<abc>)(?&a)/
+
+/(?<a>)(?&aaaaaaaaaaaaaaaaaaaaaaa)/
+
/ End of testinput2 /
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index 26cc5b1..6648221 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -9302,4 +9302,13 @@ Forced newline sequence: CR
First char = 'a'
Need char = 'b'
+/(?<a>)(?&)/
+Failed: subpattern name expected after (?& at offset 9
+
+/(?<abc>)(?&a)/
+Failed: reference to non-existent subpattern at offset 12
+
+/(?<a>)(?&aaaaaaaaaaaaaaaaaaaaaaa)/
+Failed: reference to non-existent subpattern at offset 32
+
/ End of testinput2 /