diff --git a/doc/pcre2api.3 b/doc/pcre2api.3 index 1caccbb..fe84fa4 100644 --- a/doc/pcre2api.3 +++ b/doc/pcre2api.3 @@ -3649,7 +3649,9 @@ needed is returned via \fIoutlengthptr\fP. Note that this does not happen by default. .P PCRE2_ERROR_NULL is returned if PCRE2_SUBSTITUTE_MATCHED is set but the -\fImatch_data\fP argument is NULL. +\fImatch_data\fP argument is NULL or if the \fIsubject\fP or \fIreplacement\fP +arguments are NULL. For backward compatibility reasons an exception is made for +the \fIreplacement\fP argument if the \fIrlength\fP argument is also 0. .P PCRE2_ERROR_BADREPLACEMENT is used for miscellaneous syntax errors in the replacement string, with more particular errors being PCRE2_ERROR_BADREPESCAPE diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index 060dc76..a97e071 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -3285,8 +3285,11 @@ rws->next = NULL; rws->size = RWS_BASE_SIZE; rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE; -/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated -subject string. */ +/* Plausibility checks */ + +if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; +if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL) + return PCRE2_ERROR_NULL; if (length == PCRE2_ZERO_TERMINATED) { @@ -3294,11 +3297,6 @@ if (length == PCRE2_ZERO_TERMINATED) was_zero_terminated = 1; } -/* Plausibility checks */ - -if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; -if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL) - return PCRE2_ERROR_NULL; if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE; if (start_offset > length) return PCRE2_ERROR_BADOFFSET; diff --git a/src/pcre2_match.c b/src/pcre2_match.c index f28cdbb..ea8ca5d 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE. /* #define DEBUG_SHOW_OPS */ /* #define DEBUG_SHOW_RMATCH */ -#ifdef DEBUG_FRAME_DISPLAY +#ifdef DEBUG_FRAMES_DISPLAY #include #endif @@ -6129,8 +6129,8 @@ PCRE2_UCHAR req_cu2 = 0; PCRE2_SPTR bumpalong_limit; PCRE2_SPTR end_subject; PCRE2_SPTR true_end_subject; -PCRE2_SPTR start_match = subject + start_offset; -PCRE2_SPTR req_cu_ptr = start_match - 1; +PCRE2_SPTR start_match; +PCRE2_SPTR req_cu_ptr; PCRE2_SPTR start_partial; PCRE2_SPTR match_partial; @@ -6170,9 +6170,14 @@ PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)] PCRE2_KEEP_UNINITIALIZED; mb->stack_frames = (heapframe *)stack_frames_vector; -/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated -subject string. */ +/* Plausibility checks */ +if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; +if (code == NULL || subject == NULL || match_data == NULL) + return PCRE2_ERROR_NULL; + +start_match = subject + start_offset; +req_cu_ptr = start_match - 1; if (length == PCRE2_ZERO_TERMINATED) { length = PRIV(strlen)(subject); @@ -6180,11 +6185,6 @@ if (length == PCRE2_ZERO_TERMINATED) } true_end_subject = end_subject = subject + length; -/* Plausibility checks */ - -if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; -if (code == NULL || subject == NULL || match_data == NULL) - return PCRE2_ERROR_NULL; if (start_offset > length) return PCRE2_ERROR_BADOFFSET; /* Check that the first field in the block is the magic number. */ diff --git a/src/pcre2_substitute.c b/src/pcre2_substitute.c index 981a106..7aefb60 100644 --- a/src/pcre2_substitute.c +++ b/src/pcre2_substitute.c @@ -260,6 +260,12 @@ PCRE2_UNSET, so as not to imply an offset in the replacement. */ if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0) return PCRE2_ERROR_BADOPTION; +/* Validate length and find the end of the replacement. */ +if (replacement == NULL && rlength > 0) return PCRE2_ERROR_NULL; +else if (rlength == PCRE2_ZERO_TERMINATED) + rlength = PRIV(strlen)(replacement); +repend = replacement + rlength; + /* Check for using a match that has already happened. Note that the subject pointer in the match data may be NULL after a no-match. */ @@ -292,6 +298,7 @@ else if (use_existing_match) (pcre2_general_context *)mcontext; int pairs = (code->top_bracket + 1 < match_data->oveccount)? code->top_bracket + 1 : match_data->oveccount; + if (subject == NULL) return PCRE2_ERROR_NULL; internal_match_data = pcre2_match_data_create(match_data->oveccount, gcontext); if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; @@ -312,11 +319,9 @@ scb.input = subject; scb.output = (PCRE2_SPTR)buffer; scb.ovector = ovector; -/* Find lengths of zero-terminated strings and the end of the replacement. */ - -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); -if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement); -repend = replacement + rlength; +/* Find lengths of zero-terminated subject */ +if (length == PCRE2_ZERO_TERMINATED) + length = subject? PRIV(strlen)(subject) : 0; /* Check UTF replacement string if necessary. */