Detect and warn when pcre2test is linked with an alien POSIX library.

This commit is contained in:
Philip.Hazel 2016-02-03 15:22:01 +00:00
parent 9f75a0f92a
commit 26f610a1e5
4 changed files with 45 additions and 8 deletions

View File

@ -42,6 +42,18 @@ instead of later. Previously the pre-scan carried on and could give a
misleading incorrect error message. For example, /(?J)(?'a'))(?'a')/ gave a
message about invalid duplicate group names.
10. It has happened that pcre2test was accidentally linked with another POSIX
regex library instead of libpcre2-posix. In this situation, a call to regcomp()
(in the other library) may succeed, returning zero, but of course putting its
own data into the regex_t block. In one example the re_pcre2_code field was
left as NULL, which made pcre2test think it had not got a compiled POSIX regex,
so it treated the next line as another pattern line, resulting in a confusing
error message. A check has been added to pcre2test to see if the data returned
from a successful call of regcomp() are valid for PCRE2's regcomp(). If they
are not, an error message is output and the pcre2test run is abandoned. The
message points out the possibility of a mis-linking. Hopefully this will avoid
some head-scratching the next time this happens.
Version 10.21 12-January-2016
-----------------------------

View File

@ -209,7 +209,7 @@ if ((cflags & REG_UTF) != 0) options |= PCRE2_UTF;
if ((cflags & REG_UCP) != 0) options |= PCRE2_UCP;
if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY;
preg->cflags = cflags;
preg->re_cflags = cflags;
preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED,
options, &errorcode, &erroffset, NULL);
preg->re_erroffset = erroffset;
@ -275,7 +275,7 @@ if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE2_NOTEMPTY;
put captured strings, ensure that nmatch is zero. This will stop any attempt to
write to pmatch. */
if ((preg->cflags & REG_NOSUB) != 0 || pmatch == NULL) nmatch = 0;
if ((preg->re_cflags & REG_NOSUB) != 0 || pmatch == NULL) nmatch = 0;
/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings.
The man page from OS X says "REG_STARTEND affects only the location of the

View File

@ -98,7 +98,7 @@ typedef struct {
void *re_match_data;
size_t re_nsub;
size_t re_erroffset;
int cflags;
int re_cflags;
} regex_t;
/* The structure in which a captured offset is returned. */

View File

@ -2982,7 +2982,7 @@ for (;;)
the buffer or reached the end of the file. We can detect the former by
checking that the string fills the buffer, and the latter by feof(). If
neither of these is true, it means we read a binary zero which has caused
strlen() to give a short length. This is a hard error because pcre2test
strlen() to give a short length. This is a hard error because pcre2test
expects to work with C strings. */
if (!INTERACTIVE(f) && dlen < rlen - 1 && !feof(f))
@ -4701,8 +4701,7 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
if (msg[0] == 0) fprintf(outfile, "\n");
/* Translate PCRE2 options to POSIX options and then compile. On success, set
up a match_data block to be used for all matches. */
/* Translate PCRE2 options to POSIX options and then compile. */
if (utf) cflags |= REG_UTF;
if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) cflags |= REG_NOSUB;
@ -4713,7 +4712,10 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
rc = regcomp(&preg, (char *)pbuffer8, cflags);
if (rc != 0) /* Failure */
/* Compiling failed */
if (rc != 0)
{
size_t bsize, usize;
@ -4735,6 +4737,29 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
}
return PR_SKIP;
}
/* Compiling succeeded. Check that the values in the preg block are sensible.
It can happen that pcre2test is accidentally linked with a different POSIX
library which succeeds, but of course puts different things into preg. In
this situation, calling regfree() may cause a segfault (or invalid free() in
valgrind), so ensure that preg.re_pcre2_code is NULL, which suppresses the
calling of regfree() on exit. */
if (preg.re_pcre2_code == NULL ||
((pcre2_real_code_8 *)preg.re_pcre2_code)->magic_number != MAGIC_NUMBER ||
((pcre2_real_code_8 *)preg.re_pcre2_code)->top_bracket != preg.re_nsub ||
preg.re_match_data == NULL ||
preg.re_cflags != cflags)
{
fprintf(outfile,
"** The regcomp() function returned zero (success), but the values set\n"
"** in the preg block are not valid for PCRE2. Check that pcre2test is\n"
"** linked with PCRE2's pcre2posix module (-lpcre2-posix) and not with\n"
"** some other POSIX regex library.\n**\n");
preg.re_pcre2_code = NULL;
return PR_ABEND;
}
return PR_OK;
#endif /* SUPPORT_PCRE2_8 */
}
@ -7450,7 +7475,7 @@ if (jit_stack != NULL)
#ifdef SUPPORT_PCRE2_8
#undef BITS
#define BITS 8
regfree(&preg);
if (preg.re_pcre2_code != NULL) regfree(&preg);
FREECONTEXTS;
#endif