summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-11-22 11:23:43 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-11-22 11:23:43 +0000
commit3d74632d426e8db6d5cb93e4c3fa5048f9c44e0c (patch)
tree17cd2bc781176541ece399a5130c8ea3d07d2814
parent130da81a5142a5cef80543ae5b64167229c23432 (diff)
downloadpcre-3d74632d426e8db6d5cb93e4c3fa5048f9c44e0c.tar.gz
Test for workspace overflow with forward reference data.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@760 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog4
-rw-r--r--pcre_compile.c20
-rw-r--r--pcre_internal.h2
-rw-r--r--pcreposix.c1
-rw-r--r--testdata/testinput24
-rw-r--r--testdata/testoutput25
6 files changed, 33 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index d9aed78..65ca77c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -54,6 +54,10 @@ Version 8.21
14. Perl does not support \N without a following name in a [] class; PCRE now
also gives an error.
+
+15. If a forward reference was repeated with an upper limit of around 2000,
+ it caused the error "internal error: overran compiling workspace". This
+ is now checked, and causes "too many forward references" instead.
Version 8.20 21-Oct-2011
diff --git a/pcre_compile.c b/pcre_compile.c
index 4a63e69..a5c6cea 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -413,6 +413,7 @@ static const char error_texts[] =
/* 70 */
"internal error: unknown opcode in find_fixedlength()\0"
"\\N is not supported in a class\0"
+ "too many forward references\0"
;
/* Table to identify digits and hex digits. This is used when compiling
@@ -4895,6 +4896,11 @@ for (;; ptr++)
memcpy(code, previous, len);
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
{
+ if (cd->hwm >= cd->start_workspace + WORK_SIZE_CHECK)
+ {
+ *errorcodeptr = ERR72;
+ goto FAILED;
+ }
PUT(cd->hwm, 0, GET(hc, 0) + len);
cd->hwm += LINK_SIZE;
}
@@ -4922,7 +4928,7 @@ for (;; ptr++)
add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
a 64-bit integer type when available, otherwise double. */
-
+
if (lengthptr != NULL && repeat_max > 0)
{
int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
@@ -4962,6 +4968,11 @@ for (;; ptr++)
memcpy(code, previous, len);
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
{
+ if (cd->hwm >= cd->start_workspace + WORK_SIZE_CHECK)
+ {
+ *errorcodeptr = ERR72;
+ goto FAILED;
+ }
PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
cd->hwm += LINK_SIZE;
}
@@ -5977,8 +5988,13 @@ for (;; ptr++)
/* 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. Then remember the forward reference. */
-
+
called = cd->start_code + recno;
+ if (cd->hwm >= cd->start_workspace + WORK_SIZE_CHECK)
+ {
+ *errorcodeptr = ERR72;
+ goto FAILED;
+ }
PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
}
diff --git a/pcre_internal.h b/pcre_internal.h
index 3655349..e158bda 100644
--- a/pcre_internal.h
+++ b/pcre_internal.h
@@ -1665,7 +1665,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
- ERR70, ERR71, ERRCOUNT };
+ ERR70, ERR71, ERR72, ERRCOUNT };
/* 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 b5f9d0e..7379917 100644
--- a/pcreposix.c
+++ b/pcreposix.c
@@ -156,6 +156,7 @@ static const int eint[] = {
/* 70 */
REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */
REG_BADPAT, /* \N is not supported in a class */
+ REG_BADPAT, /* too many forward references */
};
/* Table of texts corresponding to POSIX error codes */
diff --git a/testdata/testinput2 b/testdata/testinput2
index c7c5c16..39957e3 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -4014,4 +4014,8 @@ AbcdCBefgBhiBqz
/a[B-\Nc]/
+/(a)(?2){0,1999}?(b)/
+
+/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/
+
/-- End of testinput2 --/
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index ba2f53c..20bc52f 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -12600,4 +12600,9 @@ Failed: \N is not supported in a class at offset 3
/a[B-\Nc]/
Failed: \N is not supported in a class at offset 5
+/(a)(?2){0,1999}?(b)/
+Failed: too many forward references at offset 15
+
+/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/
+
/-- End of testinput2 --/