Fix crash in pcre2_substitute() with NULL match context.
This commit is contained in:
parent
590f65f061
commit
e85de98d0a
|
@ -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
|
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
|
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
|
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.
|
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
|
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
|
functions that use the standard POSIX names. However, in pcre2posix.h the POSIX
|
||||||
|
|
|
@ -1450,8 +1450,10 @@ Testing substitute callouts
|
||||||
</b><br>
|
</b><br>
|
||||||
<P>
|
<P>
|
||||||
If the <b>substitute_callout</b> modifier is set, a substitution callout
|
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
|
function is set up. The <b>null_context</b> modifier must not be set, because
|
||||||
the input and output strings are output. For example:
|
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>
|
<pre>
|
||||||
/abc/g,replace=<$0>,substitute_callout
|
/abc/g,replace=<$0>,substitute_callout
|
||||||
abcdefabcpqr
|
abcdefabcpqr
|
||||||
|
@ -1626,11 +1628,11 @@ Passing a NULL context
|
||||||
</b><br>
|
</b><br>
|
||||||
<P>
|
<P>
|
||||||
Normally, <b>pcre2test</b> passes a context block to <b>pcre2_match()</b>,
|
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>
|
<b>pcre2_dfa_match()</b>, <b>pcre2_jit_match()</b> or <b>pcre2_substitute()</b>.
|
||||||
modifier is set, however, NULL is passed. This is for testing that the matching
|
If the <b>null_context</b> modifier is set, however, NULL is passed. This is for
|
||||||
functions behave correctly in this case (they use default values). This
|
testing that the matching and substitution functions behave correctly in this
|
||||||
modifier cannot be used with the <b>find_limits</b> modifier or when testing the
|
case (they use default values). This modifier cannot be used with the
|
||||||
substitution function.
|
<b>find_limits</b> or <b>substitute_callout</b> modifiers.
|
||||||
</P>
|
</P>
|
||||||
<br><a name="SEC12" href="#TOC1">THE ALTERNATIVE MATCHING FUNCTION</a><br>
|
<br><a name="SEC12" href="#TOC1">THE ALTERNATIVE MATCHING FUNCTION</a><br>
|
||||||
<P>
|
<P>
|
||||||
|
@ -2076,7 +2078,7 @@ Cambridge, England.
|
||||||
</P>
|
</P>
|
||||||
<br><a name="SEC21" href="#TOC1">REVISION</a><br>
|
<br><a name="SEC21" href="#TOC1">REVISION</a><br>
|
||||||
<P>
|
<P>
|
||||||
Last updated: 11 February 2019
|
Last updated: 11 March 2019
|
||||||
<br>
|
<br>
|
||||||
Copyright © 1997-2019 University of Cambridge.
|
Copyright © 1997-2019 University of Cambridge.
|
||||||
<br>
|
<br>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.TH PCRE2TEST 1 "11 February 2019" "PCRE 10.33"
|
.TH PCRE2TEST 1 "11 March 2019" "PCRE 10.33"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pcre2test - a program for testing Perl-compatible regular expressions.
|
pcre2test - a program for testing Perl-compatible regular expressions.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -1417,8 +1417,10 @@ matching provokes an error return ("bad option value") from
|
||||||
.rs
|
.rs
|
||||||
.sp
|
.sp
|
||||||
If the \fBsubstitute_callout\fP modifier is set, a substitution callout
|
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
|
function is set up. The \fBnull_context\fP modifier must not be set, because
|
||||||
the input and output strings are output. For example:
|
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
|
.sp
|
||||||
/abc/g,replace=<$0>,substitute_callout
|
/abc/g,replace=<$0>,substitute_callout
|
||||||
abcdefabcpqr
|
abcdefabcpqr
|
||||||
|
@ -1587,11 +1589,11 @@ passing the replacement string as zero-terminated.
|
||||||
.rs
|
.rs
|
||||||
.sp
|
.sp
|
||||||
Normally, \fBpcre2test\fP passes a context block to \fBpcre2_match()\fP,
|
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
|
\fBpcre2_dfa_match()\fP, \fBpcre2_jit_match()\fP or \fBpcre2_substitute()\fP.
|
||||||
modifier is set, however, NULL is passed. This is for testing that the matching
|
If the \fBnull_context\fP modifier is set, however, NULL is passed. This is for
|
||||||
functions behave correctly in this case (they use default values). This
|
testing that the matching and substitution functions behave correctly in this
|
||||||
modifier cannot be used with the \fBfind_limits\fP modifier or when testing the
|
case (they use default values). This modifier cannot be used with the
|
||||||
substitution function.
|
\fBfind_limits\fP or \fBsubstitute_callout\fP modifiers.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.SH "THE ALTERNATIVE MATCHING FUNCTION"
|
.SH "THE ALTERNATIVE MATCHING FUNCTION"
|
||||||
|
@ -2057,6 +2059,6 @@ Cambridge, England.
|
||||||
.rs
|
.rs
|
||||||
.sp
|
.sp
|
||||||
.nf
|
.nf
|
||||||
Last updated: 11 February 2019
|
Last updated: 11 March 2019
|
||||||
Copyright (c) 1997-2019 University of Cambridge.
|
Copyright (c) 1997-2019 University of Cambridge.
|
||||||
.fi
|
.fi
|
||||||
|
|
|
@ -1303,8 +1303,10 @@ SUBJECT MODIFIERS
|
||||||
Testing substitute callouts
|
Testing substitute callouts
|
||||||
|
|
||||||
If the substitute_callout modifier is set, a substitution callout func-
|
If the substitute_callout modifier is set, a substitution callout func-
|
||||||
tion is set up. When it is called (after each substitution), details of
|
tion is set up. The null_context modifier must not be set, because the
|
||||||
the the input and output strings are output. For example:
|
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
|
/abc/g,replace=<$0>,substitute_callout
|
||||||
abcdefabcpqr
|
abcdefabcpqr
|
||||||
|
@ -1457,11 +1459,11 @@ SUBJECT MODIFIERS
|
||||||
Passing a NULL context
|
Passing a NULL context
|
||||||
|
|
||||||
Normally, pcre2test passes a context block to pcre2_match(),
|
Normally, pcre2test passes a context block to pcre2_match(),
|
||||||
pcre2_dfa_match() or pcre2_jit_match(). If the null_context modifier is
|
pcre2_dfa_match(), pcre2_jit_match() or pcre2_substitute(). If the
|
||||||
set, however, NULL is passed. This is for testing that the matching
|
null_context modifier is set, however, NULL is passed. This is for
|
||||||
functions behave correctly in this case (they use default values). This
|
testing that the matching and substitution functions behave correctly
|
||||||
modifier cannot be used with the find_limits modifier or when testing
|
in this case (they use default values). This modifier cannot be used
|
||||||
the substitution function.
|
with the find_limits or substitute_callout modifiers.
|
||||||
|
|
||||||
|
|
||||||
THE ALTERNATIVE MATCHING FUNCTION
|
THE ALTERNATIVE MATCHING FUNCTION
|
||||||
|
@ -1888,5 +1890,5 @@ AUTHOR
|
||||||
|
|
||||||
REVISION
|
REVISION
|
||||||
|
|
||||||
Last updated: 11 February 2019
|
Last updated: 11 March 2019
|
||||||
Copyright (c) 1997-2019 University of Cambridge.
|
Copyright (c) 1997-2019 University of Cambridge.
|
||||||
|
|
|
@ -839,7 +839,7 @@ do
|
||||||
remembered. Do the callout if there is one and we have done an actual
|
remembered. Do the callout if there is one and we have done an actual
|
||||||
replacement. */
|
replacement. */
|
||||||
|
|
||||||
if (!overflowed && mcontext->substitute_callout != NULL)
|
if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)
|
||||||
{
|
{
|
||||||
scb.subscount = subs;
|
scb.subscount = subs;
|
||||||
scb.output_offsets[1] = buff_offset;
|
scb.output_offsets[1] = buff_offset;
|
||||||
|
|
|
@ -1388,13 +1388,13 @@ are supported. */
|
||||||
|
|
||||||
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
if (test_mode == PCRE8_MODE) \
|
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); \
|
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \
|
||||||
else if (test_mode == PCRE16_MODE) \
|
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); \
|
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \
|
||||||
else \
|
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)
|
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
|
||||||
|
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#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) \
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||||
a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
|
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); \
|
(G(PCRE2_UCHAR,BITONE) *)k,l); \
|
||||||
else \
|
else \
|
||||||
a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
|
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)
|
(G(PCRE2_UCHAR,BITTWO) *)k,l)
|
||||||
|
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#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), \
|
pcre2_set_substitute_callout_8(G(a,8), \
|
||||||
(int (*)(pcre2_substitute_callout_block_8 *, void *))b,c)
|
(int (*)(pcre2_substitute_callout_block_8 *, void *))b,c)
|
||||||
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
#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)
|
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#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)
|
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), \
|
pcre2_set_substitute_callout_16(G(a,16), \
|
||||||
(int (*)(pcre2_substitute_callout_block_16 *, void *))b,c)
|
(int (*)(pcre2_substitute_callout_block_16 *, void *))b,c)
|
||||||
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
#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)
|
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#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)
|
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), \
|
pcre2_set_substitute_callout_32(G(a,32), \
|
||||||
(int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)
|
(int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)
|
||||||
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
#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)
|
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#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)
|
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 (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;
|
return PR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)
|
if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)
|
||||||
fprintf(outfile, "** Ignored with replacement text: allcaptures\n");
|
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,
|
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);
|
rbuffer, rlen, nbuffer, &nsize);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|
|
@ -5579,4 +5579,12 @@ a)"xI
|
||||||
|
|
||||||
/(*ACCEPT:XX)^abc/I
|
/(*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
|
# End of testinput2
|
||||||
|
|
|
@ -16922,6 +16922,18 @@ Subject length lower bound = 3
|
||||||
Capture group count = 0
|
Capture group count = 0
|
||||||
Subject length lower bound = 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
|
# End of testinput2
|
||||||
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
|
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
|
||||||
Error -62: bad serialized data
|
Error -62: bad serialized data
|
||||||
|
|
Loading…
Reference in New Issue