Skip to content

Commit ca2af27

Browse files
committed
ext/pcre: Refactor php_pcre_replace_func_impl()
We don't need the FCI anymore, and we always have the subject as a zend_string.
1 parent 61c0db9 commit ca2af27

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

ext/pcre/php_pcre.c

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,22 +1835,19 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
18351835
}
18361836
/* }}} */
18371837

1838-
/* {{{ php_pcre_replace_func_impl() */
1839-
static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_string *subject_str, const char *subject, size_t subject_len, zend_fcall_info *fci, zend_fcall_info_cache *fcc, size_t limit, size_t *replace_count, zend_long flags)
1838+
static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_string *subject_str, zend_fcall_info_cache *fcc, size_t limit, size_t *replace_count, zend_long flags)
18401839
{
18411840
uint32_t options; /* Execution options */
18421841
int count; /* Count of matched subpatterns */
18431842
zend_string **subpat_names; /* Array for named subpatterns */
18441843
uint32_t num_subpats; /* Number of captured subpatterns */
1845-
size_t new_len; /* Length of needed storage */
18461844
size_t alloc_len; /* Actual allocated length */
18471845
PCRE2_SIZE start_offset; /* Where the new search starts */
18481846
size_t last_end_offset; /* Where the last search ended */
18491847
const char *match, /* The current match */
18501848
*piece; /* The current piece of subject */
18511849
size_t result_len; /* Length of result */
18521850
zend_string *result; /* Result of replacement */
1853-
zend_string *eval_result; /* Result of custom function */
18541851
pcre2_match_data *match_data;
18551852
bool old_mdata_used;
18561853

@@ -1889,15 +1886,15 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
18891886
/* Execute the regular expression. */
18901887
#ifdef HAVE_PCRE_JIT_SUPPORT
18911888
if ((pce->preg_options & PREG_JIT) && options) {
1892-
count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
1889+
count = pcre2_jit_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), start_offset,
18931890
PCRE2_NO_UTF_CHECK, match_data, mctx);
18941891
} else
18951892
#endif
1896-
count = pcre2_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
1893+
count = pcre2_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), start_offset,
18971894
options, match_data, mctx);
18981895

18991896
while (1) {
1900-
piece = subject + last_end_offset;
1897+
piece = ZSTR_VAL(subject_str) + last_end_offset;
19011898

19021899
if (count >= 0 && limit) {
19031900
/* Check for too many substrings condition. */
@@ -1921,13 +1918,14 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
19211918
}
19221919

19231920
/* Set the match location in subject */
1924-
match = subject + offsets[0];
1921+
match = ZSTR_VAL(subject_str) + offsets[0];
19251922

1926-
new_len = result_len + offsets[0] - last_end_offset; /* part before the match */
1923+
/* Length of needed storage */
1924+
size_t new_len = result_len + offsets[0] - last_end_offset; /* part before the match */
19271925

19281926
/* Use custom function to get replacement string and its length. */
1929-
eval_result = preg_do_repl_func(
1930-
fcc, subject, offsets, subpat_names, num_subpats, count,
1927+
zend_string *eval_result = preg_do_repl_func(
1928+
fcc, ZSTR_VAL(subject_str), offsets, subpat_names, num_subpats, count,
19311929
pcre2_get_mark(match_data), flags);
19321930

19331931
if (UNEXPECTED(eval_result == NULL)) {
@@ -1964,18 +1962,18 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
19641962
the match again at the same point. If this fails (picked up above) we
19651963
advance to the next character. */
19661964
if (start_offset == offsets[0]) {
1967-
count = pcre2_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
1965+
count = pcre2_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), start_offset,
19681966
PCRE2_NO_UTF_CHECK | PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED, match_data, mctx);
19691967

1970-
piece = subject + start_offset;
1968+
piece = ZSTR_VAL(subject_str) + start_offset;
19711969
if (count >= 0 && limit) {
19721970
goto matched;
19731971
} else if (count == PCRE2_ERROR_NOMATCH || limit == 0) {
19741972
/* If we previously set PCRE2_NOTEMPTY_ATSTART after a null match,
19751973
this is not necessarily the end. We need to advance
19761974
the start offset, and continue. Fudge the offset values
19771975
to achieve this, unless we're already at the end of the string. */
1978-
if (start_offset < subject_len) {
1976+
if (start_offset < ZSTR_LEN(subject_str)) {
19791977
size_t unit_len = calculate_unit_length(pce, piece);
19801978
start_offset += unit_len;
19811979
} else {
@@ -1988,20 +1986,17 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
19881986

19891987
} else if (count == PCRE2_ERROR_NOMATCH || limit == 0) {
19901988
not_matched:
1991-
if (!result && subject_str) {
1989+
if (result == NULL) {
19921990
result = zend_string_copy(subject_str);
19931991
break;
19941992
}
19951993
/* now we know exactly how long it is */
1996-
alloc_len = result_len + subject_len - last_end_offset;
1997-
if (NULL != result) {
1998-
result = zend_string_realloc(result, alloc_len, 0);
1999-
} else {
2000-
result = zend_string_alloc(alloc_len, 0);
2001-
}
1994+
size_t segment_len = ZSTR_LEN(subject_str) - last_end_offset;
1995+
alloc_len = result_len + segment_len;
1996+
result = zend_string_realloc(result, alloc_len, 0);
20021997
/* stick that last bit of string on our output */
2003-
memcpy(ZSTR_VAL(result) + result_len, piece, subject_len - last_end_offset);
2004-
result_len += subject_len - last_end_offset;
1998+
memcpy(ZSTR_VAL(result) + result_len, piece, segment_len);
1999+
result_len += segment_len;
20052000
ZSTR_VAL(result)[result_len] = '\0';
20062001
ZSTR_LEN(result) = result_len;
20072002
break;
@@ -2016,11 +2011,11 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
20162011
}
20172012
#ifdef HAVE_PCRE_JIT_SUPPORT
20182013
if ((pce->preg_options & PREG_JIT)) {
2019-
count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
2014+
count = pcre2_jit_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), start_offset,
20202015
PCRE2_NO_UTF_CHECK, match_data, mctx);
20212016
} else
20222017
#endif
2023-
count = pcre2_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
2018+
count = pcre2_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), start_offset,
20242019
PCRE2_NO_UTF_CHECK, match_data, mctx);
20252020
}
20262021
if (match_data != mdata) {
@@ -2030,7 +2025,6 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
20302025

20312026
return result;
20322027
}
2033-
/* }}} */
20342028

20352029
/* {{{ php_pcre_replace_func */
20362030
static zend_always_inline zend_string *php_pcre_replace_func(zend_string *regex,
@@ -2046,9 +2040,7 @@ static zend_always_inline zend_string *php_pcre_replace_func(zend_string *regex,
20462040
return NULL;
20472041
}
20482042
pce->refcount++;
2049-
result = php_pcre_replace_func_impl(
2050-
pce, subject_str, ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), fci, fcc,
2051-
limit, replace_count, flags);
2043+
result = php_pcre_replace_func_impl(pce, subject_str, fcc, limit, replace_count, flags);
20522044
pce->refcount--;
20532045

20542046
return result;

0 commit comments

Comments
 (0)