Revision: 498
http://vcs.pcre.org/viewvc?view=rev&revision=498
Author: ph10
Date: 2010-03-03 19:29:38 +0000 (Wed, 03 Mar 2010)
Log Message:
-----------
Fix missing data in coptable and poptable vectors; add compile-time checks for
their lengths.
Modified Paths:
--------------
code/trunk/ChangeLog
code/trunk/pcre_dfa_exec.c
code/trunk/pcre_internal.h
code/trunk/pcre_printint.src
code/trunk/pcretest.c
Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog 2010-03-03 12:01:00 UTC (rev 497)
+++ code/trunk/ChangeLog 2010-03-03 19:29:38 UTC (rev 498)
@@ -24,6 +24,11 @@
variables to point to external functions. For these systems, therefore,
pcre_malloc etc. are now initialized to local functions that call the
relevant global functions.
+
+7. There were two entries missing in the vectors called coptable and poptable
+ in pcre_dfa_exec.c. This could lead to memory accesses outsize the vectors.
+ I've fixed the data, and added a kludgy way of testing at compile time that
+ the lengths are correct (equal to the number of opcodes).
Version 8.01 19-Jan-2010
Modified: code/trunk/pcre_dfa_exec.c
===================================================================
--- code/trunk/pcre_dfa_exec.c 2010-03-03 12:01:00 UTC (rev 497)
+++ code/trunk/pcre_dfa_exec.c 2010-03-03 19:29:38 UTC (rev 498)
@@ -118,8 +118,9 @@
0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
0, 0, 0, /* Any, AllAny, Anybyte */
- 0, 0, 0, /* NOTPROP, PROP, EXTUNI */
+ 0, 0, /* \P, \p */
0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
+ 0, /* \X */
0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */
1, /* Char */
1, /* Charnc */
@@ -156,8 +157,8 @@
0, /* Reverse */
0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */
0, 0, 0, /* SBRA, SCBRA, SCOND */
- 0, /* CREF */
- 0, /* RREF */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
0, /* DEF */
0, 0, /* BRAZERO, BRAMINZERO */
0, 0, 0, 0, /* PRUNE, SKIP, THEN, COMMIT */
@@ -174,8 +175,9 @@
0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
1, 1, 1, /* Any, AllAny, Anybyte */
- 1, 1, 1, /* NOTPROP, PROP, EXTUNI */
+ 1, 1, /* \P, \p */
1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
+ 1, /* \X */
0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */
1, /* Char */
1, /* Charnc */
@@ -212,8 +214,8 @@
0, /* Reverse */
0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */
0, 0, 0, /* SBRA, SCBRA, SCOND */
- 0, /* CREF */
- 0, /* RREF */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
0, /* DEF */
0, 0, /* BRAZERO, BRAMINZERO */
0, 0, 0, 0, /* PRUNE, SKIP, THEN, COMMIT */
@@ -706,6 +708,18 @@
switch (codevalue)
{
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors coptable or poptable, which are indexed by
+ opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work
+ in the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(coptable) == OP_TABLE_LENGTH) &&
+ (sizeof(poptable) == OP_TABLE_LENGTH)):
+ break;
/* ========================================================================== */
/* Reached a closing bracket. If not at the end of the pattern, carry
Modified: code/trunk/pcre_internal.h
===================================================================
--- code/trunk/pcre_internal.h 2010-03-03 12:01:00 UTC (rev 497)
+++ code/trunk/pcre_internal.h 2010-03-03 19:29:38 UTC (rev 498)
@@ -1391,7 +1391,13 @@
/* This is used to skip a subpattern with a {0} quantifier */
- OP_SKIPZERO /* 114 */
+ OP_SKIPZERO, /* 114 */
+
+ /* This is not an opcode, but is used to check that tables indexed by opcode
+ are the correct length, in order to catch updating errors - there have been
+ some in the past. */
+
+ OP_TABLE_LENGTH
};
/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
@@ -1439,8 +1445,9 @@
1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
1, 1, 1, /* Any, AllAny, Anybyte */ \
- 3, 3, 1, /* NOTPROP, PROP, EXTUNI */ \
+ 3, 3, /* \P, \p */ \
1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
+ 1, /* \X */ \
1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \
2, /* Char - the minimum length */ \
2, /* Charnc - the minimum length */ \
Modified: code/trunk/pcre_printint.src
===================================================================
--- code/trunk/pcre_printint.src 2010-03-03 12:01:00 UTC (rev 497)
+++ code/trunk/pcre_printint.src 2010-03-03 19:29:38 UTC (rev 498)
@@ -190,6 +190,25 @@
switch(*code)
{
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors OP_names or _pcre_OP_lengths, which are indexed
+ by opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work in
+ the C preprocessor. We do this while compiling pcretest, because that
+ #includes pcre_tables.c, which holds _pcre_OP_lengths. We can't do this
+ when building pcre_compile.c with PCRE_DEBUG set, because it doesn't then
+ know the size of _pcre_OP_lengths. */
+
+#ifdef COMPILING_PCRETEST
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
+ (sizeof(_pcre_OP_lengths) == OP_TABLE_LENGTH)):
+ break;
+#endif
+/* ========================================================================== */
+
case OP_END:
fprintf(f, " %s\n", OP_names[*code]);
fprintf(f, "------------------------------------------------------------------\n");
Modified: code/trunk/pcretest.c
===================================================================
--- code/trunk/pcretest.c 2010-03-03 12:01:00 UTC (rev 497)
+++ code/trunk/pcretest.c 2010-03-03 19:29:38 UTC (rev 498)
@@ -118,19 +118,20 @@
/* We also need the pcre_printint() function for printing out compiled
patterns. This function is in a separate file so that it can be included in
-pcre_compile.c when that module is compiled with debugging enabled.
+pcre_compile.c when that module is compiled with debugging enabled. It needs to
+know which case is being compiled. */
-The definition of the macro PRINTABLE, which determines whether to print an
+#define COMPILING_PCRETEST
+#include "pcre_printint.src"
+
+/* The definition of the macro PRINTABLE, which determines whether to print an
output character as-is or as a hex value when showing compiled patterns, is
-contained in this file. We uses it here also, in cases when the locale has not
-been explicitly changed, so as to get consistent output from systems that
-differ in their output from isprint() even in the "C" locale. */
+contained in the printint.src file. We uses it here also, in cases when the
+locale has not been explicitly changed, so as to get consistent output from
+systems that differ in their output from isprint() even in the "C" locale. */
-#include "pcre_printint.src"
-
#define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))
-
/* It is possible to compile this test program without including support for
testing the POSIX interface, though this is not available via the standard
Makefile. */