summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornigel <nigel@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-02-24 21:38:17 +0000
committernigel <nigel@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-02-24 21:38:17 +0000
commit688871425cacb8bd84efbf423e15ea9fc204f280 (patch)
treed4373e90fd4185f69358f1c930edda118a08cdf7
parent91453b91d322e9d5812026584c2ecbe8f4cab52a (diff)
downloadpcre-688871425cacb8bd84efbf423e15ea9fc204f280.tar.gz
Load pcre-1.04 into code/trunk.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@11 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog25
-rw-r--r--internal.h4
-rw-r--r--pcre.34
-rw-r--r--pcre.c51
-rw-r--r--pcretest.c23
-rw-r--r--testoutput2
-rw-r--r--testoutput22
7 files changed, 80 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 881fc37..7fe6927 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,29 @@ ChangeLog for PCRE
------------------
+Version 1.04 19-Dec-97
+----------------------
+
+1. Corrected the man page, where some "const" qualifiers had been omitted.
+
+2. Made debugging output print "{0,xxx}" instead of just "{,xxx}" to agree with
+input syntax.
+
+3. Fixed memory leak which occurred when a regex with back references was
+matched with an offsets vector that wasn't big enough. The temporary memory
+that is used in this case wasn't being freed if the match failed.
+
+4. Tidied pcretest to ensure it frees memory that it gets.
+
+5. Temporary memory was being obtained in the case where the passed offsets
+vector was exactly big enough.
+
+6. Corrected definition of offsetof() from change 5 below.
+
+7. I had screwed up change 6 below and broken the rules for the use of
+setjmp(). Now fixed.
+
+
Version 1.03 18-Dec-97
----------------------
@@ -39,7 +62,7 @@ optimized code for single-character negative classes.
from gcc -Wall, and avoided calling it at all unless PCRE_EXTRA is used.
7. Constructs such as \d{8,} were compiling into the equivalent of
-\d{8}\d{65527} instead of \d{8}\d* which didn't make much difference to the
+\d{8}\d{0,65527} instead of \d{8}\d* which didn't make much difference to the
outcome, but in this particular case used more store than had been allocated,
which caused the bug to be discovered because it threw up an internal error.
diff --git a/internal.h b/internal.h
index c8d17e1..af0b42d 100644
--- a/internal.h
+++ b/internal.h
@@ -3,7 +3,7 @@
*************************************************/
-#define PCRE_VERSION "1.03 18-Dec-1997"
+#define PCRE_VERSION "1.04 22-Dec-1997"
/* This is a library of functions to support regular expressions whose syntax
@@ -57,7 +57,7 @@ define a macro for memmove() if USE_BCOPY is defined. */
Standard C system should have one. */
#ifndef offsetof
-#define offsetof(p_type,field) ((size_t)&(((p_type)0)->field))
+#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
#endif
/* Private options flags start at the most significant end of the two bytes.
diff --git a/pcre.3 b/pcre.3
index 8760ff9..dc6f6ca 100644
--- a/pcre.3
+++ b/pcre.3
@@ -8,12 +8,12 @@ pcre - Perl-compatible regular expressions.
.br
.B pcre *pcre_compile(const char *\fIpattern\fR, int \fIoptions\fR,
.ti +5n
-.B char **\fIerrptr\fR, int *\fIerroffset\fR);
+.B const char **\fIerrptr\fR, int *\fIerroffset\fR);
.PP
.br
.B pcre_extra *pcre_study(const pcre *\fIcode\fR, int \fIoptions\fR,
.ti +5n
-.B char **\fIerrptr\fR);
+.B const char **\fIerrptr\fR);
.PP
.br
.B int pcre_exec(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR,"
diff --git a/pcre.c b/pcre.c
index 542f9e2..43dee7c 100644
--- a/pcre.c
+++ b/pcre.c
@@ -2041,7 +2041,7 @@ while (code < code_end)
case OP_MINUPTO:
if (isprint(c = code[3])) printf(" %c{", c);
else printf(" \\x%02x{", c);
- if (*code != OP_EXACT) printf(",");
+ if (*code != OP_EXACT) printf("0,");
printf("%d}", (code[1] << 8) + code[2]);
if (*code == OP_MINUPTO) printf("?");
code += 3;
@@ -3299,14 +3299,21 @@ hide it in a separate function. This is called only when PCRE_EXTRA is set,
since it's needed only for the extension \X option, and with any luck, a good
compiler will spot the tail recursion and compile it efficiently.
-Arguments: The block containing the match data
-Returns: The return from setjump()
+Arguments:
+ eptr pointer in subject
+ ecode position in code
+ offset_top current top pointer
+ md pointer to "static" info for the match
+
+Returns: TRUE if matched
*/
-static int
-my_setjmp(match_data *match_block)
+static BOOL
+match_with_setjmp(const uschar *eptr, const uschar *ecode, int offset_top,
+ match_data *match_block)
{
-return setjmp(match_block->fail_env);
+return setjmp(match_block->fail_env) == 0 &&
+ match(eptr, ecode, offset_top, match_block);
}
@@ -3338,8 +3345,7 @@ int
pcre_exec(const pcre *external_re, const pcre_extra *external_extra,
const char *subject, int length, int options, int *offsets, int offsetcount)
{
-int resetcount;
-int ocount = offsetcount;
+int resetcount, ocount;
int first_char = -1;
match_data match_block;
const uschar *start_bits = NULL;
@@ -3347,6 +3353,7 @@ const uschar *start_match = (const uschar *)subject;
const uschar *end_subject;
const real_pcre *re = (const real_pcre *)external_re;
const real_pcre_extra *extra = (const real_pcre_extra *)external_extra;
+BOOL using_temporary_offsets = FALSE;
BOOL anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
BOOL startline = (re->options & PCRE_STARTLINE) != 0;
@@ -3375,15 +3382,16 @@ match_block.errorcode = PCRE_ERROR_NOMATCH; /* Default error */
/* If the expression has got more back references than the offsets supplied can
hold, we get a temporary bit of working store to use during the matching.
-Otherwise, we can use the vector supplied, rounding down the size of it to a
-multiple of 2. */
+Otherwise, we can use the vector supplied, rounding down its size to a multiple
+of 2. */
-ocount &= (-2);
-if (re->top_backref > 0 && re->top_backref + 1 >= ocount/2)
+ocount = offsetcount & (-2);
+if (re->top_backref > 0 && re->top_backref >= ocount/2)
{
ocount = re->top_backref * 2 + 2;
match_block.offset_vector = (pcre_malloc)(ocount * sizeof(int));
if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
+ using_temporary_offsets = TRUE;
DPRINTF(("Got memory to hold back references\n"));
}
else match_block.offset_vector = offsets;
@@ -3498,19 +3506,22 @@ do
it unless PCRE_EXTRA is set, since only in that case is the "cut" operation
enabled. */
- if (((re->options & PCRE_EXTRA) != 0 && my_setjmp(&match_block) != 0) ||
- !match(start_match, re->code, 2, &match_block))
- continue;
+ if ((re->options & PCRE_EXTRA) != 0)
+ {
+ if (!match_with_setjmp(start_match, re->code, 2, &match_block))
+ continue;
+ }
+ else if (!match(start_match, re->code, 2, &match_block)) continue;
/* Copy the offset information from temporary store if necessary */
- if (ocount != offsetcount)
+ if (using_temporary_offsets)
{
if (offsetcount >= 4)
{
memcpy(offsets + 2, match_block.offset_vector + 2,
(offsetcount - 2) * sizeof(int));
- DPRINTF(("Copied offsets; freeing temporary memory\n"));
+ DPRINTF(("Copied offsets from temporary memory\n"));
}
if (match_block.end_offset_top > offsetcount)
match_block.offset_overflow = TRUE;
@@ -3534,6 +3545,12 @@ while (!anchored &&
match_block.errorcode == PCRE_ERROR_NOMATCH &&
start_match++ < end_subject);
+if (using_temporary_offsets)
+ {
+ DPRINTF(("Freeing temporary memory\n"));
+ (pcre_free)(match_block.offset_vector);
+ }
+
DPRINTF((">>>> returning %d\n", match_block.errorcode));
return match_block.errorcode;
diff --git a/pcretest.c b/pcretest.c
index 5d5eec5..06e70e5 100644
--- a/pcretest.c
+++ b/pcretest.c
@@ -122,7 +122,7 @@ for(;;)
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
printf(" %s{", OP_names[code[3]]);
- if (*code != OP_TYPEEXACT) printf(",");
+ if (*code != OP_TYPEEXACT) printf("0,");
printf("%d}", (code[1] << 8) + code[2]);
if (*code == OP_TYPEMINUPTO) printf("?");
code += 3;
@@ -268,6 +268,7 @@ int timeit = 0;
int showinfo = 0;
int posix = 0;
int debug = 0;
+int done = 0;
unsigned char buffer[30000];
unsigned char dbuffer[1024];
@@ -326,7 +327,7 @@ fprintf(outfile, "PCRE version %s\n\n", pcre_version());
/* Main loop */
-for (;;)
+while (!done)
{
pcre *re = NULL;
pcre_extra *extra = NULL;
@@ -375,7 +376,8 @@ for (;;)
if (fgets((char *)pp, len, infile) == NULL)
{
fprintf(outfile, "** Unexpected EOF\n");
- goto END_OFF;
+ done = 1;
+ goto CONTINUE;
}
if (infile != stdin) fprintf(outfile, (char *)pp);
}
@@ -410,7 +412,7 @@ for (;;)
}
}
- /* Handle compiing via the POSIX interface, which doesn't support the
+ /* Handle compiling via the POSIX interface, which doesn't support the
timing, showing, or debugging options. */
if (posix || do_posix)
@@ -465,7 +467,10 @@ for (;;)
for (;;)
{
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
- goto END_OFF;
+ {
+ done = 1;
+ goto CONTINUE;
+ }
len = (int)strlen((char *)buffer);
while (len > 0 && isspace(buffer[len-1])) len--;
if (len == 0) break;
@@ -592,7 +597,11 @@ for (;;)
options = 0;
if (infile == stdin) printf(" data> ");
- if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) goto END_OFF;
+ if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
+ {
+ done = 1;
+ goto CONTINUE;
+ }
if (infile != stdin) fprintf(outfile, (char *)buffer);
len = (int)strlen((char *)buffer);
@@ -762,12 +771,12 @@ for (;;)
}
}
+ CONTINUE:
if (posix || do_posix) regfree(&preg);
if (re != NULL) free(re);
if (extra != NULL) free(extra);
}
-END_OFF:
fprintf(outfile, "\n");
return 0;
}
diff --git a/testoutput b/testoutput
index 3596b2a..3fac753 100644
--- a/testoutput
+++ b/testoutput
@@ -1,5 +1,5 @@
Testing Perl-Compatible Regular Expressions
-PCRE version 1.03 18-Dec-1997
+PCRE version 1.04 22-Dec-1997
/the quick brown fox/
the quick brown fox
diff --git a/testoutput2 b/testoutput2
index 23da939..75e20e0 100644
--- a/testoutput2
+++ b/testoutput2
@@ -1,5 +1,5 @@
Testing Perl-Compatible Regular Expressions
-PCRE version 1.03 18-Dec-1997
+PCRE version 1.04 22-Dec-1997
/(a)b|/
Identifying subpattern count = 1