summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorGeorge Peter Banyard <girgias@php.net>2020-06-22 16:29:59 +0200
committerGeorge Peter Banyard <girgias@php.net>2020-07-09 14:17:19 +0200
commitaf1de148025197f4f9131c2f074ea9ce65b7b04d (patch)
tree267432b0a83dcce4f134b86cb8fb47252d125b48 /ext
parent9839752a9c364dcec6e3c6f15f25987498486171 (diff)
downloadphp-git-af1de148025197f4f9131c2f074ea9ce65b7b04d.tar.gz
Use ZPP string|array union check in PCRE extension
Diffstat (limited to 'ext')
-rw-r--r--ext/pcre/php_pcre.c227
-rw-r--r--ext/pcre/php_pcre.stub.php25
-rw-r--r--ext/pcre/php_pcre_arginfo.h12
-rw-r--r--ext/pcre/tests/preg_replace_callback_array2.phpt13
-rw-r--r--ext/pcre/tests/preg_replace_error1.phpt2
-rw-r--r--ext/pcre/tests/preg_replace_error2.phpt2
-rw-r--r--ext/standard/tests/streams/bug61115.phpt4
7 files changed, 137 insertions, 148 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 16ec75d02b..8138dd5e69 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -2060,48 +2060,46 @@ static zend_always_inline zend_string *php_pcre_replace_func(zend_string *regex,
/* }}} */
/* {{{ php_pcre_replace_array */
-static zend_string *php_pcre_replace_array(HashTable *regex, zval *replace, zend_string *subject_str, size_t limit, size_t *replace_count)
+static zend_string *php_pcre_replace_array(HashTable *regex,
+ zend_string *replace_str, HashTable *replace_ht,
+ zend_string *subject_str, size_t limit, size_t *replace_count)
{
zval *regex_entry;
zend_string *result;
- zend_string *replace_str, *tmp_replace_str;
- if (Z_TYPE_P(replace) == IS_ARRAY) {
+ zend_string_addref(subject_str);
+
+ if (replace_ht) {
uint32_t replace_idx = 0;
- HashTable *replace_ht = Z_ARRVAL_P(replace);
/* For each entry in the regex array, get the entry */
ZEND_HASH_FOREACH_VAL(regex, regex_entry) {
/* Make sure we're dealing with strings. */
zend_string *tmp_regex_str;
zend_string *regex_str = zval_get_tmp_string(regex_entry, &tmp_regex_str);
+ zend_string *replace_entry_str, *tmp_replace_entry_str;
zval *zv;
/* Get current entry */
while (1) {
if (replace_idx == replace_ht->nNumUsed) {
- replace_str = ZSTR_EMPTY_ALLOC();
- tmp_replace_str = NULL;
+ replace_entry_str = ZSTR_EMPTY_ALLOC();
+ tmp_replace_entry_str = NULL;
break;
}
zv = &replace_ht->arData[replace_idx].val;
replace_idx++;
if (Z_TYPE_P(zv) != IS_UNDEF) {
- replace_str = zval_get_tmp_string(zv, &tmp_replace_str);
+ replace_entry_str = zval_get_tmp_string(zv, &tmp_replace_entry_str);
break;
}
}
/* Do the actual replacement and put the result back into subject_str
for further replacements. */
- result = php_pcre_replace(regex_str,
- subject_str,
- ZSTR_VAL(subject_str),
- ZSTR_LEN(subject_str),
- replace_str,
- limit,
- replace_count);
- zend_tmp_string_release(tmp_replace_str);
+ result = php_pcre_replace(regex_str, subject_str, ZSTR_VAL(subject_str),
+ ZSTR_LEN(subject_str), replace_entry_str, limit, replace_count);
+ zend_tmp_string_release(tmp_replace_entry_str);
zend_tmp_string_release(tmp_regex_str);
zend_string_release_ex(subject_str, 0);
subject_str = result;
@@ -2111,7 +2109,7 @@ static zend_string *php_pcre_replace_array(HashTable *regex, zval *replace, zend
} ZEND_HASH_FOREACH_END();
} else {
- replace_str = Z_STR_P(replace);
+ ZEND_ASSERT(replace_str != NULL);
/* For each entry in the regex array, get the entry */
ZEND_HASH_FOREACH_VAL(regex, regex_entry) {
@@ -2121,13 +2119,8 @@ static zend_string *php_pcre_replace_array(HashTable *regex, zval *replace, zend
/* Do the actual replacement and put the result back into subject_str
for further replacements. */
- result = php_pcre_replace(regex_str,
- subject_str,
- ZSTR_VAL(subject_str),
- ZSTR_LEN(subject_str),
- replace_str,
- limit,
- replace_count);
+ result = php_pcre_replace(regex_str, subject_str, ZSTR_VAL(subject_str),
+ ZSTR_LEN(subject_str), replace_str, limit, replace_count);
zend_tmp_string_release(tmp_regex_str);
zend_string_release_ex(subject_str, 0);
subject_str = result;
@@ -2143,83 +2136,80 @@ static zend_string *php_pcre_replace_array(HashTable *regex, zval *replace, zend
/* }}} */
/* {{{ php_replace_in_subject */
-static zend_always_inline zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *subject, size_t limit, size_t *replace_count)
+static zend_always_inline zend_string *php_replace_in_subject(
+ zend_string *regex_str, HashTable *regex_ht,
+ zend_string *replace_str, HashTable *replace_ht,
+ zend_string *subject, size_t limit, size_t *replace_count)
{
zend_string *result;
- zend_string *subject_str = zval_get_string(subject);
-
- if (Z_TYPE_P(regex) != IS_ARRAY) {
- result = php_pcre_replace(Z_STR_P(regex),
- subject_str,
- ZSTR_VAL(subject_str),
- ZSTR_LEN(subject_str),
- Z_STR_P(replace),
- limit,
- replace_count);
- zend_string_release_ex(subject_str, 0);
+
+ if (regex_str) {
+ ZEND_ASSERT(replace_str != NULL);
+ result = php_pcre_replace(regex_str, subject, ZSTR_VAL(subject), ZSTR_LEN(subject),
+ replace_str, limit, replace_count);
} else {
- result = php_pcre_replace_array(Z_ARRVAL_P(regex),
- replace,
- subject_str,
- limit,
- replace_count);
+ ZEND_ASSERT(regex_ht != NULL);
+ result = php_pcre_replace_array(regex_ht, replace_str, replace_ht, subject,
+ limit, replace_count);
}
return result;
}
/* }}} */
/* {{{ php_replace_in_subject_func */
-static zend_string *php_replace_in_subject_func(zval *regex, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *subject, size_t limit, size_t *replace_count, zend_long flags)
+static zend_string *php_replace_in_subject_func(zend_string *regex_str, HashTable *regex_ht,
+ zend_fcall_info *fci, zend_fcall_info_cache *fcc,
+ zend_string *subject, size_t limit, size_t *replace_count, zend_long flags)
{
zend_string *result;
- zend_string *subject_str = zval_get_string(subject);
- if (Z_TYPE_P(regex) != IS_ARRAY) {
+ if (regex_str) {
result = php_pcre_replace_func(
- Z_STR_P(regex), subject_str, fci, fcc, limit, replace_count, flags);
- zend_string_release_ex(subject_str, 0);
+ regex_str, subject, fci, fcc, limit, replace_count, flags);
return result;
} else {
+ /* If regex is an array */
zval *regex_entry;
- /* If regex is an array */
+ ZEND_ASSERT(regex_ht != NULL);
+
+ zend_string_addref(subject);
/* For each entry in the regex array, get the entry */
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) {
+ ZEND_HASH_FOREACH_VAL(regex_ht, regex_entry) {
/* Make sure we're dealing with strings. */
- zend_string *tmp_regex_str;
- zend_string *regex_str = zval_get_tmp_string(regex_entry, &tmp_regex_str);
+ zend_string *tmp_regex_entry_str;
+ zend_string *regex_entry_str = zval_get_tmp_string(regex_entry, &tmp_regex_entry_str);
- /* Do the actual replacement and put the result back into subject_str
+ /* Do the actual replacement and put the result back into subject
for further replacements. */
result = php_pcre_replace_func(
- regex_str, subject_str, fci, fcc, limit, replace_count, flags);
- zend_tmp_string_release(tmp_regex_str);
- zend_string_release_ex(subject_str, 0);
- subject_str = result;
+ regex_entry_str, subject, fci, fcc, limit, replace_count, flags);
+ zend_tmp_string_release(tmp_regex_entry_str);
+ zend_string_release(subject);
+ subject = result;
if (UNEXPECTED(result == NULL)) {
break;
}
} ZEND_HASH_FOREACH_END();
- return subject_str;
+ return subject;
}
}
/* }}} */
/* {{{ preg_replace_func_impl */
-static size_t preg_replace_func_impl(zval *return_value, zval *regex, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *subject, zend_long limit_val, zend_long flags)
+static size_t preg_replace_func_impl(zval *return_value,
+ zend_string *regex_str, HashTable *regex_ht,
+ zend_fcall_info *fci, zend_fcall_info_cache *fcc,
+ zend_string *subject_str, HashTable *subject_ht, zend_long limit_val, zend_long flags)
{
zend_string *result;
size_t replace_count = 0;
- if (Z_TYPE_P(regex) != IS_ARRAY) {
- convert_to_string_ex(regex);
- }
-
- if (Z_TYPE_P(subject) != IS_ARRAY) {
+ if (subject_str) {
result = php_replace_in_subject_func(
- regex, fci, fcc, subject, limit_val, &replace_count, flags);
+ regex_str, regex_ht, fci, fcc, subject_str, limit_val, &replace_count, flags);
if (result != NULL) {
RETVAL_STR(result);
} else {
@@ -2231,13 +2221,18 @@ static size_t preg_replace_func_impl(zval *return_value, zval *regex, zend_fcall
zend_string *string_key;
zend_ulong num_key;
- array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(subject)));
+ ZEND_ASSERT(subject_ht != NULL);
+
+ array_init_size(return_value, zend_hash_num_elements(subject_ht));
/* For each subject entry, convert it to string, then perform replacement
and add the result to the return_value array. */
- ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) {
+ ZEND_HASH_FOREACH_KEY_VAL(subject_ht, num_key, string_key, subject_entry) {
+ zend_string *tmp_subject_entry_str;
+ zend_string *subject_entry_str = zval_get_tmp_string(subject_entry, &tmp_subject_entry_str);
+
result = php_replace_in_subject_func(
- regex, fci, fcc, subject_entry, limit_val, &replace_count, flags);
+ regex_str, regex_ht, fci, fcc, subject_entry_str, limit_val, &replace_count, flags);
if (result != NULL) {
/* Add to return array */
ZVAL_STR(&zv, result);
@@ -2247,6 +2242,7 @@ static size_t preg_replace_func_impl(zval *return_value, zval *regex, zend_fcall
zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, &zv);
}
}
+ zend_tmp_string_release(tmp_subject_entry_str);
} ZEND_HASH_FOREACH_END();
}
@@ -2255,9 +2251,15 @@ static size_t preg_replace_func_impl(zval *return_value, zval *regex, zend_fcall
/* }}} */
/* {{{ preg_replace_common */
-static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter)
+static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, bool is_filter)
{
- zval *regex, *replace, *subject, *zcount = NULL;
+ zval *zcount = NULL;
+ zend_string *regex_str;
+ HashTable *regex_ht;
+ zend_string *replace_str;
+ HashTable *replace_ht;
+ zend_string *subject_str;
+ HashTable *subject_ht;
zend_long limit = -1;
size_t replace_count = 0;
zend_string *result;
@@ -2265,33 +2267,24 @@ static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter)
/* Get function parameters and do error-checking. */
ZEND_PARSE_PARAMETERS_START(3, 5)
- Z_PARAM_ZVAL(regex)
- Z_PARAM_ZVAL(replace)
- Z_PARAM_ZVAL(subject)
+ Z_PARAM_STR_OR_ARRAY_HT(regex_str, regex_ht)
+ Z_PARAM_STR_OR_ARRAY_HT(replace_str, replace_ht)
+ Z_PARAM_STR_OR_ARRAY_HT(subject_str, subject_ht)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(limit)
Z_PARAM_ZVAL(zcount)
ZEND_PARSE_PARAMETERS_END();
- if (Z_TYPE_P(replace) != IS_ARRAY) {
- convert_to_string_ex(replace);
- if (Z_TYPE_P(regex) != IS_ARRAY) {
- convert_to_string_ex(regex);
- }
- } else {
- if (Z_TYPE_P(regex) != IS_ARRAY) {
- zend_argument_type_error(1, "must be of type array when argument #2 ($replace) is an array, %s given", zend_zval_type_name(regex));
- RETURN_THROWS();
- }
+ /* If replace is an array then the regex argument needs to also be an array */
+ if (replace_ht && !regex_ht) {
+ zend_argument_type_error(1, "must be of type array when argument #2 ($replace) is an array, string given");
+ RETURN_THROWS();
}
- if (Z_TYPE_P(subject) != IS_ARRAY) {
+ if (subject_str) {
old_replace_count = replace_count;
- result = php_replace_in_subject(regex,
- replace,
- subject,
- limit,
- &replace_count);
+ result = php_replace_in_subject(regex_str, regex_ht, replace_str, replace_ht,
+ subject_str, limit, &replace_count);
if (result != NULL) {
if (!is_filter || replace_count > old_replace_count) {
RETVAL_STR(result);
@@ -2308,17 +2301,19 @@ static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter)
zend_string *string_key;
zend_ulong num_key;
- array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(subject)));
+ ZEND_ASSERT(subject_ht != NULL);
+
+ array_init_size(return_value, zend_hash_num_elements(subject_ht));
/* For each subject entry, convert it to string, then perform replacement
and add the result to the return_value array. */
- ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) {
+ ZEND_HASH_FOREACH_KEY_VAL(subject_ht, num_key, string_key, subject_entry) {
old_replace_count = replace_count;
- result = php_replace_in_subject(regex,
- replace,
- subject_entry,
- limit,
- &replace_count);
+ zend_string *tmp_subject_entry_str;
+ zend_string *subject_entry_str = zval_get_tmp_string(subject_entry, &tmp_subject_entry_str);
+ result = php_replace_in_subject(regex_str, regex_ht, replace_str, replace_ht,
+ subject_entry_str, limit, &replace_count);
+
if (result != NULL) {
if (!is_filter || replace_count > old_replace_count) {
/* Add to return array */
@@ -2332,6 +2327,7 @@ static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter)
zend_string_release_ex(result, 0);
}
}
+ zend_tmp_string_release(tmp_subject_entry_str);
} ZEND_HASH_FOREACH_END();
}
@@ -2344,14 +2340,18 @@ static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter)
/* {{{ Perform Perl-style regular expression replacement. */
PHP_FUNCTION(preg_replace)
{
- preg_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+ preg_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
/* }}} */
/* {{{ Perform Perl-style regular expression replacement using replacement callback. */
PHP_FUNCTION(preg_replace_callback)
{
- zval *regex, *subject, *zcount = NULL;
+ zval *zcount = NULL;
+ zend_string *regex_str;
+ HashTable *regex_ht;
+ zend_string *subject_str;
+ HashTable *subject_ht;
zend_long limit = -1, flags = 0;
size_t replace_count;
zend_fcall_info fci;
@@ -2359,16 +2359,18 @@ PHP_FUNCTION(preg_replace_callback)
/* Get function parameters and do error-checking. */
ZEND_PARSE_PARAMETERS_START(3, 6)
- Z_PARAM_ZVAL(regex)
+ Z_PARAM_STR_OR_ARRAY_HT(regex_str, regex_ht)
Z_PARAM_FUNC(fci, fcc)
- Z_PARAM_ZVAL(subject)
+ Z_PARAM_STR_OR_ARRAY_HT(subject_str, subject_ht)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(limit)
Z_PARAM_ZVAL(zcount)
Z_PARAM_LONG(flags)
ZEND_PARSE_PARAMETERS_END();
- replace_count = preg_replace_func_impl(return_value, regex, &fci, &fcc, subject, limit, flags);
+ replace_count = preg_replace_func_impl(return_value, regex_str, regex_ht,
+ &fci, &fcc,
+ subject_str, subject_ht, limit, flags);
if (zcount) {
ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count);
}
@@ -2378,16 +2380,17 @@ PHP_FUNCTION(preg_replace_callback)
/* {{{ Perform Perl-style regular expression replacement using replacement callback. */
PHP_FUNCTION(preg_replace_callback_array)
{
- zval regex, zv, *replace, *subject, *pattern, *zcount = NULL;
+ zval zv, *replace, *subject, *zcount = NULL;
+ HashTable *pattern;
+ zend_string *str_idx_regex;
zend_long limit = -1, flags = 0;
- zend_string *str_idx;
size_t replace_count = 0;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
/* Get function parameters and do error-checking. */
ZEND_PARSE_PARAMETERS_START(2, 5)
- Z_PARAM_ARRAY(pattern)
+ Z_PARAM_ARRAY_HT(pattern)
Z_PARAM_ZVAL(subject)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(limit)
@@ -2398,10 +2401,8 @@ PHP_FUNCTION(preg_replace_callback_array)
fci.size = sizeof(fci);
fci.object = NULL;
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pattern), str_idx, replace) {
- if (str_idx) {
- ZVAL_STR_COPY(&regex, str_idx);
- } else {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(pattern, str_idx_regex, replace) {
+ if (!str_idx_regex) {
php_error_docref(NULL, E_WARNING, "Delimiter must not be alphanumeric or backslash");
zval_ptr_dtor(return_value);
RETURN_NULL();
@@ -2409,25 +2410,23 @@ PHP_FUNCTION(preg_replace_callback_array)
if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) {
zend_string *callback_name = zend_get_callable_name(replace);
- php_error_docref(NULL, E_WARNING, "'%s' is not a valid callback", ZSTR_VAL(callback_name));
+ zend_type_error("'%s' is not a valid callback", ZSTR_VAL(callback_name));
zend_string_release_ex(callback_name, 0);
- zval_ptr_dtor(&regex);
- zval_ptr_dtor(return_value);
- ZVAL_COPY(return_value, subject);
- return;
+ RETURN_THROWS();
}
ZVAL_COPY_VALUE(&fci.function_name, replace);
- replace_count += preg_replace_func_impl(&zv, &regex, &fci, &fcc, subject, limit, flags);
+ replace_count += preg_replace_func_impl(&zv, str_idx_regex, /* regex_ht */ NULL, &fci, &fcc,
+ Z_STR_P(subject), Z_ARRVAL_P(subject),
+ limit, flags);
+
if (subject != return_value) {
subject = return_value;
} else {
zval_ptr_dtor(return_value);
}
- zval_ptr_dtor(&regex);
-
ZVAL_COPY_VALUE(return_value, &zv);
if (UNEXPECTED(EG(exception))) {
@@ -2445,7 +2444,7 @@ PHP_FUNCTION(preg_replace_callback_array)
/* {{{ Perform Perl-style regular expression replacement and only return matches. */
PHP_FUNCTION(preg_filter)
{
- preg_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+ preg_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
/* }}} */
diff --git a/ext/pcre/php_pcre.stub.php b/ext/pcre/php_pcre.stub.php
index 58bc5c378f..97f08eec0f 100644
--- a/ext/pcre/php_pcre.stub.php
+++ b/ext/pcre/php_pcre.stub.php
@@ -6,32 +6,17 @@ function preg_match(string $pattern, string $subject, &$subpatterns = null, int
function preg_match_all(string $pattern, string $subject, &$subpatterns = null, int $flags = 0, int $offset = 0): int|false|null {}
-/**
- * @param string|array $regex
- * @param string|array $replace
- * @param string|array $subject
- */
-function preg_replace($regex, $replace, $subject, int $limit = -1, &$count = null): string|array|null {}
-
-/**
- * @param string|array $regex
- * @param string|array $replace
- * @param string|array $subject
- */
-function preg_filter($regex, $replace, $subject, int $limit = -1, &$count = null): string|array|null {}
-
-/**
- * @param string|array $regex
- * @param string|array $subject
- */
-function preg_replace_callback($regex, callable $callback, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
+function preg_replace(string|array $regex, string|array $replace, string|array $subject, int $limit = -1, &$count = null): string|array|null {}
+
+function preg_filter(string|array $regex, string|array $replace, string|array $subject, int $limit = -1, &$count = null): string|array|null {}
+
+function preg_replace_callback(string|array $regex, callable $callback, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
/** @param string|array $subject */
function preg_replace_callback_array(array $pattern, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
function preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|false {}
-
function preg_quote(string $str, ?string $delim_char = null): string {}
function preg_grep(string $regex, array $input, int $flags = 0): array|false {}
diff --git a/ext/pcre/php_pcre_arginfo.h b/ext/pcre/php_pcre_arginfo.h
index b63bfd5856..678fdd69a4 100644
--- a/ext/pcre/php_pcre_arginfo.h
+++ b/ext/pcre/php_pcre_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 2e7402e33a485cd3c1a74c0d6210214b3e7c4e9a */
+ * Stub hash: 88e664fe3f4714ab7760a99bffef5c11eafcf0aa */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0)
@@ -18,9 +18,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match_all, 0, 2, MAY_BE_LON
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL)
- ZEND_ARG_INFO(0, regex)
- ZEND_ARG_INFO(0, replace)
- ZEND_ARG_INFO(0, subject)
+ ZEND_ARG_TYPE_MASK(0, regex, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
+ ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
+ ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null")
ZEND_END_ARG_INFO()
@@ -28,9 +28,9 @@ ZEND_END_ARG_INFO()
#define arginfo_preg_filter arginfo_preg_replace
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL)
- ZEND_ARG_INFO(0, regex)
+ ZEND_ARG_TYPE_MASK(0, regex, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
- ZEND_ARG_INFO(0, subject)
+ ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
diff --git a/ext/pcre/tests/preg_replace_callback_array2.phpt b/ext/pcre/tests/preg_replace_callback_array2.phpt
index f333d06dcb..679a4b0c54 100644
--- a/ext/pcre/tests/preg_replace_callback_array2.phpt
+++ b/ext/pcre/tests/preg_replace_callback_array2.phpt
@@ -5,7 +5,14 @@ preg_replace_callback_array() errors
$a = array();
$b = "";
-var_dump(preg_replace_callback_array(array("xx" => "s"), $a, -1, $b));
+
+try {
+ var_dump(preg_replace_callback_array(array("xx" => "s"), $a, -1, $b));
+} catch (\TypeError $e) {
+ echo $e->getMessage() . \PHP_EOL;
+}
+
+
var_dump($b);
function f() {
static $count = 1;
@@ -23,9 +30,7 @@ try {
echo "Done\n";
?>
--EXPECTF--
-Warning: preg_replace_callback_array(): 's' is not a valid callback in %spreg_replace_callback_array2.php on line %d
-array(0) {
-}
+'s' is not a valid callback
string(0) ""
Warning: preg_replace_callback_array(): No ending delimiter '/' found in %spreg_replace_callback_array2.php on line %d
diff --git a/ext/pcre/tests/preg_replace_error1.phpt b/ext/pcre/tests/preg_replace_error1.phpt
index 39d0b692e7..58cd049691 100644
--- a/ext/pcre/tests/preg_replace_error1.phpt
+++ b/ext/pcre/tests/preg_replace_error1.phpt
@@ -56,4 +56,4 @@ string(1) "a"
Arg value is /[a-zA-Z]/
string(1) "1"
-Object of class stdClass could not be converted to string
+preg_replace(): Argument #1 ($regex) must be of type string|array, stdClass given
diff --git a/ext/pcre/tests/preg_replace_error2.phpt b/ext/pcre/tests/preg_replace_error2.phpt
index 0aefff9df6..9a3056ab88 100644
--- a/ext/pcre/tests/preg_replace_error2.phpt
+++ b/ext/pcre/tests/preg_replace_error2.phpt
@@ -36,5 +36,5 @@ string(64) "this is a stringthis is a stringthis is a stringthis is a string"
Arg value is: Array
preg_replace(): Argument #1 ($regex) must be of type array when argument #2 ($replace) is an array, string given
-Object of class stdClass could not be converted to string
+preg_replace(): Argument #2 ($replace) must be of type string|array, stdClass given
Done
diff --git a/ext/standard/tests/streams/bug61115.phpt b/ext/standard/tests/streams/bug61115.phpt
index ce6b57651c..28a1838c16 100644
--- a/ext/standard/tests/streams/bug61115.phpt
+++ b/ext/standard/tests/streams/bug61115.phpt
@@ -9,9 +9,9 @@ $resourceFileTemp = fopen('php://temp', 'r+');
stream_context_set_params($resourceFileTemp, array());
try {
preg_replace('', function() {}, $resourceFileTemp);
-} catch (Error $e) {
+} catch (\TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
-Object of class Closure could not be converted to string
+preg_replace(): Argument #2 ($replace) must be of type string|array, Closure given