]> granicus.if.org Git - php/commitdiff
Use ZPP string|array union check in PCRE extension
authorGeorge Peter Banyard <girgias@php.net>
Mon, 22 Jun 2020 14:29:59 +0000 (16:29 +0200)
committerGeorge Peter Banyard <girgias@php.net>
Thu, 9 Jul 2020 12:17:19 +0000 (14:17 +0200)
ext/pcre/php_pcre.c
ext/pcre/php_pcre.stub.php
ext/pcre/php_pcre_arginfo.h
ext/pcre/tests/preg_replace_callback_array2.phpt
ext/pcre/tests/preg_replace_error1.phpt
ext/pcre/tests/preg_replace_error2.phpt
ext/standard/tests/streams/bug61115.phpt
sapi/cli/tests/006.phpt

index 16ec75d02b2d7dde0eee6f78425fe18b86b50068..8138dd5e699962424ed55f55a19ad648d699c712 100644 (file)
@@ -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);
 }
 /* }}} */
 
index 58bc5c378f29fee7d2a0aa046230f31eb9116bf2..97f08eec0fcfa9a443b6afcec1f02243d49d43b3 100644 (file)
@@ -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 {}
index b63bfd5856e0661d4533f5b10f72a7e18e1ce727..678fdd69a4088031319e3e8ca3e0db52233b7965 100644 (file)
@@ -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")
index f333d06dcb4e2bd3c039c55a105f3342af7f5bf2..679a4b0c54ec2b9b12739c78ce7e0c37c14b9b02 100644 (file)
@@ -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
index 39d0b692e72ee6415ab1604356aaa6a0cc3f75fb..58cd049691a97f74e4cf69061be17a6c85c83068 100644 (file)
@@ -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
index 0aefff9df64a3bdb60542fa060e2d6f84582912a..9a3056ab882ad47c0bc4abd0ce04ab67ef1e282d 100644 (file)
@@ -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
index ce6b57651cfa565d90b94e79f93ee996e1c5ee81..28a1838c1638a8e0c8df6327676064e20b0dce24 100644 (file)
@@ -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
index 8d15e653625af494de9f5578e9acb0672636ea85..ad4fa457f5ac7675ac70e268dad6e9a5f5ec4ba5 100644 (file)
@@ -90,9 +90,9 @@ string(%d) "Extension [ <persistent> extension #%d pcre version %s ] {
     Function [ <internal:pcre> function preg_replace ] {
 
       - Parameters [5] {
-        Parameter #0 [ <required> $regex ]
-        Parameter #1 [ <required> $replace ]
-        Parameter #2 [ <required> $subject ]
+        Parameter #0 [ <required> array|string $regex ]
+        Parameter #1 [ <required> array|string $replace ]
+        Parameter #2 [ <required> array|string $subject ]
         Parameter #3 [ <optional> int $limit = -1 ]
         Parameter #4 [ <optional> &$count = null ]
       }
@@ -101,9 +101,9 @@ string(%d) "Extension [ <persistent> extension #%d pcre version %s ] {
     Function [ <internal:pcre> function preg_filter ] {
 
       - Parameters [5] {
-        Parameter #0 [ <required> $regex ]
-        Parameter #1 [ <required> $replace ]
-        Parameter #2 [ <required> $subject ]
+        Parameter #0 [ <required> array|string $regex ]
+        Parameter #1 [ <required> array|string $replace ]
+        Parameter #2 [ <required> array|string $subject ]
         Parameter #3 [ <optional> int $limit = -1 ]
         Parameter #4 [ <optional> &$count = null ]
       }
@@ -112,9 +112,9 @@ string(%d) "Extension [ <persistent> extension #%d pcre version %s ] {
     Function [ <internal:pcre> function preg_replace_callback ] {
 
       - Parameters [6] {
-        Parameter #0 [ <required> $regex ]
+        Parameter #0 [ <required> array|string $regex ]
         Parameter #1 [ <required> callable $callback ]
-        Parameter #2 [ <required> $subject ]
+        Parameter #2 [ <required> array|string $subject ]
         Parameter #3 [ <optional> int $limit = -1 ]
         Parameter #4 [ <optional> &$count = null ]
         Parameter #5 [ <optional> int $flags = 0 ]