Fix crash in pcre2_substitute() with NULL match context.

This commit is contained in:
Philip.Hazel 2019-03-11 17:29:08 +00:00
parent 590f65f061
commit e85de98d0a
8 changed files with 70 additions and 40 deletions

View File

@ -2,8 +2,8 @@ Change Log for PCRE2
--------------------
Version 10.33-RC1 03-March-2019
-------------------------------
Version 10.33 11-March-2019
---------------------------
1. Added "allvector" to pcre2test to make it easy to check the part of the
ovector that shouldn't be changed, in particular after substitute and failed or
@ -12,7 +12,9 @@ partial matches.
2. Fix subject buffer overread in JIT when UTF is disabled and \X or \R has
a greater than 1 fixed quantifier. This issue was found by Yunho Kim.
3. Added support for callouts from pcre2_substitute().
3. Added support for callouts from pcre2_substitute(). After 10.33-RC1, but
prior to release, fixed a bug that caused a crash if pcre2_substitute() was
called with a NULL match context.
4. The POSIX functions are now all called pcre2_regcomp() etc., with wrapper
functions that use the standard POSIX names. However, in pcre2posix.h the POSIX

View File

@ -1450,8 +1450,10 @@ Testing substitute callouts
</b><br>
<P>
If the <b>substitute_callout</b> modifier is set, a substitution callout
function is set up. When it is called (after each substitution), details of the
the input and output strings are output. For example:
function is set up. The <b>null_context</b> modifier must not be set, because
the address of the callout function is passed in a match context. When the
callout function is called (after each substitution), details of the the input
and output strings are output. For example:
<pre>
/abc/g,replace=&#60;$0&#62;,substitute_callout
abcdefabcpqr
@ -1626,11 +1628,11 @@ Passing a NULL context
</b><br>
<P>
Normally, <b>pcre2test</b> passes a context block to <b>pcre2_match()</b>,
<b>pcre2_dfa_match()</b> or <b>pcre2_jit_match()</b>. If the <b>null_context</b>
modifier is set, however, NULL is passed. This is for testing that the matching
functions behave correctly in this case (they use default values). This
modifier cannot be used with the <b>find_limits</b> modifier or when testing the
substitution function.
<b>pcre2_dfa_match()</b>, <b>pcre2_jit_match()</b> or <b>pcre2_substitute()</b>.
If the <b>null_context</b> modifier is set, however, NULL is passed. This is for
testing that the matching and substitution functions behave correctly in this
case (they use default values). This modifier cannot be used with the
<b>find_limits</b> or <b>substitute_callout</b> modifiers.
</P>
<br><a name="SEC12" href="#TOC1">THE ALTERNATIVE MATCHING FUNCTION</a><br>
<P>
@ -2076,7 +2078,7 @@ Cambridge, England.
</P>
<br><a name="SEC21" href="#TOC1">REVISION</a><br>
<P>
Last updated: 11 February 2019
Last updated: 11 March 2019
<br>
Copyright &copy; 1997-2019 University of Cambridge.
<br>

View File

@ -1,4 +1,4 @@
.TH PCRE2TEST 1 "11 February 2019" "PCRE 10.33"
.TH PCRE2TEST 1 "11 March 2019" "PCRE 10.33"
.SH NAME
pcre2test - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@ -1417,8 +1417,10 @@ matching provokes an error return ("bad option value") from
.rs
.sp
If the \fBsubstitute_callout\fP modifier is set, a substitution callout
function is set up. When it is called (after each substitution), details of the
the input and output strings are output. For example:
function is set up. The \fBnull_context\fP modifier must not be set, because
the address of the callout function is passed in a match context. When the
callout function is called (after each substitution), details of the the input
and output strings are output. For example:
.sp
/abc/g,replace=<$0>,substitute_callout
abcdefabcpqr
@ -1587,11 +1589,11 @@ passing the replacement string as zero-terminated.
.rs
.sp
Normally, \fBpcre2test\fP passes a context block to \fBpcre2_match()\fP,
\fBpcre2_dfa_match()\fP or \fBpcre2_jit_match()\fP. If the \fBnull_context\fP
modifier is set, however, NULL is passed. This is for testing that the matching
functions behave correctly in this case (they use default values). This
modifier cannot be used with the \fBfind_limits\fP modifier or when testing the
substitution function.
\fBpcre2_dfa_match()\fP, \fBpcre2_jit_match()\fP or \fBpcre2_substitute()\fP.
If the \fBnull_context\fP modifier is set, however, NULL is passed. This is for
testing that the matching and substitution functions behave correctly in this
case (they use default values). This modifier cannot be used with the
\fBfind_limits\fP or \fBsubstitute_callout\fP modifiers.
.
.
.SH "THE ALTERNATIVE MATCHING FUNCTION"
@ -2057,6 +2059,6 @@ Cambridge, England.
.rs
.sp
.nf
Last updated: 11 February 2019
Last updated: 11 March 2019
Copyright (c) 1997-2019 University of Cambridge.
.fi

View File

@ -1303,8 +1303,10 @@ SUBJECT MODIFIERS
Testing substitute callouts
If the substitute_callout modifier is set, a substitution callout func-
tion is set up. When it is called (after each substitution), details of
the the input and output strings are output. For example:
tion is set up. The null_context modifier must not be set, because the
address of the callout function is passed in a match context. When the
callout function is called (after each substitution), details of the
the input and output strings are output. For example:
/abc/g,replace=<$0>,substitute_callout
abcdefabcpqr
@ -1457,11 +1459,11 @@ SUBJECT MODIFIERS
Passing a NULL context
Normally, pcre2test passes a context block to pcre2_match(),
pcre2_dfa_match() or pcre2_jit_match(). If the null_context modifier is
set, however, NULL is passed. This is for testing that the matching
functions behave correctly in this case (they use default values). This
modifier cannot be used with the find_limits modifier or when testing
the substitution function.
pcre2_dfa_match(), pcre2_jit_match() or pcre2_substitute(). If the
null_context modifier is set, however, NULL is passed. This is for
testing that the matching and substitution functions behave correctly
in this case (they use default values). This modifier cannot be used
with the find_limits or substitute_callout modifiers.
THE ALTERNATIVE MATCHING FUNCTION
@ -1888,5 +1890,5 @@ AUTHOR
REVISION
Last updated: 11 February 2019
Last updated: 11 March 2019
Copyright (c) 1997-2019 University of Cambridge.

View File

@ -839,7 +839,7 @@ do
remembered. Do the callout if there is one and we have done an actual
replacement. */
if (!overflowed && mcontext->substitute_callout != NULL)
if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)
{
scb.subscount = subs;
scb.output_offsets[1] = buff_offset;

View File

@ -1388,13 +1388,13 @@ are supported. */
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
if (test_mode == PCRE8_MODE) \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h, \
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \
else if (test_mode == PCRE16_MODE) \
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h, \
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \
else \
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h, \
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
@ -1866,11 +1866,11 @@ the three different cases. */
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
G(g,BITONE),G(h,BITONE),(G(PCRE2_SPTR,BITONE))i,j, \
G(g,BITONE),h,(G(PCRE2_SPTR,BITONE))i,j, \
(G(PCRE2_UCHAR,BITONE) *)k,l); \
else \
a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
G(g,BITTWO),G(h,BITTWO),(G(PCRE2_SPTR,BITTWO))i,j, \
G(g,BITTWO),h,(G(PCRE2_SPTR,BITTWO))i,j, \
(G(PCRE2_UCHAR,BITTWO) *)k,l)
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
@ -2068,7 +2068,7 @@ the three different cases. */
pcre2_set_substitute_callout_8(G(a,8), \
(int (*)(pcre2_substitute_callout_block_8 *, void *))b,c)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h, \
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e)
@ -2175,7 +2175,7 @@ the three different cases. */
pcre2_set_substitute_callout_16(G(a,16), \
(int (*)(pcre2_substitute_callout_block_16 *, void *))b,c)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h, \
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e)
@ -2282,7 +2282,7 @@ the three different cases. */
pcre2_set_substitute_callout_32(G(a,32), \
(int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h, \
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)
@ -6939,11 +6939,13 @@ for (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++)
if (pat_patctl.replacement[0] != 0)
{
if ((dat_datctl.control & CTL_NULLCONTEXT) != 0)
if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0 &&
(dat_datctl.control & CTL_NULLCONTEXT) != 0)
{
fprintf(outfile, "** Replacement text is not supported with null_context.\n");
fprintf(outfile, "** Replacement callouts are not supported with null_context.\n");
return PR_OK;
}
if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)
fprintf(outfile, "** Ignored with replacement text: allcaptures\n");
}
@ -7335,7 +7337,7 @@ if (dat_datctl.replacement[0] != 0)
}
PCRE2_SUBSTITUTE(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,
dat_datctl.options|xoptions, match_data, dat_context,
dat_datctl.options|xoptions, match_data, use_dat_context,
rbuffer, rlen, nbuffer, &nsize);
if (rc < 0)

8
testdata/testinput2 vendored
View File

@ -5579,4 +5579,12 @@ a)"xI
/(*ACCEPT:XX)^abc/I
/abc/replace=xyz
abc\=null_context
/abc/replace=xyz,substitute_callout
abc
\= Expect error message
abc\=null_context
# End of testinput2

12
testdata/testoutput2 vendored
View File

@ -16922,6 +16922,18 @@ Subject length lower bound = 3
Capture group count = 0
Subject length lower bound = 0
/abc/replace=xyz
abc\=null_context
1: xyz
/abc/replace=xyz,substitute_callout
abc
1(1) Old 0 3 "abc" New 0 3 "xyz"
1: xyz
\= Expect error message
abc\=null_context
** Replacement callouts are not supported with null_context.
# End of testinput2
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
Error -62: bad serialized data