diff options
Diffstat (limited to 'src/3rdparty/pcre2/src/pcre2_substitute.c')
-rw-r--r-- | src/3rdparty/pcre2/src/pcre2_substitute.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/src/3rdparty/pcre2/src/pcre2_substitute.c b/src/3rdparty/pcre2/src/pcre2_substitute.c index 981a106a9f..edbb78c6d7 100644 --- a/src/3rdparty/pcre2/src/pcre2_substitute.c +++ b/src/3rdparty/pcre2/src/pcre2_substitute.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2020 University of Cambridge + New API code Copyright (c) 2016-2022 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -260,6 +260,18 @@ 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. A NULL replacement of +zero length is interpreted as an empty string. */ + +if (replacement == NULL) + { + if (rlength != 0) return PCRE2_ERROR_NULL; + replacement = (PCRE2_SPTR)""; + } + +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. */ @@ -270,8 +282,9 @@ replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0); match data block. We create an internal match_data block in two cases: (a) an external one is not supplied (and we are not starting from an existing match); (b) an existing match is to be used for the first substitution. In the latter -case, we copy the existing match into the internal block. This ensures that no -changes are made to the existing match data block. */ +case, we copy the existing match into the internal block, except for any cached +heap frame size and pointer. This ensures that no changes are made to the +external match data block. */ if (match_data == NULL) { @@ -297,6 +310,8 @@ else if (use_existing_match) if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector) + 2*pairs*sizeof(PCRE2_SIZE)); + internal_match_data->heapframes = NULL; + internal_match_data->heapframes_size = 0; match_data = internal_match_data; } @@ -312,11 +327,18 @@ scb.input = subject; scb.output = (PCRE2_SPTR)buffer; scb.ovector = ovector; -/* Find lengths of zero-terminated strings and the end of the replacement. */ +/* A NULL subject of zero length is treated as an empty string. */ -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); -if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement); -repend = replacement + rlength; +if (subject == NULL) + { + if (length != 0) return PCRE2_ERROR_NULL; + subject = (PCRE2_SPTR)""; + } + +/* Find length of zero-terminated subject */ + +if (length == PCRE2_ZERO_TERMINATED) + length = subject? PRIV(strlen)(subject) : 0; /* Check UTF replacement string if necessary. */ |