diff options
Diffstat (limited to 'ext/pcre')
89 files changed, 816 insertions, 775 deletions
diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index 86298bbe1b..cbc8cf4517 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -6,7 +6,6 @@ ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_ ADD_DEF_FILE("ext\\pcre\\php_pcre.def"); AC_DEFINE('HAVE_BUNDLED_PCRE', 1, 'Using bundled PCRE library'); -AC_DEFINE('HAVE_PCRE', 1, 'Have PCRE library'); AC_DEFINE('PCRE2_CODE_UNIT_WIDTH', 8, 'Have PCRE library'); AC_DEFINE("PCRE2_STATIC", 1, ""); PHP_PCRE="yes"; diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 7e57201954..4a500207d7 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -19,7 +19,6 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then PHP_EVAL_INCLINE($PCRE2_CFLAGS) PHP_EVAL_LIBLINE($PCRE2_LIBS) AC_DEFINE(PCRE2_CODE_UNIT_WIDTH, 8, [ ]) - AC_DEFINE(HAVE_PCRE, 1, [ ]) if test "$PHP_PCRE_JIT" != "no"; then AC_CACHE_CHECK([for JIT support in PCRE2], ac_cv_have_pcre2_jit, [ diff --git a/ext/pcre/pcre2lib/config.h b/ext/pcre/pcre2lib/config.h index 7864897743..9bd2a9e1ba 100644 --- a/ext/pcre/pcre2lib/config.h +++ b/ext/pcre/pcre2lib/config.h @@ -20,12 +20,12 @@ #endif /* Define to any value for valgrind support to find invalid memory reads. */ -#if HAVE_PCRE_VALGRIND_SUPPORT +#ifdef HAVE_PCRE_VALGRIND_SUPPORT #define SUPPORT_VALGRIND 1 #endif /* Define to any value to enable support for Just-In-Time compiling. */ -#if HAVE_PCRE_JIT_SUPPORT +#ifdef HAVE_PCRE_JIT_SUPPORT #define SUPPORT_JIT #endif diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 39896bb07b..4a796062ec 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -20,6 +18,7 @@ #include "php_ini.h" #include "php_globals.h" #include "php_pcre.h" +#include "php_pcre_arginfo.h" #include "ext/standard/info.h" #include "ext/standard/basic_functions.h" #include "zend_smart_str.h" @@ -50,21 +49,9 @@ struct _pcre_cache_entry { uint32_t capture_count; uint32_t name_count; uint32_t compile_options; - uint32_t extra_compile_options; uint32_t refcount; }; -enum { - PHP_PCRE_NO_ERROR = 0, - PHP_PCRE_INTERNAL_ERROR, - PHP_PCRE_BACKTRACK_LIMIT_ERROR, - PHP_PCRE_RECURSION_LIMIT_ERROR, - PHP_PCRE_BAD_UTF8_ERROR, - PHP_PCRE_BAD_UTF8_OFFSET_ERROR, - PHP_PCRE_JIT_STACKLIMIT_ERROR -}; - - PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre) #ifdef HAVE_PCRE_JIT_SUPPORT @@ -72,6 +59,7 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre) #define PCRE_JIT_STACK_MAX_SIZE (192 * 1024) ZEND_TLS pcre2_jit_stack *jit_stack = NULL; #endif +/* General context using (infallible) system allocator. */ ZEND_TLS pcre2_general_context *gctx = NULL; /* These two are global per thread for now. Though it is possible to use these per pattern. Either one can copy it and use in pce, or one does no global @@ -140,6 +128,33 @@ static void pcre_handle_exec_error(int pcre_code) /* {{{ */ } /* }}} */ +static const char *php_pcre_get_error_msg(php_pcre_error_code error_code) /* {{{ */ +{ + switch (error_code) { + case PHP_PCRE_NO_ERROR: + return "No error"; + case PHP_PCRE_INTERNAL_ERROR: + return "Internal error"; + case PHP_PCRE_BAD_UTF8_ERROR: + return "Malformed UTF-8 characters, possibly incorrectly encoded"; + case PHP_PCRE_BAD_UTF8_OFFSET_ERROR: + return "The offset did not correspond to the beginning of a valid UTF-8 code point"; + case PHP_PCRE_BACKTRACK_LIMIT_ERROR: + return "Backtrack limit exhausted"; + case PHP_PCRE_RECURSION_LIMIT_ERROR: + return "Recursion limit exhausted"; + +#ifdef HAVE_PCRE_JIT_SUPPORT + case PHP_PCRE_JIT_STACKLIMIT_ERROR: + return "JIT stack limit exhausted"; +#endif + + default: + return "Unknown error"; + } +} +/* }}} */ + static void php_free_pcre_cache(zval *data) /* {{{ */ { pcre_cache_entry *pce = (pcre_cache_entry *) Z_PTR_P(data); @@ -159,17 +174,25 @@ static void php_efree_pcre_cache(zval *data) /* {{{ */ /* }}} */ static void *php_pcre_malloc(PCRE2_SIZE size, void *data) -{/*{{{*/ - void *p = pemalloc(size, 1); - return p; -}/*}}}*/ +{ + return pemalloc(size, 1); +} static void php_pcre_free(void *block, void *data) -{/*{{{*/ +{ pefree(block, 1); -}/*}}}*/ +} + +static void *php_pcre_emalloc(PCRE2_SIZE size, void *data) +{ + return emalloc(size); +} + +static void php_pcre_efree(void *block, void *data) +{ + efree(block); +} -#define PHP_PCRE_DEFAULT_EXTRA_COPTIONS PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL #define PHP_PCRE_PREALLOC_MDATA_SIZE 32 static void php_pcre_init_pcre2(uint8_t jit) @@ -190,12 +213,6 @@ static void php_pcre_init_pcre2(uint8_t jit) } } - /* XXX The 'X' modifier is the default behavior in PCRE2. This option is - called dangerous in the manual, as typos in patterns can cause - unexpected results. We might want to to switch to the default PCRE2 - behavior, too, thus causing a certain BC break. */ - pcre2_set_compile_extra_options(cctx, PHP_PCRE_DEFAULT_EXTRA_COPTIONS); - if (!mctx) { mctx = pcre2_match_context_create(gctx); if (!mctx) { @@ -469,6 +486,12 @@ static PHP_RINIT_FUNCTION(pcre) mdata_used = 0; #endif + PCRE_G(error_code) = PHP_PCRE_NO_ERROR; + PCRE_G(gctx_zmm) = pcre2_general_context_create(php_pcre_emalloc, php_pcre_efree, NULL); + if (!PCRE_G(gctx_zmm)) { + return FAILURE; + } + if (PCRE_G(per_request_cache)) { zend_hash_init(&PCRE_G(pcre_cache), 0, NULL, php_efree_pcre_cache, 0); } @@ -479,6 +502,9 @@ static PHP_RINIT_FUNCTION(pcre) static PHP_RSHUTDOWN_FUNCTION(pcre) { + pcre2_general_context_free(PCRE_G(gctx_zmm)); + PCRE_G(gctx_zmm) = NULL; + if (PCRE_G(per_request_cache)) { zend_hash_destroy(&PCRE_G(pcre_cache)); } @@ -548,12 +574,12 @@ static zend_string **make_subpats_table(uint32_t num_subpats, pcre_cache_entry * /* {{{ static calculate_unit_length */ /* Calculates the byte length of the next character. Assumes valid UTF-8 for PCRE2_UTF. */ -static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, char *start) +static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, const char *start) { size_t unit_len; if (pce->compile_options & PCRE2_UTF) { - char *end = start; + const char *end = start; /* skip continuation bytes */ while ((*++end & 0xC0) == 0x80); @@ -565,13 +591,11 @@ static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, ch } /* }}} */ -/* {{{ pcre_get_compiled_regex_cache - */ +/* {{{ pcre_get_compiled_regex_cache */ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, int locale_aware) { pcre2_code *re = NULL; uint32_t coptions = 0; - uint32_t extra_coptions = PHP_PCRE_DEFAULT_EXTRA_COPTIONS; PCRE2_UCHAR error[128]; PCRE2_SIZE erroffset; int errnumber; @@ -589,11 +613,10 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in zend_string *key; pcre_cache_entry *ret; - if (locale_aware && BG(locale_string) && - (ZSTR_LEN(BG(locale_string)) != 1 && ZSTR_VAL(BG(locale_string))[0] != 'C')) { - key = zend_string_alloc(ZSTR_LEN(regex) + ZSTR_LEN(BG(locale_string)) + 1, 0); - memcpy(ZSTR_VAL(key), ZSTR_VAL(BG(locale_string)), ZSTR_LEN(BG(locale_string)) + 1); - memcpy(ZSTR_VAL(key) + ZSTR_LEN(BG(locale_string)), ZSTR_VAL(regex), ZSTR_LEN(regex) + 1); + if (locale_aware && BG(ctype_string)) { + key = zend_string_concat2( + ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)), + ZSTR_VAL(regex), ZSTR_LEN(regex)); } else { key = regex; } @@ -705,8 +728,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in case 'A': coptions |= PCRE2_ANCHORED; break; case 'D': coptions |= PCRE2_DOLLAR_ENDONLY;break; case 'S': /* Pass. */ break; + case 'X': /* Pass. */ break; case 'U': coptions |= PCRE2_UNGREEDY; break; - case 'X': extra_coptions &= ~PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL; break; case 'u': coptions |= PCRE2_UTF; /* In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII characters, even in UTF-8 mode. However, this can be changed by setting @@ -751,7 +774,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in } if (key != regex) { - tables = (uint8_t *)zend_hash_find_ptr(&char_tables, BG(locale_string)); + tables = (uint8_t *)zend_hash_find_ptr(&char_tables, BG(ctype_string)); if (!tables) { zend_string *_k; tables = pcre2_maketables(gctx); @@ -762,7 +785,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in efree(pattern); return NULL; } - _k = zend_string_init(ZSTR_VAL(BG(locale_string)), ZSTR_LEN(BG(locale_string)), 1); + _k = zend_string_init(ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)), 1); GC_MAKE_PERSISTENT_LOCAL(_k); zend_hash_add_ptr(&char_tables, _k, (void *)tables); zend_string_release(_k); @@ -770,19 +793,9 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in pcre2_set_character_tables(cctx, tables); } - /* Set extra options for the compile context. */ - if (PHP_PCRE_DEFAULT_EXTRA_COPTIONS != extra_coptions) { - pcre2_set_compile_extra_options(cctx, extra_coptions); - } - /* Compile pattern and display a warning if compilation failed. */ re = pcre2_compile((PCRE2_SPTR)pattern, pattern_len, coptions, &errnumber, &erroffset, cctx); - /* Reset the compile context extra options to default. */ - if (PHP_PCRE_DEFAULT_EXTRA_COPTIONS != extra_coptions) { - pcre2_set_compile_extra_options(cctx, PHP_PCRE_DEFAULT_EXTRA_COPTIONS); - } - if (re == NULL) { if (key != regex) { zend_string_release_ex(key, 0); @@ -832,7 +845,6 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in new_entry.re = re; new_entry.preg_options = poptions; new_entry.compile_options = coptions; - new_entry.extra_compile_options = extra_coptions; new_entry.refcount = 0; rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count); @@ -881,16 +893,14 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in } /* }}} */ -/* {{{ pcre_get_compiled_regex_cache - */ +/* {{{ pcre_get_compiled_regex_cache */ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex) { return pcre_get_compiled_regex_cache_ex(regex, 1); } /* }}} */ -/* {{{ pcre_get_compiled_regex - */ +/* {{{ pcre_get_compiled_regex */ PHPAPI pcre2_code *pcre_get_compiled_regex(zend_string *regex, uint32_t *capture_count) { pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex); @@ -903,8 +913,7 @@ PHPAPI pcre2_code *pcre_get_compiled_regex(zend_string *regex, uint32_t *capture } /* }}} */ -/* {{{ pcre_get_compiled_regex_ex - */ +/* {{{ pcre_get_compiled_regex_ex */ PHPAPI pcre2_code* pcre_get_compiled_regex_ex(zend_string *regex, uint32_t *capture_count, uint32_t *preg_options, uint32_t *compile_options) { pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex); @@ -972,13 +981,7 @@ static void init_unmatched_empty_pair() { static zend_always_inline void populate_match_value_str( zval *val, const char *subject, PCRE2_SIZE start_offset, PCRE2_SIZE end_offset) { - if (start_offset == end_offset) { - ZVAL_EMPTY_STRING(val); - } else if (start_offset + 1 == end_offset) { - ZVAL_INTERNED_STR(val, ZSTR_CHAR((unsigned char) subject[start_offset])); - } else { - ZVAL_STRINGL(val, subject + start_offset, end_offset - start_offset); - } + ZVAL_STRINGL_FAST(val, subject + start_offset, end_offset - start_offset); } static inline void populate_match_value( @@ -1044,7 +1047,7 @@ static inline void add_offset_pair( /* }}} */ static void populate_subpat_array( - zval *subpats, char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, + zval *subpats, const char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, uint32_t num_subpats, int count, const PCRE2_SPTR mark, zend_long flags) { zend_bool offset_capture = (flags & PREG_OFFSET_CAPTURE) != 0; zend_bool unmatched_as_null = (flags & PREG_UNMATCHED_AS_NULL) != 0; @@ -1128,7 +1131,7 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * Z_PARAM_ZVAL(subpats) Z_PARAM_LONG(flags) Z_PARAM_LONG(start_offset) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END(); /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { @@ -1209,8 +1212,8 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, } if ((global && (subpats_order < PREG_PATTERN_ORDER || subpats_order > PREG_SET_ORDER)) || (!global && subpats_order != 0)) { - php_error_docref(NULL, E_WARNING, "Invalid flags specified"); - return; + zend_argument_value_error(4, "must be a PREG_* constant"); + RETURN_THROWS(); } } else { offset_capture = 0; @@ -1262,7 +1265,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; if (subpat_names) { @@ -1480,24 +1483,21 @@ error: } /* }}} */ -/* {{{ proto int preg_match(string pattern, string subject [, array &subpatterns [, int flags [, int offset]]]) - Perform a Perl-style regular expression match */ -static PHP_FUNCTION(preg_match) +/* {{{ Perform a Perl-style regular expression match */ +PHP_FUNCTION(preg_match) { php_do_pcre_match(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ -/* {{{ proto int preg_match_all(string pattern, string subject [, array &subpatterns [, int flags [, int offset]]]) - Perform a Perl-style global regular expression match */ -static PHP_FUNCTION(preg_match_all) +/* {{{ Perform a Perl-style global regular expression match */ +PHP_FUNCTION(preg_match_all) { php_do_pcre_match(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ -/* {{{ preg_get_backref - */ +/* {{{ preg_get_backref */ static int preg_get_backref(char **str, int *backref) { register char in_brace = 0; @@ -1535,9 +1535,8 @@ static int preg_get_backref(char **str, int *backref) } /* }}} */ -/* {{{ preg_do_repl_func - */ -static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, uint32_t num_subpats, int count, const PCRE2_SPTR mark, zend_long flags) +/* {{{ preg_do_repl_func */ +static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cache *fcc, const char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, uint32_t num_subpats, int count, const PCRE2_SPTR mark, zend_long flags) { zend_string *result_str; zval retval; /* Function return value */ @@ -1549,7 +1548,6 @@ static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cach fci->retval = &retval; fci->param_count = 1; fci->params = &arg; - fci->no_separation = 0; if (zend_call_function(fci, fcc) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { if (EXPECTED(Z_TYPE(retval) == IS_STRING)) { @@ -1572,11 +1570,10 @@ static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cach } /* }}} */ -/* {{{ php_pcre_replace - */ +/* {{{ php_pcre_replace */ PHPAPI zend_string *php_pcre_replace(zend_string *regex, zend_string *subject_str, - char *subject, size_t subject_len, + const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count) { @@ -1602,7 +1599,7 @@ PHPAPI zend_string *php_pcre_replace(zend_string *regex, /* }}} */ /* {{{ php_pcre_replace_impl() */ -PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count) +PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count) { uint32_t options; /* Execution options */ int count; /* Count of matched subpatterns */ @@ -1616,10 +1613,10 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su size_t last_end_offset; /* Where the last search ended */ char *walkbuf, /* Location of current replacement in the result */ *walk, /* Used to walk the replacement string */ - *match, /* The current match */ - *piece, /* The current piece of subject */ - *replace_end, /* End of replacement string */ walk_last; /* Last walked character */ + const char *match, /* The current match */ + *piece, /* The current piece of subject */ + *replace_end; /* End of replacement string */ size_t result_len; /* Length of result */ zend_string *result; /* Result of replacement */ pcre2_match_data *match_data; @@ -1639,7 +1636,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; return NULL; @@ -1844,7 +1841,7 @@ error: /* }}} */ /* {{{ php_pcre_replace_func_impl() */ -static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_string *subject_str, 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) +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) { uint32_t options; /* Execution options */ int count; /* Count of matched subpatterns */ @@ -1855,7 +1852,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin size_t alloc_len; /* Actual allocated length */ PCRE2_SIZE start_offset; /* Where the new search starts */ size_t last_end_offset; /* Where the last search ended */ - char *match, /* The current match */ + const char *match, /* The current match */ *piece; /* The current piece of subject */ size_t result_len; /* Length of result */ zend_string *result; /* Result of replacement */ @@ -1893,7 +1890,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin mdata_used = 1; match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; if (subpat_names) { @@ -2058,8 +2055,7 @@ error: } /* }}} */ -/* {{{ php_pcre_replace_func - */ +/* {{{ php_pcre_replace_func */ static zend_always_inline zend_string *php_pcre_replace_func(zend_string *regex, zend_string *subject_str, zend_fcall_info *fci, zend_fcall_info_cache *fcc, @@ -2082,50 +2078,47 @@ 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) +/* {{{ php_pcre_replace_array */ +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; @@ -2135,7 +2128,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) { @@ -2145,13 +2138,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; @@ -2166,87 +2154,81 @@ 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) +/* {{{ php_replace_in_subject */ +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) +/* {{{ php_replace_in_subject_func */ +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) +/* {{{ preg_replace_func_impl */ +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 { @@ -2258,13 +2240,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); @@ -2274,6 +2261,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(); } @@ -2281,11 +2269,16 @@ 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) +/* {{{ preg_replace_common */ +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; @@ -2293,33 +2286,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_ARRAY_HT_OR_STR(regex_ht, regex_str) + Z_PARAM_ARRAY_HT_OR_STR(replace_ht, replace_str) + Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str) 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) { - php_error_docref(NULL, E_WARNING, "Parameter mismatch, pattern is a string while replacement is an array"); - RETURN_FALSE; - } + /* 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 ($replacement) 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); @@ -2336,17 +2320,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 */ @@ -2360,6 +2346,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(); } @@ -2369,19 +2356,21 @@ static void preg_replace_common(INTERNAL_FUNCTION_PARAMETERS, int is_filter) } /* }}} */ -/* {{{ proto mixed preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, int &count]]) - Perform Perl-style regular expression replacement. */ -static PHP_FUNCTION(preg_replace) +/* {{{ 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); } /* }}} */ -/* {{{ proto mixed preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit [, int &count]]) - Perform Perl-style regular expression replacement using replacement callback. */ -static PHP_FUNCTION(preg_replace_callback) +/* {{{ Perform Perl-style regular expression replacement using replacement callback. */ +PHP_FUNCTION(preg_replace_callback) { - zval *regex, *replace, *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; @@ -2389,49 +2378,39 @@ static PHP_FUNCTION(preg_replace_callback) /* Get function parameters and do error-checking. */ ZEND_PARSE_PARAMETERS_START(3, 6) - Z_PARAM_ZVAL(regex) - Z_PARAM_ZVAL(replace) - Z_PARAM_ZVAL(subject) + Z_PARAM_ARRAY_HT_OR_STR(regex_ht, regex_str) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(limit) Z_PARAM_ZVAL(zcount) Z_PARAM_LONG(flags) ZEND_PARSE_PARAMETERS_END(); - 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, "Requires argument 2, '%s', to be a valid callback", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - ZVAL_STR(return_value, zval_get_string(subject)); - return; - } - - fci.size = sizeof(fci); - fci.object = NULL; - ZVAL_COPY_VALUE(&fci.function_name, replace); - - 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); } } /* }}} */ -/* {{{ proto mixed preg_replace_callback_array(array pattern, mixed subject [, int limit [, int &count]]) - Perform Perl-style regular expression replacement using replacement callback. */ -static PHP_FUNCTION(preg_replace_callback_array) +/* {{{ 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, *zcount = NULL; + HashTable *pattern, *subject_ht; + zend_string *subject_str, *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_ZVAL(subject) + Z_PARAM_ARRAY_HT(pattern) + Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(limit) Z_PARAM_ZVAL(zcount) @@ -2440,62 +2419,80 @@ static PHP_FUNCTION(preg_replace_callback_array) fci.size = sizeof(fci); fci.object = NULL; + fci.named_params = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pattern), str_idx, replace) { - if (str_idx) { - ZVAL_STR_COPY(®ex, str_idx); - } else { + if (subject_ht) { + GC_TRY_ADDREF(subject_ht); + } else { + GC_TRY_ADDREF(subject_str); + } + + 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(); + RETVAL_NULL(); + goto error; } 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_string_release_ex(callback_name, 0); - zval_ptr_dtor(®ex); - zval_ptr_dtor(return_value); - ZVAL_COPY(return_value, subject); - return; + zend_argument_type_error(1, "must contain only valid callbacks"); + goto error; } ZVAL_COPY_VALUE(&fci.function_name, replace); - replace_count += preg_replace_func_impl(&zv, ®ex, &fci, &fcc, subject, limit, flags); - if (subject != return_value) { - subject = return_value; - } else { - zval_ptr_dtor(return_value); + replace_count += preg_replace_func_impl(&zv, str_idx_regex, /* regex_ht */ NULL, &fci, &fcc, + subject_str, subject_ht, limit, flags); + switch (Z_TYPE(zv)) { + case IS_ARRAY: + ZEND_ASSERT(subject_ht); + zend_array_release(subject_ht); + subject_ht = Z_ARR(zv); + break; + case IS_STRING: + ZEND_ASSERT(subject_str); + zend_string_release(subject_str); + subject_str = Z_STR(zv); + break; + case IS_NULL: + RETVAL_NULL(); + goto error; + EMPTY_SWITCH_DEFAULT_CASE() } - zval_ptr_dtor(®ex); - - ZVAL_COPY_VALUE(return_value, &zv); - - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor(return_value); - RETURN_NULL(); + if (EG(exception)) { + goto error; } } ZEND_HASH_FOREACH_END(); if (zcount) { ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count); } + + if (subject_ht) { + RETURN_ARR(subject_ht); + } else { + RETURN_STR(subject_str); + } + +error: + if (subject_ht) { + zend_array_release(subject_ht); + } else { + zend_string_release(subject_str); + } } /* }}} */ -/* {{{ proto mixed preg_filter(mixed regex, mixed replace, mixed subject [, int limit [, int &count]]) - Perform Perl-style regular expression replacement and only return matches. */ -static PHP_FUNCTION(preg_filter) +/* {{{ 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); } /* }}} */ -/* {{{ proto array preg_split(string pattern, string subject [, int limit [, int flags]]) - Split string into an array using a perl-style regular expression as a delimiter */ -static PHP_FUNCTION(preg_split) +/* {{{ Split string into an array using a perl-style regular expression as a delimiter */ +PHP_FUNCTION(preg_split) { zend_string *regex; /* Regular expression */ zend_string *subject; /* String to match against */ @@ -2510,7 +2507,7 @@ static PHP_FUNCTION(preg_split) Z_PARAM_OPTIONAL Z_PARAM_LONG(limit_val) Z_PARAM_LONG(flags) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END(); /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { @@ -2523,8 +2520,7 @@ static PHP_FUNCTION(preg_split) } /* }}} */ -/* {{{ php_pcre_split - */ +/* {{{ php_pcre_split */ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, zval *return_value, zend_long limit_val, zend_long flags) { @@ -2567,7 +2563,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; zval_ptr_dtor(return_value); @@ -2714,9 +2710,8 @@ last: } /* }}} */ -/* {{{ proto string preg_quote(string str [, string delim_char]) - Quote regular expression characters plus an optional character */ -static PHP_FUNCTION(preg_quote) +/* {{{ Quote regular expression characters plus an optional character */ +PHP_FUNCTION(preg_quote) { zend_string *str; /* Input string argument */ zend_string *delim = NULL; /* Additional delimiter argument */ @@ -2851,9 +2846,8 @@ static PHP_FUNCTION(preg_quote) } /* }}} */ -/* {{{ proto array preg_grep(string regex, array input [, int flags]) - Searches array and returns entries which match regex */ -static PHP_FUNCTION(preg_grep) +/* {{{ Searches array and returns entries which match regex */ +PHP_FUNCTION(preg_grep) { zend_string *regex; /* Regular expression */ zval *input; /* Input array */ @@ -2903,7 +2897,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; return; @@ -2968,9 +2962,8 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } /* }}} */ -/* {{{ proto int preg_last_error() - Returns the error code of the last regexp execution. */ -static PHP_FUNCTION(preg_last_error) +/* {{{ Returns the error code of the last regexp execution. */ +PHP_FUNCTION(preg_last_error) { ZEND_PARSE_PARAMETERS_NONE(); @@ -2978,90 +2971,21 @@ static PHP_FUNCTION(preg_last_error) } /* }}} */ -/* {{{ module definition structures */ +/* {{{ Returns the error message of the last regexp execution. */ +PHP_FUNCTION(preg_last_error_msg) +{ + ZEND_PARSE_PARAMETERS_NONE(); -/* {{{ arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_match, 0, 0, 2) - ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(1, subpatterns) /* array */ - ZEND_ARG_INFO(0, flags) - ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_match_all, 0, 0, 2) - ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(1, subpatterns) /* array */ - ZEND_ARG_INFO(0, flags) - ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace, 0, 0, 3) - ZEND_ARG_INFO(0, regex) - ZEND_ARG_INFO(0, replace) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(0, limit) - ZEND_ARG_INFO(1, count) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace_callback, 0, 0, 3) - ZEND_ARG_INFO(0, regex) - ZEND_ARG_INFO(0, callback) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(0, limit) - ZEND_ARG_INFO(1, count) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace_callback_array, 0, 0, 2) - ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(0, limit) - ZEND_ARG_INFO(1, count) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_split, 0, 0, 2) - ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, subject) - ZEND_ARG_INFO(0, limit) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_quote, 0, 0, 1) - ZEND_ARG_INFO(0, str) - ZEND_ARG_INFO(0, delim_char) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_grep, 0, 0, 2) - ZEND_ARG_INFO(0, regex) - ZEND_ARG_INFO(0, input) /* array */ - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_preg_last_error, 0) -ZEND_END_ARG_INFO() + RETURN_STRING(php_pcre_get_error_msg(PCRE_G(error_code))); +} /* }}} */ -static const zend_function_entry pcre_functions[] = { - PHP_FE(preg_match, arginfo_preg_match) - PHP_FE(preg_match_all, arginfo_preg_match_all) - PHP_FE(preg_replace, arginfo_preg_replace) - PHP_FE(preg_replace_callback, arginfo_preg_replace_callback) - PHP_FE(preg_replace_callback_array, arginfo_preg_replace_callback_array) - PHP_FE(preg_filter, arginfo_preg_replace) - PHP_FE(preg_split, arginfo_preg_split) - PHP_FE(preg_quote, arginfo_preg_quote) - PHP_FE(preg_grep, arginfo_preg_grep) - PHP_FE(preg_last_error, arginfo_preg_last_error) - PHP_FE_END -}; +/* {{{ module definition structures */ zend_module_entry pcre_module_entry = { STANDARD_MODULE_HEADER, "pcre", - pcre_functions, + ext_functions, PHP_MINIT(pcre), PHP_MSHUTDOWN(pcre), PHP_RINIT(pcre), diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index b375981df3..e9f5e34ab9 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -19,7 +17,7 @@ #ifndef PHP_PCRE_H #define PHP_PCRE_H -#if HAVE_BUNDLED_PCRE +#ifdef HAVE_BUNDLED_PCRE #include "pcre2lib/pcre2.h" #else #include "pcre2.h" @@ -27,7 +25,7 @@ #include <locale.h> -PHPAPI zend_string *php_pcre_replace(zend_string *regex, zend_string *subject_str, char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count); +PHPAPI zend_string *php_pcre_replace(zend_string *regex, zend_string *subject_str, const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count); PHPAPI pcre2_code* pcre_get_compiled_regex(zend_string *regex, uint32_t *capture_count); PHPAPI pcre2_code* pcre_get_compiled_regex_ex(zend_string *regex, uint32_t *capture_count, uint32_t *preg_options, uint32_t *coptions); @@ -39,13 +37,23 @@ extern zend_module_entry pcre_module_entry; typedef struct _pcre_cache_entry pcre_cache_entry; +typedef enum { + PHP_PCRE_NO_ERROR = 0, + PHP_PCRE_INTERNAL_ERROR, + PHP_PCRE_BACKTRACK_LIMIT_ERROR, + PHP_PCRE_RECURSION_LIMIT_ERROR, + PHP_PCRE_BAD_UTF8_ERROR, + PHP_PCRE_BAD_UTF8_OFFSET_ERROR, + PHP_PCRE_JIT_STACKLIMIT_ERROR +} php_pcre_error_code; + PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex); PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, int locale_aware); PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, zval *return_value, zval *subpats, int global, int use_flags, zend_long flags, zend_off_t start_offset); -PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, char *subject, size_t subject_len, zend_string *replace_str, +PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count); PHPAPI void php_pcre_split_impl( pcre_cache_entry *pce, zend_string *subject_str, zval *return_value, @@ -72,10 +80,12 @@ ZEND_BEGIN_MODULE_GLOBALS(pcre) zend_bool jit; #endif zend_bool per_request_cache; - int error_code; + php_pcre_error_code error_code; /* Used for unmatched subpatterns in OFFSET_CAPTURE mode */ zval unmatched_null_pair; zval unmatched_empty_pair; + /* General context using per-request allocator (ZMM). */ + pcre2_general_context *gctx_zmm; ZEND_END_MODULE_GLOBALS(pcre) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(pcre) diff --git a/ext/pcre/php_pcre.stub.php b/ext/pcre/php_pcre.stub.php new file mode 100644 index 0000000000..b2862a2f62 --- /dev/null +++ b/ext/pcre/php_pcre.stub.php @@ -0,0 +1,31 @@ +<?php + +/** @generate-function-entries */ + +/** @param array $matches */ +function preg_match(string $pattern, string $subject, &$matches = null, int $flags = 0, int $offset = 0): int|false {} + +/** @param array $matches */ +function preg_match_all(string $pattern, string $subject, &$matches = null, int $flags = 0, int $offset = 0): int|false|null {} + +/** @param int $count */ +function preg_replace(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, &$count = null): string|array|null {} + +/** @param int $count */ +function preg_filter(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, &$count = null): string|array|null {} + +/** @param int $count */ +function preg_replace_callback(string|array $pattern, callable $callback, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {} + +/** @param int $count */ +function preg_replace_callback_array(array $pattern, string|array $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 $delimiter = null): string {} + +function preg_grep(string $pattern, array $array, int $flags = 0): array|false {} + +function preg_last_error(): int {} + +function preg_last_error_msg(): string {} diff --git a/ext/pcre/php_pcre_arginfo.h b/ext/pcre/php_pcre_arginfo.h new file mode 100644 index 0000000000..c53f35559e --- /dev/null +++ b/ext/pcre/php_pcre_arginfo.h @@ -0,0 +1,98 @@ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: 2e5a9edc9635edd4f5a00e9d888fb34c1746a5b8 */ + +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) + ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, matches, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match_all, 0, 2, MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_NULL) + ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, matches, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "0") +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_TYPE_MASK(0, pattern, MAY_BE_STRING|MAY_BE_ARRAY, NULL) + ZEND_ARG_TYPE_MASK(0, replacement, 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() + +#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_TYPE_MASK(0, pattern, MAY_BE_STRING|MAY_BE_ARRAY, NULL) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + 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") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback_array, 0, 2, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL) + ZEND_ARG_TYPE_INFO(0, pattern, IS_ARRAY, 0) + 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") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_split, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_preg_quote, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, delimiter, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_grep, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_preg_last_error, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_preg_last_error_msg, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + + +ZEND_FUNCTION(preg_match); +ZEND_FUNCTION(preg_match_all); +ZEND_FUNCTION(preg_replace); +ZEND_FUNCTION(preg_filter); +ZEND_FUNCTION(preg_replace_callback); +ZEND_FUNCTION(preg_replace_callback_array); +ZEND_FUNCTION(preg_split); +ZEND_FUNCTION(preg_quote); +ZEND_FUNCTION(preg_grep); +ZEND_FUNCTION(preg_last_error); +ZEND_FUNCTION(preg_last_error_msg); + + +static const zend_function_entry ext_functions[] = { + ZEND_FE(preg_match, arginfo_preg_match) + ZEND_FE(preg_match_all, arginfo_preg_match_all) + ZEND_FE(preg_replace, arginfo_preg_replace) + ZEND_FE(preg_filter, arginfo_preg_filter) + ZEND_FE(preg_replace_callback, arginfo_preg_replace_callback) + ZEND_FE(preg_replace_callback_array, arginfo_preg_replace_callback_array) + ZEND_FE(preg_split, arginfo_preg_split) + ZEND_FE(preg_quote, arginfo_preg_quote) + ZEND_FE(preg_grep, arginfo_preg_grep) + ZEND_FE(preg_last_error, arginfo_preg_last_error) + ZEND_FE(preg_last_error_msg, arginfo_preg_last_error_msg) + ZEND_FE_END +}; diff --git a/ext/pcre/tests/001.phpt b/ext/pcre/tests/001.phpt index 313f7fdc67..482ba1b732 100644 --- a/ext/pcre/tests/001.phpt +++ b/ext/pcre/tests/001.phpt @@ -4,14 +4,14 @@ abusing preg_match() <?php foreach (array('2006-05-13', '06-12-12', 'data: "12-Aug-87"') as $s) { - var_dump(preg_match('~ - (?P<date> - (?P<year>(\d{2})?\d\d) - - (?P<month>(?:\d\d|[a-zA-Z]{2,3})) - - (?P<day>[0-3]?\d)) - ~x', $s, $m)); + var_dump(preg_match('~ + (?P<date> + (?P<year>(\d{2})?\d\d) - + (?P<month>(?:\d\d|[a-zA-Z]{2,3})) - + (?P<day>[0-3]?\d)) + ~x', $s, $m)); - var_dump($m); + var_dump($m); } ?> diff --git a/ext/pcre/tests/002.phpt b/ext/pcre/tests/002.phpt index d4780447bc..641cffb05e 100644 --- a/ext/pcre/tests/002.phpt +++ b/ext/pcre/tests/002.phpt @@ -3,11 +3,12 @@ preg_* with bogus vals --FILE-- <?php -var_dump(preg_match()); -var_dump(preg_match_all()); -var_dump(preg_match_all('//', '', $dummy, 0xdead)); +try { + preg_match_all('//', '', $dummy, 0xdead); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} -var_dump(preg_quote()); var_dump(preg_quote('')); var_dump(preg_replace('/(.)/', '${1}${1', 'abc')); @@ -16,22 +17,12 @@ var_dump(preg_replace('/(.)/e', 'for ($', 'abc')); ?> --EXPECTF-- -Warning: preg_match() expects at least 2 parameters, 0 given in %s002.php on line 3 -bool(false) - -Warning: preg_match_all() expects at least 2 parameters, 0 given in %s002.php on line 4 -bool(false) - -Warning: preg_match_all(): Invalid flags specified in %s002.php on line 5 -NULL - -Warning: preg_quote() expects at least 1 parameter, 0 given in %s002.php on line 7 -NULL +preg_match_all(): Argument #4 ($flags) must be a PREG_* constant string(0) "" string(12) "a${1b${1c${1" -Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 8 in %s002.php on line 11 +Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 8 in %s002.php on line %d NULL -Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in %s on line 12 +Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in %s on line %d NULL diff --git a/ext/pcre/tests/003.phpt b/ext/pcre/tests/003.phpt index e697c375c6..b5fce13194 100644 --- a/ext/pcre/tests/003.phpt +++ b/ext/pcre/tests/003.phpt @@ -4,15 +4,15 @@ abusing preg_match_all() <?php foreach (array(PREG_PATTERN_ORDER, PREG_SET_ORDER) as $flag) { - var_dump(preg_match_all('~ - (?P<date> - (?P<year>(\d{2})?\d\d) - - (?P<month>(?:\d\d|[a-zA-Z]{2,3})) - - (?P<day>[0-3]?\d)) - ~x', - '2006-05-13 e outra data: "12-Aug-37"', $m, $flag)); + var_dump(preg_match_all('~ + (?P<date> + (?P<year>(\d{2})?\d\d) - + (?P<month>(?:\d\d|[a-zA-Z]{2,3})) - + (?P<day>[0-3]?\d)) + ~x', + '2006-05-13 e outra data: "12-Aug-37"', $m, $flag)); - var_dump($m); + var_dump($m); } ?> --EXPECT-- diff --git a/ext/pcre/tests/005.phpt b/ext/pcre/tests/005.phpt index 5eff83eba6..f988da054a 100644 --- a/ext/pcre/tests/005.phpt +++ b/ext/pcre/tests/005.phpt @@ -63,12 +63,12 @@ ext/ming/ming.o(.text+0x851): In function `zif_ming_setSWFCompression': /p2/var/php_gcov/PHP_5_2/ext/ming/ming.c:154: undefined reference to `Ming_setSWFCompression' "; - // Regular expression to select the error and warning information - // tuned for gcc 3.4, 4.0 and 4.1 - $gcc_regex = '/^((.+)(\(\.text\+0x[[:xdigit:]]+\))?: In function [`\'](\w+)\':\s+)?'. - '((?(1)(?(3)[^:\n]+|\2)|[^:\n]+)):(\d+): (?:(error|warning):\s+)?(.+)'. - str_repeat('(?:\s+\5:(\d+): (?:(error|warning):\s+)?(.+))?', 99). // capture up to 100 errors - '/mS'; + // Regular expression to select the error and warning information + // tuned for gcc 3.4, 4.0 and 4.1 + $gcc_regex = '/^((.+)(\(\.text\+0x[[:xdigit:]]+\))?: In function [`\'](\w+)\':\s+)?'. + '((?(1)(?(3)[^:\n]+|\2)|[^:\n]+)):(\d+): (?:(error|warning):\s+)?(.+)'. + str_repeat('(?:\s+\5:(\d+): (?:(error|warning):\s+)?(.+))?', 99). // capture up to 100 errors + '/mS'; var_dump(preg_match_all($gcc_regex, $sampledata, $m, PREG_SET_ORDER)); diff --git a/ext/pcre/tests/007.phpt b/ext/pcre/tests/007.phpt index 776bec27b2..d2bfb7ee6f 100644 --- a/ext/pcre/tests/007.phpt +++ b/ext/pcre/tests/007.phpt @@ -3,17 +3,17 @@ preg_replace_callback() with callback that modifies subject string --SKIPIF-- <?php if (@preg_match('/./u', '') === false) { - die('skip no utf8 support in PCRE library'); + die('skip no utf8 support in PCRE library'); } ?> --FILE-- <?php function evil($x) { - global $txt; - $txt[3] = "\xFF"; - var_dump($x); - return $x[0]; + global $txt; + $txt[3] = "\xFF"; + var_dump($x); + return $x[0]; } $txt = "ola123"; diff --git a/ext/pcre/tests/backtrack_limit.phpt b/ext/pcre/tests/backtrack_limit.phpt index 3f0d8e6446..3b6f7786a2 100644 --- a/ext/pcre/tests/backtrack_limit.phpt +++ b/ext/pcre/tests/backtrack_limit.phpt @@ -3,7 +3,7 @@ Backtracking limit --SKIPIF-- <?php if (@preg_match_all('/\p{N}/', '0123456789', $dummy) === false) { - die("skip no support for \p support PCRE library"); + die("skip no support for \p support PCRE library"); } ?> --INI-- diff --git a/ext/pcre/tests/bug20528.phpt b/ext/pcre/tests/bug20528.phpt index 43e548b26e..a067680b05 100644 --- a/ext/pcre/tests/bug20528.phpt +++ b/ext/pcre/tests/bug20528.phpt @@ -2,8 +2,8 @@ Bug #20528 (preg_split() drops characters (re-opens Bug #15413)) --FILE-- <?php - $data = '(#11/19/2002#)'; - var_dump(preg_split('/\b/', $data)); + $data = '(#11/19/2002#)'; + var_dump(preg_split('/\b/', $data)); ?> --EXPECT-- array(7) { diff --git a/ext/pcre/tests/bug21732.phpt b/ext/pcre/tests/bug21732.phpt index 3dfc41e19f..02a13713e2 100644 --- a/ext/pcre/tests/bug21732.phpt +++ b/ext/pcre/tests/bug21732.phpt @@ -1,21 +1,23 @@ --TEST-- Bug #21732 (preg_replace() segfaults with invalid parameters) ---INI-- -error_reporting=0 --FILE-- <?php class foo { - function cb($param) { - var_dump($param); - return "yes!"; - } + function cb($param) { + var_dump($param); + return "yes!"; + } } -var_dump(preg_replace('', array(), '')); +try { + var_dump(preg_replace('', array(), '')); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} var_dump(preg_replace_callback("/(ab)(cd)(e)/", array(new foo(), "cb"), 'abcde')); ?> --EXPECT-- -bool(false) +preg_replace(): Argument #1 ($pattern) must be of type array when argument #2 ($replacement) is an array, string given array(4) { [0]=> string(5) "abcde" diff --git a/ext/pcre/tests/bug26927.phpt b/ext/pcre/tests/bug26927.phpt index 200a534b76..8cc6280afd 100644 --- a/ext/pcre/tests/bug26927.phpt +++ b/ext/pcre/tests/bug26927.phpt @@ -2,9 +2,9 @@ Bug #26927 (preg_quote() does not escape \0) --FILE-- <?php - $str = "a\000b"; - $str_quoted = preg_quote($str); - var_dump(preg_match("!{$str_quoted}!", $str), $str_quoted); + $str = "a\000b"; + $str_quoted = preg_quote($str); + var_dump(preg_match("!{$str_quoted}!", $str), $str_quoted); ?> --EXPECT-- int(1) diff --git a/ext/pcre/tests/bug27103.phpt b/ext/pcre/tests/bug27103.phpt index 0264228aee..9ba70f7a64 100644 --- a/ext/pcre/tests/bug27103.phpt +++ b/ext/pcre/tests/bug27103.phpt @@ -3,16 +3,16 @@ Bug #27103 (preg_split('//u') incorrectly splits UTF-8 strings into octets) --SKIPIF-- <?php if (@preg_match('/./u', '') === false) { - die('skip no utf8 support in PCRE library'); + die('skip no utf8 support in PCRE library'); } ?> --FILE-- <?php function iter($ar) { - foreach ($ar as $c) { - echo htmlentities($c, 0, "UTF-8"), ": ", strlen($c), "\n"; - } + foreach ($ar as $c) { + echo htmlentities($c, 0, "UTF-8"), ": ", strlen($c), "\n"; + } } $teststr = "\xe2\x82\xac hi there"; iter(preg_split('//u', $teststr, -1, PREG_SPLIT_NO_EMPTY)); diff --git a/ext/pcre/tests/bug37911.phpt b/ext/pcre/tests/bug37911.phpt index 4f3cb3574d..c9cad1d6d5 100644 --- a/ext/pcre/tests/bug37911.phpt +++ b/ext/pcre/tests/bug37911.phpt @@ -5,8 +5,8 @@ Bug #37911 (preg_replace_callback ignores named groups) function callback($match) { - var_dump($match); - return $match[1].'/'.strlen($match['name']); + var_dump($match); + return $match[1].'/'.strlen($match['name']); } var_dump(preg_replace_callback('|(?P<name>blub)|', 'callback', 'bla blub blah')); diff --git a/ext/pcre/tests/bug41638.phpt b/ext/pcre/tests/bug41638.phpt index 8c907f9903..3ab9a84ac2 100644 --- a/ext/pcre/tests/bug41638.phpt +++ b/ext/pcre/tests/bug41638.phpt @@ -2,7 +2,7 @@ Bug #41638 (pcre 7.0 regression) --FILE-- <?php -$str = "repeater id='loopt' dataSrc=subject colums=2"; +$str = "repeater id='loopt' dataSrc=subject columns=2"; preg_match_all("/(['\"])((.*(\\\\\\1)*)*)\\1/sU",$str,$str_instead); print_r($str_instead); diff --git a/ext/pcre/tests/bug44191.phpt b/ext/pcre/tests/bug44191.phpt index 73fc29cd90..7d0b535dc6 100644 --- a/ext/pcre/tests/bug44191.phpt +++ b/ext/pcre/tests/bug44191.phpt @@ -8,7 +8,7 @@ $array = range(1, 10); preg_grep('/asdf/', $array); foreach ($array as $k => $v) { - print $k; + print $k; } ?> diff --git a/ext/pcre/tests/bug44925.phpt b/ext/pcre/tests/bug44925.phpt index f6e0db4253..c495331b4b 100644 --- a/ext/pcre/tests/bug44925.phpt +++ b/ext/pcre/tests/bug44925.phpt @@ -45,11 +45,11 @@ array(9) { &string(1) "b" } -Notice: Array to string conversion in %sbug44925.php on line 9 +Warning: Array to string conversion in %s on line %d array(0) { } -Notice: Array to string conversion in %sbug44925.php on line 11 +Warning: Array to string conversion in %s on line %d array(7) { [0]=> string(1) "1" diff --git a/ext/pcre/tests/bug47662.phpt b/ext/pcre/tests/bug47662.phpt index abf65e6ca9..84b237864a 100644 --- a/ext/pcre/tests/bug47662.phpt +++ b/ext/pcre/tests/bug47662.phpt @@ -5,7 +5,7 @@ Bug #47662 (support more than 127 named subpatterns) $regex = '@'; for($bar=0; $bar<129; $bar++) { - $regex .= '((?P<x'.$bar.'>))'; + $regex .= '((?P<x'.$bar.'>))'; } $regex .= 'fo+bar@'; diff --git a/ext/pcre/tests/bug70345.phpt b/ext/pcre/tests/bug70345.phpt index 187a3e1e6f..42d4f8b12e 100644 --- a/ext/pcre/tests/bug70345.phpt +++ b/ext/pcre/tests/bug70345.phpt @@ -12,6 +12,7 @@ $subject = "aaaaxyzaaaa"; preg_match($regex, $subject, $matches); var_dump($matches); +?> --EXPECTF-- bool(false) diff --git a/ext/pcre/tests/bug72463.phpt b/ext/pcre/tests/bug72463.phpt index b40a721998..156b692ab0 100644 --- a/ext/pcre/tests/bug72463.phpt +++ b/ext/pcre/tests/bug72463.phpt @@ -3,7 +3,7 @@ Bug #72463 mail fails with invalid argument --SKIPIF-- <?php if(substr(PHP_OS, 0, 3) == "WIN") { - die('skip not for windows'); + die('skip not for windows'); } ?> --INI-- diff --git a/ext/pcre/tests/bug72463_2.phpt b/ext/pcre/tests/bug72463_2.phpt index 1baeb0f2a1..3cc87b47ac 100644 --- a/ext/pcre/tests/bug72463_2.phpt +++ b/ext/pcre/tests/bug72463_2.phpt @@ -3,7 +3,7 @@ Bug #72463 mail fails with invalid argument --SKIPIF-- <?php if(substr(PHP_OS, 0, 3) != "WIN") { - die('skip windows only'); + die('skip windows only'); } ?> --INI-- diff --git a/ext/pcre/tests/bug73392.phpt b/ext/pcre/tests/bug73392.phpt index 90606c9e05..7546f5d99f 100644 --- a/ext/pcre/tests/bug73392.phpt +++ b/ext/pcre/tests/bug73392.phpt @@ -3,25 +3,23 @@ Bug #73392 (A use-after-free in zend allocator management) --FILE-- <?php class Rep { - public function __invoke() { - return "d"; - } + public function __invoke() { + return "d"; + } } class Foo { - public static function rep($rep) { - return "ok"; - } + public static function rep($rep) { + return "ok"; + } } function b() { - return "b"; + return "b"; } var_dump(preg_replace_callback_array( - array( - "/a/" => 'b', "/b/" => function () { return "c"; }, "/c/" => new Rep, "reporting" => array("Foo", "rep"), "a1" => array("Foo", "rep"), - ), 'a')); + array( + "/a/" => 'b', "/b/" => function () { return "c"; }, "/c/" => new Rep, "reporting" => array("Foo", "rep"), "a1" => array("Foo", "rep"), + ), 'a')); ?> --EXPECTF-- Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d - -Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d NULL diff --git a/ext/pcre/tests/bug73483.phpt b/ext/pcre/tests/bug73483.phpt index fd10702527..cbf4a2bdaf 100644 --- a/ext/pcre/tests/bug73483.phpt +++ b/ext/pcre/tests/bug73483.phpt @@ -8,7 +8,7 @@ var_dump(preg_replace_callback($regex, function (array $matches) use($regex) { setlocale(LC_ALL, "en_US"); $ret = preg_replace($regex, "okey", $matches[0]); setlocale(LC_ALL, "C"); - return $ret; + return $ret; }, "dummy")); ?> --EXPECT-- diff --git a/ext/pcre/tests/bug75207.phpt b/ext/pcre/tests/bug75207.phpt index 82b2cc9bd9..ea25c547c1 100644 --- a/ext/pcre/tests/bug75207.phpt +++ b/ext/pcre/tests/bug75207.phpt @@ -4,7 +4,5 @@ CVE-2016-1283, see bug #75207 <?php preg_match("/(?:F?+(?:^(?(R)a+\"){99}-))(?J)(?'R'(?'R'<((?'RR'(?'R'\){97)?J)?J)(?'R'(?'R'\){99|(:(?|(?'R')(\k'R')|((?'R')))H'R'R)(H'R))))))/", "*b\dc"); ?> -==DONE== --EXPECTF-- Warning: preg_match(): Compilation failed: unmatched closing parenthesis at offset %d in %s on line %d -==DONE== diff --git a/ext/pcre/tests/bug76512.phpt b/ext/pcre/tests/bug76512.phpt index cb8a9fa95f..3090291736 100644 --- a/ext/pcre/tests/bug76512.phpt +++ b/ext/pcre/tests/bug76512.phpt @@ -4,7 +4,5 @@ Bug #76512 (\w no longer includes unicode characters) <?php var_dump(preg_match('/\w/u', 'ä')); ?> -===DONE=== --EXPECT-- int(1) -===DONE=== diff --git a/ext/pcre/tests/bug76850.phpt b/ext/pcre/tests/bug76850.phpt index 3e07ab7aa8..acceb2da71 100644 --- a/ext/pcre/tests/bug76850.phpt +++ b/ext/pcre/tests/bug76850.phpt @@ -2,10 +2,10 @@ Bug #76850 Exit code mangled by set locale/preg_match --SKIPIF-- <?php - $l = setlocale(LC_CTYPE, 0); - if ("C" == $l) { - die("skip need the current locale to be other than C"); - } + $l = setlocale(LC_CTYPE, 0); + if ("C" == $l) { + die("skip need the current locale to be other than C"); + } ?> --FILE-- <?php @@ -21,7 +21,5 @@ foo(); var_dump(preg_match('/./', "a")); ?> -==DONE== --EXPECT-- int(1) -==DONE== diff --git a/ext/pcre/tests/bug76909.phpt b/ext/pcre/tests/bug76909.phpt index 5109bed3a7..b2f22381c5 100644 --- a/ext/pcre/tests/bug76909.phpt +++ b/ext/pcre/tests/bug76909.phpt @@ -3,7 +3,7 @@ Bug #76909 preg_match difference between 7.3 and < 7.3 --SKIPIF-- <?php if(!ini_get("pcre.jit")) { - echo "skip JIT is disabled"; + echo "skip JIT is disabled"; } ?> --FILE-- diff --git a/ext/pcre/tests/bug77193.phpt b/ext/pcre/tests/bug77193.phpt index 5dc7913db2..ddceb6141f 100644 --- a/ext/pcre/tests/bug77193.phpt +++ b/ext/pcre/tests/bug77193.phpt @@ -2,9 +2,9 @@ Bug #77193 Infinite loop in preg_replace_callback --SKIPIF-- <?php - if (!extension_loaded("filter")) { - die("skip need filter extension"); - } + if (!extension_loaded("filter")) { + die("skip need filter extension"); + } ?> --FILE-- <?php @@ -12,16 +12,14 @@ $text = '{CCM:CID_2}'; echo '1'; $mt = array(); preg_replace_callback( - '/([0-9]+)/i', - function ($matches) { - echo $matches[1]; - filter_var('http', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^http$/i']]); - }, - $text + '/([0-9]+)/i', + function ($matches) { + echo $matches[1]; + filter_var('http', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^http$/i']]); + }, + $text ); echo '3', "\n"; ?> -===DONE=== --EXPECT-- 123 -===DONE=== diff --git a/ext/pcre/tests/bug77827.phpt b/ext/pcre/tests/bug77827.phpt index c8f8c7a16a..ebb5d8b228 100644 --- a/ext/pcre/tests/bug77827.phpt +++ b/ext/pcre/tests/bug77827.phpt @@ -7,8 +7,6 @@ var_dump( preg_last_error() ); ?> -===DONE=== --EXPECT-- int(1) int(0) -===DONE=== diff --git a/ext/pcre/tests/bug79241.phpt b/ext/pcre/tests/bug79241.phpt index de89e19760..f6dbb8bea4 100644 --- a/ext/pcre/tests/bug79241.phpt +++ b/ext/pcre/tests/bug79241.phpt @@ -1,7 +1,5 @@ --TEST-- Bug #79241: Segmentation fault on preg_match() ---SKIPIF-- -<?php if (!extension_loaded("json")) print "skip json extension missing"; ?> --FILE-- <?php diff --git a/ext/pcre/tests/cache_limit.phpt b/ext/pcre/tests/cache_limit.phpt index d6f3510e9d..d15b7675e4 100644 --- a/ext/pcre/tests/cache_limit.phpt +++ b/ext/pcre/tests/cache_limit.phpt @@ -12,10 +12,10 @@ $re = ''; $str = str_repeat('x', PREG_CACHE_SIZE); for ($i=0; $i < PREG_CACHE_SIZE; ++$i) { - $re .= '.'; - if (!preg_match("/$re/", $str)) { - die('non match. error'); - } + $re .= '.'; + if (!preg_match("/$re/", $str)) { + die('non match. error'); + } } var_dump(preg_match('/./', $str)); // this one was already deleted from the cache diff --git a/ext/pcre/tests/check_jit_enabled.phpt b/ext/pcre/tests/check_jit_enabled.phpt index de6e263e70..9cd249ea92 100644 --- a/ext/pcre/tests/check_jit_enabled.phpt +++ b/ext/pcre/tests/check_jit_enabled.phpt @@ -3,7 +3,7 @@ Check for JIT enablement status --SKIPIF-- <?php if (ini_get("pcre.jit") === FALSE) { - die("skip no jit built"); + die("skip no jit built"); } --FILE-- <?php diff --git a/ext/pcre/tests/errors01.phpt b/ext/pcre/tests/errors01.phpt new file mode 100644 index 0000000000..c239309c11 --- /dev/null +++ b/ext/pcre/tests/errors01.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test preg_split() function : error conditions - Recursion limit exhausted +--INI-- +pcre.recursion_limit=1 +--FILE-- +<?php + +var_dump(preg_last_error_msg() === 'No error'); +preg_split('/(\d*)/', 'ab2c3u'); +var_dump(preg_last_error_msg() === 'Recursion limit exhausted'); + +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/pcre/tests/errors02.phpt b/ext/pcre/tests/errors02.phpt new file mode 100644 index 0000000000..d350bae705 --- /dev/null +++ b/ext/pcre/tests/errors02.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test preg_split() function : error conditions - Malformed UTF-8 +--FILE-- +<?php + +var_dump(preg_split('/a/u', "a\xff")); +var_dump(preg_last_error_msg() === 'Malformed UTF-8 characters, possibly incorrectly encoded'); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/pcre/tests/errors03.phpt b/ext/pcre/tests/errors03.phpt new file mode 100644 index 0000000000..1f519cb599 --- /dev/null +++ b/ext/pcre/tests/errors03.phpt @@ -0,0 +1,13 @@ +--TEST-- +Test preg_match() function : error conditions - Internal error +--FILE-- +<?php + +var_dump(preg_match('/', 'Hello world')); +var_dump(preg_last_error_msg() === 'Internal error'); + +?> +--EXPECTF-- +Warning: preg_match(): No ending delimiter '/' found in %s on line %d +bool(false) +bool(true) diff --git a/ext/pcre/tests/errors04.phpt b/ext/pcre/tests/errors04.phpt new file mode 100644 index 0000000000..9e784deee8 --- /dev/null +++ b/ext/pcre/tests/errors04.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test preg_match_all() function : error conditions - Backtracking limit +--SKIPIF-- +<?php +if (@preg_match_all('/\p{N}/', '0123456789', $dummy) === false) { + die("skip no support for \p support PCRE library"); +} +?> +--INI-- +pcre.backtrack_limit=2 +pcre.jit=0 +--FILE-- +<?php + +var_dump(preg_match_all('/.*\p{N}/', '0123456789', $dummy)); +var_dump(preg_last_error_msg() === 'Backtrack limit exhausted'); + +var_dump(preg_match_all('/\p{Nd}/', '0123456789', $dummy)); +var_dump(preg_last_error_msg() === 'No error'); + +?> +--EXPECT-- +bool(false) +bool(true) +int(10) +bool(true) diff --git a/ext/pcre/tests/errors05.phpt b/ext/pcre/tests/errors05.phpt new file mode 100644 index 0000000000..dc60c24938 --- /dev/null +++ b/ext/pcre/tests/errors05.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test preg_match() function : error conditions - jit stacklimit exhausted +--SKIPIF-- +<?php +if (ini_get('pcre.jit') === false) { + die("skip no jit built"); +} +?> +--INI-- +pcre.jit=1 +--FILE-- +<?php +var_dump(preg_match('/^(foo)+$/', str_repeat('foo', 1024*8192))); +var_dump(preg_last_error_msg() === 'JIT stack limit exhausted'); +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/pcre/tests/errors06.phpt b/ext/pcre/tests/errors06.phpt new file mode 100644 index 0000000000..8e78244233 --- /dev/null +++ b/ext/pcre/tests/errors06.phpt @@ -0,0 +1,11 @@ +--TEST-- +Test preg_match() function : error conditions - Malformed UTF-8 offset +--FILE-- +<?php +preg_match('/a/u', "\xE3\x82\xA2", $m, 0, 1); +var_dump(preg_last_error() === PREG_BAD_UTF8_OFFSET_ERROR); +var_dump(preg_last_error_msg() === 'The offset did not correspond to the beginning of a valid UTF-8 code point'); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt index 4c6f9b155f..9721dfbd9e 100644 --- a/ext/pcre/tests/grep2.phpt +++ b/ext/pcre/tests/grep2.phpt @@ -7,8 +7,6 @@ pcre.jit=1 --FILE-- <?php -var_dump(preg_grep(1,array(),3,4)); -var_dump(preg_grep(1, 2)); var_dump(preg_grep('/+/', array())); $array = array(5=>'a', 'x' => '1', 'xyz'=>'q6', 'h20'); @@ -23,13 +21,7 @@ var_dump(preg_last_error() == PREG_RECURSION_LIMIT_ERROR); ?> --EXPECTF-- -Warning: preg_grep() expects at most 3 parameters, 4 given in %sgrep2.php on line 3 -NULL - -Warning: preg_grep() expects parameter 2 to be array, int given in %sgrep2.php on line 4 -NULL - -Warning: preg_grep(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %sgrep2.php on line 5 +Warning: preg_grep(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %sgrep2.php on line %d bool(false) array(3) { [5]=> diff --git a/ext/pcre/tests/invalid_utf8.phpt b/ext/pcre/tests/invalid_utf8.phpt index f24042a3bd..1a5124daaa 100644 --- a/ext/pcre/tests/invalid_utf8.phpt +++ b/ext/pcre/tests/invalid_utf8.phpt @@ -3,7 +3,7 @@ preg_replace() and invalid UTF8 --SKIPIF-- <?php if (@preg_match('/./u', '') === false) { - die('skip no utf8 support in PCRE library'); + die('skip no utf8 support in PCRE library'); } ?> --FILE-- diff --git a/ext/pcre/tests/invalid_utf8_offset.phpt b/ext/pcre/tests/invalid_utf8_offset.phpt index 2b9e7fa239..311a6d73d6 100644 --- a/ext/pcre/tests/invalid_utf8_offset.phpt +++ b/ext/pcre/tests/invalid_utf8_offset.phpt @@ -3,7 +3,7 @@ preg_replace() and invalid UTF8 offset --SKIPIF-- <?php if (@preg_match('/./u', '') === false) { - die('skip no utf8 support in PCRE library'); + die('skip no utf8 support in PCRE library'); } ?> --FILE-- diff --git a/ext/pcre/tests/marks.phpt b/ext/pcre/tests/marks.phpt index 2a410834c6..e718e78093 100644 --- a/ext/pcre/tests/marks.phpt +++ b/ext/pcre/tests/marks.phpt @@ -4,7 +4,7 @@ Test support for PCRE marks <?php $regex = <<<'REGEX' -/ +/ _ (a) (*MARK:A_MARK) _ | _ (b) _ | _ (c) (*MARK:C_MARK) _ diff --git a/ext/pcre/tests/no_jit_bug70110.phpt b/ext/pcre/tests/no_jit_bug70110.phpt index fa673ac935..aece155257 100644 --- a/ext/pcre/tests/no_jit_bug70110.phpt +++ b/ext/pcre/tests/no_jit_bug70110.phpt @@ -9,8 +9,6 @@ var_dump(preg_match('/(*NO_JIT)^(A{1,2}B)+$$/',str_repeat('AB',8192))); var_dump(preg_match('~(*NO_JIT)(a)*~', str_repeat('a', 5431), $match)) ?> -==DONE== --EXPECT-- int(1) int(1) -==DONE== diff --git a/ext/pcre/tests/pcre.constants.phpt b/ext/pcre/tests/pcre.constants.phpt index 5abc6c72c2..d58454c225 100644 --- a/ext/pcre/tests/pcre.constants.phpt +++ b/ext/pcre/tests/pcre.constants.phpt @@ -18,7 +18,6 @@ echo "PREG_RECURSION_LIMIT_ERROR= ", PREG_RECURSION_LIMIT_ERROR, "\n"; echo "PREG_BAD_UTF8_ERROR= ", PREG_BAD_UTF8_ERROR, "\n"; ?> -===Done=== --EXPECT-- PCRE constants test PREG_PATTERN_ORDER= 1 @@ -32,4 +31,3 @@ PREG_INTERNAL_ERROR= 1 PREG_BACKTRACK_LIMIT_ERROR= 2 PREG_RECURSION_LIMIT_ERROR= 3 PREG_BAD_UTF8_ERROR= 4 -===Done=== diff --git a/ext/pcre/tests/pcre_anchored.phpt b/ext/pcre/tests/pcre_anchored.phpt index c03d13501a..7852cd6d62 100644 --- a/ext/pcre/tests/pcre_anchored.phpt +++ b/ext/pcre/tests/pcre_anchored.phpt @@ -3,7 +3,7 @@ A (PCRE_ANCHORED) modifier --SKIPIF-- <?php if (@preg_match_all('/\p{N}/', '0123456789', $dummy) === false) { - die("skip no support for \p support PCRE library"); + die("skip no support for \p support PCRE library"); } ?> --FILE-- diff --git a/ext/pcre/tests/pcre_extra.phpt b/ext/pcre/tests/pcre_extra.phpt index 4c5930f975..730c729939 100644 --- a/ext/pcre/tests/pcre_extra.phpt +++ b/ext/pcre/tests/pcre_extra.phpt @@ -1,5 +1,5 @@ --TEST-- -X (PCRE_EXTRA) modifier +X (PCRE_EXTRA) modifier is ignored (no error, no change) --FILE-- <?php @@ -8,7 +8,8 @@ var_dump(preg_match('/\y/X', '\y')); ?> --EXPECTF-- -int(1) +Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in %spcre_extra.php on line 3 +bool(false) Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in %spcre_extra.php on line 4 bool(false) diff --git a/ext/pcre/tests/preg_filter.phpt b/ext/pcre/tests/preg_filter.phpt index 6cd9802575..1625fc8450 100644 --- a/ext/pcre/tests/preg_filter.phpt +++ b/ext/pcre/tests/preg_filter.phpt @@ -10,7 +10,6 @@ $replace = array('A:$0', 'B:$0', 'C:$0'); var_dump(preg_filter($pattern, $replace, $subject)); ?> -===DONE=== --EXPECT-- array(6) { [0]=> @@ -26,4 +25,3 @@ array(6) { [7]=> string(3) "A:4" } -===DONE=== diff --git a/ext/pcre/tests/preg_grep_basic.phpt b/ext/pcre/tests/preg_grep_basic.phpt index 4874aa8ab6..435c3500d4 100644 --- a/ext/pcre/tests/preg_grep_basic.phpt +++ b/ext/pcre/tests/preg_grep_basic.phpt @@ -3,7 +3,6 @@ Test preg_grep() function : basic functionality --FILE-- <?php /* -* proto array preg_grep(string regex, array input [, int flags]) * Function is implemented in ext/pcre/php_pcre.c */ $array = array('HTTP://WWW.EXAMPLE.COM', '/index.html', '/info/stat/', 'http://test.uk.com/index/html', '/display/dept.php'); diff --git a/ext/pcre/tests/preg_grep_error1.phpt b/ext/pcre/tests/preg_grep_error1.phpt index fcc36e7d91..3079c0b4b0 100644 --- a/ext/pcre/tests/preg_grep_error1.phpt +++ b/ext/pcre/tests/preg_grep_error1.phpt @@ -3,10 +3,8 @@ Test preg_grep() function : error conditions - bad regular expressions --FILE-- <?php /* -* proto array preg_grep(string regex, array input [, int flags]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_grep reacts to being passed bad regexes */ @@ -19,11 +17,19 @@ $values = array('abcdef', //Regex without delimiter ); $array = array(123, 'abc', 'test'); foreach($values as $value) { - print "\nArg value is $value\n"; - var_dump(preg_grep($value, $array)); + @print "\nArg value is $value\n"; + try { + var_dump(preg_grep($value, $array)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } } $value = new stdclass(); //Object -var_dump(preg_grep($value, $array)); +try { + var_dump(preg_grep($value, $array)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} echo "Done" ?> --EXPECTF-- @@ -50,9 +56,7 @@ Warning: preg_grep(): Unknown modifier 'F' in %spreg_grep_error1.php on line %d bool(false) Arg value is Array - -Warning: preg_grep() expects parameter 1 to be string, array given in %spreg_grep_error1.php on line %d -NULL +preg_grep(): Argument #1 ($pattern) must be of type string, array given Arg value is /[a-zA-Z]/ array(2) { @@ -61,7 +65,5 @@ array(2) { [2]=> string(4) "test" } - -Warning: preg_grep() expects parameter 1 to be string, object given in %spreg_grep_error1.php on line %d -NULL +preg_grep(): Argument #1 ($pattern) must be of type string, stdClass given Done diff --git a/ext/pcre/tests/preg_match_all_basic.phpt b/ext/pcre/tests/preg_match_all_basic.phpt index 63e9b6a6dd..9f02fb2027 100644 --- a/ext/pcre/tests/preg_match_all_basic.phpt +++ b/ext/pcre/tests/preg_match_all_basic.phpt @@ -3,7 +3,6 @@ Test preg_match_all() function : basic functionality --FILE-- <?php /* -* proto int preg_match_all(string pattern, string subject, [array subpatterns [, int flags [, int offset]]]) * Function is implemented in ext/pcre/php_pcre.c */ $string = 'Hello, world! This is a test. This is another test. \[4]. 34534 string.'; diff --git a/ext/pcre/tests/preg_match_all_edit_basic.phpt b/ext/pcre/tests/preg_match_all_edit_basic.phpt index 27034f90f1..02e658e941 100644 --- a/ext/pcre/tests/preg_match_all_edit_basic.phpt +++ b/ext/pcre/tests/preg_match_all_edit_basic.phpt @@ -2,12 +2,6 @@ Test preg_match_all() function : basic functionality --FILE-- <?php -/* Prototype : proto int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]]) - * Description: Perform a Perl-style global regular expression match - * Source code: ext/pcre/php_pcre.c - * Alias to functions: -*/ - $string = 'Hello, world! This is a test. This is another test. \[4]. 34534 string.'; var_dump(preg_match_all('/[0-35-9]/', $string, $match1, PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER, -10)); //finds any digit that's not 4 10 digits from the end(1 match) diff --git a/ext/pcre/tests/preg_match_all_error1.phpt b/ext/pcre/tests/preg_match_all_error1.phpt index 95ab905d7d..d25bfe99c6 100644 --- a/ext/pcre/tests/preg_match_all_error1.phpt +++ b/ext/pcre/tests/preg_match_all_error1.phpt @@ -3,10 +3,8 @@ Test preg_match_all() function : error conditions - bad regular expressions --FILE-- <?php /* -* proto int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_match_all reacts to being passed the wrong type of regex argument */ @@ -19,12 +17,20 @@ $regex_array = array('abcdef', //Regex without delimiter ); $subject = 'test'; foreach($regex_array as $regex_value) { - print "\nArg value is $regex_value\n"; - var_dump(preg_match_all($regex_value, $subject, $matches1)); + @print "\nArg value is $regex_value\n"; + try { + var_dump(preg_match_all($regex_value, $subject, $matches1)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } var_dump($matches1); } $regex_value = new stdclass(); //Object -var_dump(preg_match_all($regex_value, $subject, $matches)); +try { + var_dump(preg_match_all($regex_value, $subject, $matches)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} var_dump($matches); ?> --EXPECTF-- @@ -55,9 +61,7 @@ bool(false) NULL Arg value is Array - -Warning: preg_match_all() expects parameter 1 to be string, array given in %spreg_match_all_error1.php on line %d -bool(false) +preg_match_all(): Argument #1 ($pattern) must be of type string, array given NULL Arg value is /[a-zA-Z]/ @@ -75,7 +79,5 @@ array(1) { string(1) "t" } } - -Warning: preg_match_all() expects parameter 1 to be string, object given in %spreg_match_all_error1.php on line %d -bool(false) +preg_match_all(): Argument #1 ($pattern) must be of type string, stdClass given NULL diff --git a/ext/pcre/tests/preg_match_all_error2.phpt b/ext/pcre/tests/preg_match_all_error2.phpt index 1c55cce64e..bffd84552e 100644 --- a/ext/pcre/tests/preg_match_all_error2.phpt +++ b/ext/pcre/tests/preg_match_all_error2.phpt @@ -3,37 +3,30 @@ Test preg_match_all() function : error conditions - wrong arg types --FILE-- <?php /* -* proto int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_match_all reacts to being passed the wrong type of input argument */ echo "*** Testing preg_match_all() : error conditions ***\n"; $regex = '/[a-zA-Z]/'; -$value = new stdclass(); //Object -var_dump(preg_match_all($regex, $value, $matches)); -var_dump($matches); $input = array(array('this is', 'a subarray'), 'test',); foreach($input as $value) { - print "\nArg value is: $value\n"; - var_dump(preg_match_all($regex, $value, $matches)); + @print "\nArg value is: $value\n"; + try { + var_dump(preg_match_all($regex, $value, $matches)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } var_dump($matches); } echo "Done"; ?> ---EXPECTF-- +--EXPECT-- *** Testing preg_match_all() : error conditions *** -Warning: preg_match_all() expects parameter 2 to be string, object given in %spreg_match_all_error2.php on line %d -bool(false) -NULL - Arg value is: Array - -Warning: preg_match_all() expects parameter 2 to be string, array given in %spreg_match_all_error2.php on line %d -bool(false) +preg_match_all(): Argument #2 ($subject) must be of type string, array given NULL Arg value is: test diff --git a/ext/pcre/tests/preg_match_all_error3.phpt b/ext/pcre/tests/preg_match_all_error3.phpt index 6559b22d2e..a78619bdd7 100644 --- a/ext/pcre/tests/preg_match_all_error3.phpt +++ b/ext/pcre/tests/preg_match_all_error3.phpt @@ -3,7 +3,6 @@ Test preg_match_all() function : error conditions --FILE-- <?php /* -* proto int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]]) * Function is implemented in ext/pcre/php_pcre.c */ /* @@ -16,4 +15,9 @@ var_dump(preg_match_all($regex, $subject, 'test')); echo "Done"; ?> --EXPECTF-- -Fatal error: Only variables can be passed by reference in %spreg_match_all_error3.php on line %d +*** Testing preg_match_all() : error conditions *** + +Fatal error: Uncaught Error: preg_match_all(): Argument #3 ($matches) cannot be passed by reference in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/ext/pcre/tests/preg_match_basic.phpt b/ext/pcre/tests/preg_match_basic.phpt index a0015f129e..fd9dc8cc96 100644 --- a/ext/pcre/tests/preg_match_basic.phpt +++ b/ext/pcre/tests/preg_match_basic.phpt @@ -2,10 +2,7 @@ Test preg_match() function : basic functionality --FILE-- <?php -/* - * proto int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]]) - * Function is implemented in ext/pcre/php_pcre.c -*/ +/* Function is implemented in ext/pcre/php_pcre.c */ $string = 'Hello, world. [*], this is \ a string'; var_dump(preg_match('/^[hH]ello,\s/', $string, $match1)); //finds "Hello, " var_dump($match1); diff --git a/ext/pcre/tests/preg_match_basic_002.phpt b/ext/pcre/tests/preg_match_basic_002.phpt index bca8f3e3c5..d91bdce836 100644 --- a/ext/pcre/tests/preg_match_basic_002.phpt +++ b/ext/pcre/tests/preg_match_basic_002.phpt @@ -2,17 +2,11 @@ preg_match() single line match with multi-line input --FILE-- <?php -/* Prototype : int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags [, int $offset ]]] ) - * Description: Perform a regular expression match - * Source code: ext/pcre/php_pcre.c - */ - $string = "My\nName\nIs\nStrange"; preg_match("/M(.*)/", $string, $matches); var_dump($matches); ?> -===Done=== --EXPECT-- array(2) { [0]=> @@ -20,4 +14,3 @@ array(2) { [1]=> string(1) "y" } -===Done=== diff --git a/ext/pcre/tests/preg_match_basic_edit.phpt b/ext/pcre/tests/preg_match_basic_edit.phpt index e06bb4005c..0471ffb0b7 100644 --- a/ext/pcre/tests/preg_match_basic_edit.phpt +++ b/ext/pcre/tests/preg_match_basic_edit.phpt @@ -2,13 +2,6 @@ Test preg_match() function : basic functionality --FILE-- <?php -/* Prototype : proto int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]]) - * Description: Perform a Perl-style regular expression match - * Source code: ext/pcre/php_pcre.c - * Alias to functions: -*/ - - $string = 'Hello, world. [*], this is \ a string'; var_dump(preg_match('/^[hH]ello,\s/', $string, $match1)); //finds "Hello, " diff --git a/ext/pcre/tests/preg_match_error1.phpt b/ext/pcre/tests/preg_match_error1.phpt index 42bb5abd27..7a7106270f 100644 --- a/ext/pcre/tests/preg_match_error1.phpt +++ b/ext/pcre/tests/preg_match_error1.phpt @@ -2,11 +2,7 @@ Test preg_match() function : error conditions - bad regular expressions --FILE-- <?php -/* - * proto int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]]) - * Function is implemented in ext/pcre/php_pcre.c -*/ -error_reporting(E_ALL&~E_NOTICE); +/* Function is implemented in ext/pcre/php_pcre.c */ /* * Testing how preg_match reacts to being passed the wrong type of regex argument */ @@ -19,11 +15,19 @@ $regex_array = array('abcdef', //Regex without delimiter ); $subject = 'this is a test'; foreach($regex_array as $regex_value) { - print "\nArg value is $regex_value\n"; - var_dump(preg_match($regex_value, $subject)); + @print "\nArg value is $regex_value\n"; + try { + var_dump(preg_match($regex_value, $subject)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } } $regex_value = new stdclass(); //Object -var_dump(preg_match($regex_value, $subject)); +try { + var_dump(preg_match($regex_value, $subject)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECTF-- *** Testing preg_match() : error conditions *** @@ -49,12 +53,8 @@ Warning: preg_match(): Unknown modifier 'F' in %spreg_match_error1.php on line % bool(false) Arg value is Array - -Warning: preg_match() expects parameter 1 to be string, array given in %spreg_match_error1.php on line %d -bool(false) +preg_match(): Argument #1 ($pattern) must be of type string, array given Arg value is /[a-zA-Z]/ int(1) - -Warning: preg_match() expects parameter 1 to be string, object given in %spreg_match_error1.php on line %d -bool(false) +preg_match(): Argument #1 ($pattern) must be of type string, stdClass given diff --git a/ext/pcre/tests/preg_match_error2.phpt b/ext/pcre/tests/preg_match_error2.phpt index cb0917a228..48aafd3713 100644 --- a/ext/pcre/tests/preg_match_error2.phpt +++ b/ext/pcre/tests/preg_match_error2.phpt @@ -2,11 +2,7 @@ Test preg_match() function : error conditions - wrong arg types --FILE-- <?php -/* - * proto int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]]) - * Function is implemented in ext/pcre/php_pcre.c -*/ -error_reporting(E_ALL&~E_NOTICE); +/* Function is implemented in ext/pcre/php_pcre.c */ /* * Testing how preg_match reacts to being passed the wrong type of subject argument */ @@ -14,24 +10,28 @@ echo "*** Testing preg_match() : error conditions ***\n"; $regex = '/[a-zA-Z]/'; $input = array('this is a string', array('this is', 'a subarray'),); foreach($input as $value) { - print "\nArg value is: $value\n"; - var_dump(preg_match($regex, $value)); + @print "\nArg value is: $value\n"; + try { + var_dump(preg_match($regex, $value)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } } $value = new stdclass(); //Object -var_dump(preg_match($regex, $value)); +try { + var_dump(preg_match($regex, $value)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} echo "Done"; ?> ---EXPECTF-- +--EXPECT-- *** Testing preg_match() : error conditions *** Arg value is: this is a string int(1) Arg value is: Array - -Warning: preg_match() expects parameter 2 to be string, array given in %spreg_match_error2.php on line %d -bool(false) - -Warning: preg_match() expects parameter 2 to be string, object given in %spreg_match_error2.php on line %d -bool(false) +preg_match(): Argument #2 ($subject) must be of type string, array given +preg_match(): Argument #2 ($subject) must be of type string, stdClass given Done diff --git a/ext/pcre/tests/preg_match_error3.phpt b/ext/pcre/tests/preg_match_error3.phpt index 8b9d59fc58..cf9c29a112 100644 --- a/ext/pcre/tests/preg_match_error3.phpt +++ b/ext/pcre/tests/preg_match_error3.phpt @@ -3,7 +3,7 @@ Test preg_match() function : error conditions - jit stacklimit exhausted --SKIPIF-- <?php if (ini_get("pcre.jit") === FALSE) { - die("skip no jit built"); + die("skip no jit built"); } ?> --INI-- diff --git a/ext/pcre/tests/preg_match_error4.phpt b/ext/pcre/tests/preg_match_error4.phpt index 06aa82b469..8c8f25b6e9 100644 --- a/ext/pcre/tests/preg_match_error4.phpt +++ b/ext/pcre/tests/preg_match_error4.phpt @@ -926,10 +926,8 @@ if($count === false) { throw new \RuntimeException('Failed to execute regex: Unknown error'); } } else { - var_dump("Done, $count matches."); + var_dump("Done, $count matches."); } ?> -==DONE== --EXPECT-- string(16) "Done, 1 matches." -==DONE== diff --git a/ext/pcre/tests/preg_match_latin.phpt b/ext/pcre/tests/preg_match_latin.phpt index 8f1d1899cb..4685470d21 100644 --- a/ext/pcre/tests/preg_match_latin.phpt +++ b/ext/pcre/tests/preg_match_latin.phpt @@ -2,11 +2,6 @@ preg_match() single line match with latin input --FILE-- <?php -/* Prototype : int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags [, int $offset ]]] ) - * Description: Perform a regular expression match - * Source code: ext/pcre/php_pcre.c - */ - preg_match('/^[\w\p{Cyrillic}\s\-\']+$/u', 'latin', $test1); preg_match('/^[\w\p{Cyrillic}\s\-\']+$/u', 'кириллица', $test2); preg_match('/^[\w\s\-\']+$/u', 'latin', $test3); diff --git a/ext/pcre/tests/preg_match_variation1.phpt b/ext/pcre/tests/preg_match_variation1.phpt index 5fa50ce49c..d9375ddd24 100644 --- a/ext/pcre/tests/preg_match_variation1.phpt +++ b/ext/pcre/tests/preg_match_variation1.phpt @@ -2,10 +2,7 @@ Test preg_match() function : variation --FILE-- <?php -/* - * proto int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]]) - * Function is implemented in ext/pcre/php_pcre.c -*/ +/* Function is implemented in ext/pcre/php_pcre.c */ //test passing in the same variable where 1 is by value, the other is a different //type and by reference so should be updated to the new type. @@ -13,10 +10,8 @@ $string = "-1"; preg_match('/[\-\+]?[0-9\.]*/', $string, $string); var_dump($string); ?> -===Done=== --EXPECT-- array(1) { [0]=> string(2) "-1" } -===Done=== diff --git a/ext/pcre/tests/preg_quote_basic.phpt b/ext/pcre/tests/preg_quote_basic.phpt index bdcd933428..7f5136d5e2 100644 --- a/ext/pcre/tests/preg_quote_basic.phpt +++ b/ext/pcre/tests/preg_quote_basic.phpt @@ -3,7 +3,6 @@ Test preg_quote() function : basic functionality --FILE-- <?php /* -* proto string preg_quote(string str [, string delim_char]) * Function is implemented in ext/pcre/php_pcre.c */ $string_before = '/this *-has \ metacharacters^ in $'; diff --git a/ext/pcre/tests/preg_replace2.phpt b/ext/pcre/tests/preg_replace2.phpt index 4a191f3331..e38c4788cb 100644 --- a/ext/pcre/tests/preg_replace2.phpt +++ b/ext/pcre/tests/preg_replace2.phpt @@ -3,14 +3,12 @@ preg_replace() --SKIPIF-- <?php if (@preg_match('/./u', '') === false) { - die('skip no utf8 support in PCRE library'); + die('skip no utf8 support in PCRE library'); } ?> --FILE-- <?php -var_dump(preg_replace('', array(), '')); - var_dump(preg_replace(array('/\da(.)/ui', '@..@'), '$1', '12Abc')); var_dump(preg_replace(array('/\da(.)/ui', '@(.)@'), '$1', array('x','a2aA', '1av2Ab'))); @@ -18,12 +16,8 @@ var_dump(preg_replace(array('/\da(.)/ui', '@(.)@'), '$1', array('x','a2aA', '1av var_dump(preg_replace(array('/[\w]+/'), array('$'), array('xyz', 'bdbd'))); var_dump(preg_replace(array('/\s+/', '~[b-d]~'), array('$'), array('x y', 'bd bc'))); -echo "==done==\n"; - ?> ---EXPECTF-- -Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array in %spreg_replace2.php on line 3 -bool(false) +--EXPECT-- string(1) "c" array(3) { [0]=> @@ -45,4 +39,3 @@ array(2) { [1]=> string(1) "$" } -==done== diff --git a/ext/pcre/tests/preg_replace_basic.phpt b/ext/pcre/tests/preg_replace_basic.phpt index 266bd0eebd..1e5ba8b23f 100644 --- a/ext/pcre/tests/preg_replace_basic.phpt +++ b/ext/pcre/tests/preg_replace_basic.phpt @@ -3,7 +3,6 @@ Test preg_replace() function : basic functionality --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ $string = '123456789 - Hello, world - This is a string.'; diff --git a/ext/pcre/tests/preg_replace_callback2.phpt b/ext/pcre/tests/preg_replace_callback2.phpt index 1fe78d59ee..42c613726f 100644 --- a/ext/pcre/tests/preg_replace_callback2.phpt +++ b/ext/pcre/tests/preg_replace_callback2.phpt @@ -4,7 +4,7 @@ preg_replace_callback() 2 <?php function f() { - throw new Exception(); + throw new Exception(); } try { @@ -12,7 +12,7 @@ var_dump(preg_replace_callback('/\w/', 'f', 'z')); } catch(Exception $e) {} function g($x) { - return "'$x[0]'"; + return "'$x[0]'"; } var_dump(preg_replace_callback('@\b\w{1,2}\b@', 'g', array('a b3 bcd', 'v' => 'aksfjk', 12 => 'aa bb'))); @@ -31,7 +31,7 @@ array(3) { string(9) "'aa' 'bb'" } -Notice: Array to string conversion in %spreg_replace_callback2.php on line 17 +Warning: Array to string conversion in %s on line %d array(1) { [0]=> string(7) "'A'rray" diff --git a/ext/pcre/tests/preg_replace_callback3.phpt b/ext/pcre/tests/preg_replace_callback3.phpt index f5c87176f9..9a26555cb5 100644 --- a/ext/pcre/tests/preg_replace_callback3.phpt +++ b/ext/pcre/tests/preg_replace_callback3.phpt @@ -3,42 +3,26 @@ preg_replace_callback() 3 --FILE-- <?php -var_dump(preg_replace_callback()); -var_dump(preg_replace_callback(1)); -var_dump(preg_replace_callback(1,2)); -var_dump(preg_replace_callback(1,2,3)); -var_dump(preg_replace_callback(1,2,3,4)); +try { + var_dump(preg_replace_callback(1,2,3)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(preg_replace_callback(1,2,3,4)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + $a = 5; -var_dump(preg_replace_callback(1,2,3,4,$a)); -$a = ""; -var_dump(preg_replace_callback("","","","",$a)); -$a = array(); -var_dump(preg_replace_callback($a,$a,$a,$a,$a)); +try { + var_dump(preg_replace_callback(1,2,3,4,$a)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} -echo "Done\n"; ?> ---EXPECTF-- -Warning: preg_replace_callback() expects at least 3 parameters, 0 given in %s on line %d -NULL - -Warning: preg_replace_callback() expects at least 3 parameters, 1 given in %s on line %d -NULL - -Warning: preg_replace_callback() expects at least 3 parameters, 2 given in %s on line %d -NULL - -Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d -string(1) "3" - -Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d -string(1) "3" - -Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d -string(1) "3" - -Warning: preg_replace_callback() expects parameter 4 to be int, string given in %s on line %d -NULL - -Warning: preg_replace_callback() expects parameter 4 to be int, array given in %s on line %d -NULL -Done +--EXPECT-- +preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given +preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given +preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given diff --git a/ext/pcre/tests/preg_replace_callback_array.phpt b/ext/pcre/tests/preg_replace_callback_array.phpt index 01973eaa32..cf872547f3 100644 --- a/ext/pcre/tests/preg_replace_callback_array.phpt +++ b/ext/pcre/tests/preg_replace_callback_array.phpt @@ -4,46 +4,56 @@ preg_replace_callback_array() basic functions <?php class Rep { - public function __invoke() { - return "d"; - } + public function __invoke() { + return "d"; + } } class Foo { - public static function rep($rep) { - return "ok"; - } + public static function rep($rep) { + return "ok"; + } } function b() { - return "b"; + return "b"; } var_dump(preg_replace_callback_array( - array( - "/a/" => 'b', - "/b/" => function () { return "c"; }, - "/c/" => new Rep, - '/d/' => array("Foo", "rep")), 'a')); + array( + "/a/" => 'b', + "/b/" => function () { return "c"; }, + "/c/" => new Rep, + '/d/' => array("Foo", "rep")), 'a')); var_dump(preg_replace_callback_array( - array( - "/a/" => 'b', - "/c/" => new Rep, - "/b/" => function () { return "ok"; }, - '/d/' => array("Foo", "rep")), 'a')); + array( + "/a/" => 'b', + "/c/" => new Rep, + "/b/" => function () { return "ok"; }, + '/d/' => array("Foo", "rep")), 'a')); var_dump(preg_replace_callback_array( - array( - '/d/' => array("Foo", "rep"), - "/c/" => new Rep, - "/a/" => 'b', - "/b/" => function($a) { return "ok"; }), 'a', -1, $count)); - + array( + '/d/' => array("Foo", "rep"), + "/c/" => new Rep, + "/a/" => 'b', + "/b/" => function($a) { return "ok"; }), 'a', -1, $count)); var_dump($count); + +var_dump(preg_replace_callback_array( + array('/a/' => 'b', "/c/" => new Rep), + array('a', 'c'))); + ?> --EXPECT-- string(2) "ok" string(2) "ok" string(2) "ok" int(2) +array(2) { + [0]=> + string(1) "b" + [1]=> + string(1) "d" +} diff --git a/ext/pcre/tests/preg_replace_callback_array2.phpt b/ext/pcre/tests/preg_replace_callback_array2.phpt index f2f20ef645..aca11dc19c 100644 --- a/ext/pcre/tests/preg_replace_callback_array2.phpt +++ b/ext/pcre/tests/preg_replace_callback_array2.phpt @@ -3,62 +3,34 @@ preg_replace_callback_array() errors --FILE-- <?php -var_dump(preg_replace_callback_array()); -var_dump(preg_replace_callback_array(1)); -var_dump(preg_replace_callback_array(1,2)); -var_dump(preg_replace_callback_array(1,2,3)); -$a = 5; -var_dump(preg_replace_callback_array(1,2,3,$a)); -$a = ""; -var_dump(preg_replace_callback_array(array("" => ""),"","",$a)); $a = array(); $b = ""; -var_dump(preg_replace_callback($a, $a, $a, $a, $b)); -var_dump($b); -$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; - throw new Exception($count); + static $count = 1; + throw new Exception($count); } var_dump(preg_replace_callback_array(array('/\w' => 'f'), 'z')); try { - var_dump(preg_replace_callback_array(array('/\w/' => 'f', '/.*/' => 'f'), 'z')); + var_dump(preg_replace_callback_array(array('/\w/' => 'f', '/.*/' => 'f'), 'z')); } catch (Exception $e) { - var_dump($e->getMessage()); + var_dump($e->getMessage()); } echo "Done\n"; ?> --EXPECTF-- -Warning: preg_replace_callback_array() expects at least 2 parameters, 0 given in %s on line %d -NULL - -Warning: preg_replace_callback_array() expects at least 2 parameters, 1 given in %s on line %d -NULL - -Warning: preg_replace_callback_array() expects parameter 1 to be array, int given in %s on line %d -NULL - -Warning: preg_replace_callback_array() expects parameter 1 to be array, int given in %s on line %d -NULL - -Warning: preg_replace_callback_array() expects parameter 1 to be array, int given in %s on line %d -NULL - -Warning: preg_replace_callback_array() expects parameter 3 to be int, string given in %s on line %d -NULL - -Warning: preg_replace_callback() expects parameter 4 to be int, array given in %s on line %d -NULL -string(0) "" - -Warning: preg_replace_callback_array(): 's' is not a valid callback in %spreg_replace_callback_array2.php on line %d -array(0) { -} +preg_replace_callback_array(): Argument #1 ($pattern) must contain only valid callbacks 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_callback_basic.phpt b/ext/pcre/tests/preg_replace_callback_basic.phpt index c89fa8c12c..79bedb00bd 100644 --- a/ext/pcre/tests/preg_replace_callback_basic.phpt +++ b/ext/pcre/tests/preg_replace_callback_basic.phpt @@ -3,7 +3,6 @@ Test preg_replace_callback() function : basic functionality --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ /* diff --git a/ext/pcre/tests/preg_replace_callback_error1.phpt b/ext/pcre/tests/preg_replace_callback_error1.phpt index 313064eab8..eb6478e506 100644 --- a/ext/pcre/tests/preg_replace_callback_error1.phpt +++ b/ext/pcre/tests/preg_replace_callback_error1.phpt @@ -3,10 +3,8 @@ Test preg_replace_callback() function : error --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_replace_callback reacts to being passed the wrong type of regex argument */ @@ -15,7 +13,7 @@ $regex_array = array('abcdef', //Regex without delimiters '/[a-zA-Z]', //Regex without closing delimiter '[a-zA-Z]/', //Regex without opening delimiter '/[a-zA-Z]/F', array('[a-z]', //Array of Regexes -'[A-Z]', '[0-9]'), '/[a-zA-Z]/'); //Regex string +'[A-Z]', '[0-9]'), '/[0-9]/'); //Regex string $replacement = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'); function integer_word($matches) { global $replacement; @@ -23,11 +21,10 @@ function integer_word($matches) { } $subject = 'number 1.'; foreach($regex_array as $regex_value) { - print "\nArg value is $regex_value\n"; + @print "\nArg value is $regex_value\n"; var_dump(preg_replace_callback($regex_value, 'integer_word', $subject)); } ?> -===Done=== --EXPECTF-- *** Testing preg_replace_callback() : error conditions *** @@ -54,6 +51,5 @@ NULL Arg value is Array string(9) "number 1." -Arg value is /[a-zA-Z]/ -string(3) " 1." -===Done=== +Arg value is /[0-9]/ +string(11) "number one." diff --git a/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt b/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt new file mode 100644 index 0000000000..5ea3d4081e --- /dev/null +++ b/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt @@ -0,0 +1,18 @@ +--TEST-- +preg_replace_callback() should not leak persistent memory on fatal error +--FILE-- +<?php + +function test() {} + +preg_replace_callback('/a/', function($matches) { + preg_replace_callback('/x/', function($matches) { + function test() {} // Trigger a fatal error. + return 'y'; + }, 'x'); + return 'b'; +}, 'a'); + +?> +--EXPECTF-- +Fatal error: Cannot redeclare test() (previously declared in %s on line %d diff --git a/ext/pcre/tests/preg_replace_edit_basic.phpt b/ext/pcre/tests/preg_replace_edit_basic.phpt index b272f379be..ac7b1d4a92 100644 --- a/ext/pcre/tests/preg_replace_edit_basic.phpt +++ b/ext/pcre/tests/preg_replace_edit_basic.phpt @@ -2,12 +2,6 @@ Test preg_replace() function : basic --FILE-- <?php -/* Prototype : proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) - * Description: Perform Perl-style regular expression replacement. - * Source code: ext/pcre/php_pcre.c - * Alias to functions: -*/ - $string = '123456789 - Hello, world - This is a string.'; var_dump($string); @@ -16,7 +10,7 @@ var_dump(preg_replace('<- This is a string$>', var_dump(preg_replace('<[0-35-9]>', '4', $string, //finds any number that's not 4 and replaces it with a 4 - '5', $count)); //limits to 5 replacements returns 444444789 + '5', $count)); //limits to 5 replacements returns 444444789 var_dump($count); //counts the number of replacements made (5) diff --git a/ext/pcre/tests/preg_replace_error1.phpt b/ext/pcre/tests/preg_replace_error1.phpt index 780556956a..ccd3554745 100644 --- a/ext/pcre/tests/preg_replace_error1.phpt +++ b/ext/pcre/tests/preg_replace_error1.phpt @@ -3,10 +3,8 @@ Test preg_replace() function : error - bad regular expressions --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_replace reacts to being passed the wrong type of regex argument */ @@ -20,7 +18,7 @@ $regex_array = array('abcdef', //Regex without delimiter $replace = 1; $subject = 'a'; foreach($regex_array as $regex_value) { - print "\nArg value is $regex_value\n"; + @print "\nArg value is $regex_value\n"; var_dump(preg_replace($regex_value, $replace, $subject)); } $regex_value = new stdclass(); //Object @@ -58,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 ($pattern) must be of type array|string, stdClass given diff --git a/ext/pcre/tests/preg_replace_error2.phpt b/ext/pcre/tests/preg_replace_error2.phpt index a334b2fefd..4b162061b3 100644 --- a/ext/pcre/tests/preg_replace_error2.phpt +++ b/ext/pcre/tests/preg_replace_error2.phpt @@ -3,10 +3,8 @@ Test preg_replace() function : error conditions - wrong arg types --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_replace reacts to being passed the wrong type of replacement argument */ @@ -15,8 +13,12 @@ $regex = '/[a-zA-Z]/'; $replace = array('this is a string', array('this is', 'a subarray'),); $subject = 'test'; foreach($replace as $value) { - print "\nArg value is: $value\n"; - var_dump(preg_replace($regex, $value, $subject)); + @print "\nArg value is: $value\n"; + try { + var_dump(preg_replace($regex, $value, $subject)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } } $value = new stdclass(); //Object try { @@ -26,15 +28,13 @@ try { } echo "Done"; ?> ---EXPECTF-- +--EXPECT-- *** Testing preg_replace() : error conditions *** Arg value is: this is a string string(64) "this is a stringthis is a stringthis is a stringthis is a string" Arg value is: Array - -Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array in %spreg_replace_error2.php on line %d -bool(false) -Object of class stdClass could not be converted to string +preg_replace(): Argument #1 ($pattern) must be of type array when argument #2 ($replacement) is an array, string given +preg_replace(): Argument #2 ($replacement) must be of type array|string, stdClass given Done diff --git a/ext/pcre/tests/preg_replace_variation1.phpt b/ext/pcre/tests/preg_replace_variation1.phpt index d99cc63212..91aa8432b7 100644 --- a/ext/pcre/tests/preg_replace_variation1.phpt +++ b/ext/pcre/tests/preg_replace_variation1.phpt @@ -3,7 +3,6 @@ Test preg_replace() function : variation both arguments are arrays --FILE-- <?php /* -* proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) * Function is implemented in ext/pcre/php_pcre.c */ /* diff --git a/ext/pcre/tests/preg_split_basic.phpt b/ext/pcre/tests/preg_split_basic.phpt index c33640920b..6f1568a680 100644 --- a/ext/pcre/tests/preg_split_basic.phpt +++ b/ext/pcre/tests/preg_split_basic.phpt @@ -3,7 +3,6 @@ Test preg_split() function : basic functionality --FILE-- <?php /* -* proto array preg_split(string pattern, string subject [, int limit [, int flags]]) * Function is implemented in ext/pcre/php_pcre.c */ $string = 'this is a_list: value1, Test__, string; Hello, world!_(parentheses)'; diff --git a/ext/pcre/tests/preg_split_error1.phpt b/ext/pcre/tests/preg_split_error1.phpt index 79942a9480..4d0fb9e22a 100644 --- a/ext/pcre/tests/preg_split_error1.phpt +++ b/ext/pcre/tests/preg_split_error1.phpt @@ -3,10 +3,8 @@ Test preg_split() function : error conditions - bad regular expressions --FILE-- <?php /* -* proto array preg_split(string pattern, string subject [, int limit [, int flags]]) * Function is implemented in ext/pcre/php_pcre.c */ -error_reporting(E_ALL&~E_NOTICE); /* * Testing how preg_split reacts to being passed the wrong type of regex argument */ @@ -19,11 +17,19 @@ $regex_array = array('abcdef', //Regex without delimiter ); $subject = '1 2 a 3 4 b 5 6'; foreach($regex_array as $regex_value) { - print "\nArg value is $regex_value\n"; - var_dump(preg_split($regex_value, $subject)); + @print "\nArg value is $regex_value\n"; + try { + var_dump(preg_split($regex_value, $subject)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } } $regex_value = new stdclass(); //Object -var_dump(preg_split($regex_value, $subject)); +try { + var_dump(preg_split($regex_value, $subject)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECTF-- *** Testing preg_split() : error conditions *** @@ -49,9 +55,7 @@ Warning: preg_split(): Unknown modifier 'F' in %spreg_split_error1.php on line % bool(false) Arg value is Array - -Warning: preg_split() expects parameter 1 to be string, array given in %spreg_split_error1.php on line %d -bool(false) +preg_split(): Argument #1 ($pattern) must be of type string, array given Arg value is /[a-zA-Z]/ array(3) { @@ -62,6 +66,4 @@ array(3) { [2]=> string(4) " 5 6" } - -Warning: preg_split() expects parameter 1 to be string, object given in %spreg_split_error1.php on line %d -bool(false) +preg_split(): Argument #1 ($pattern) must be of type string, stdClass given diff --git a/ext/pcre/tests/recursion_limit.phpt b/ext/pcre/tests/recursion_limit.phpt index 294931388d..5d08f1771b 100644 --- a/ext/pcre/tests/recursion_limit.phpt +++ b/ext/pcre/tests/recursion_limit.phpt @@ -3,7 +3,7 @@ PCRE Recursion limit --SKIPIF-- <?php if (@preg_match_all('/\p{N}/', '0123456789', $dummy) === false) { - die("skip no support for \p support PCRE library"); + die("skip no support for \p support PCRE library"); } ?> --INI-- diff --git a/ext/pcre/tests/skip_001.inc b/ext/pcre/tests/skip_001.inc index 35434ece5b..13035969b4 100644 --- a/ext/pcre/tests/skip_001.inc +++ b/ext/pcre/tests/skip_001.inc @@ -1,5 +1,5 @@ <?php if (!@setlocale(LC_ALL, 'pt_PT', 'pt', 'pt_PT.ISO8859-1', 'portuguese')) { - die('skip pt locale not available'); + die('skip pt locale not available'); } diff --git a/ext/pcre/tests/skip_002.inc b/ext/pcre/tests/skip_002.inc index 7f3a253faa..e62864b6a8 100644 --- a/ext/pcre/tests/skip_002.inc +++ b/ext/pcre/tests/skip_002.inc @@ -1,5 +1,5 @@ <?php if (@preg_match('/./u', '') === false) { - die('skip'); + die('skip'); } diff --git a/ext/pcre/tests/skip_003.inc b/ext/pcre/tests/skip_003.inc index af2f548ca1..5a03c5802c 100644 --- a/ext/pcre/tests/skip_003.inc +++ b/ext/pcre/tests/skip_003.inc @@ -1,5 +1,5 @@ <?php if (@preg_match_all('/\p{N}/', '0123456789', $dummy) === false) { - die('skip'); + die('skip'); } diff --git a/ext/pcre/tests/split.phpt b/ext/pcre/tests/split.phpt index c87d1b03a9..df4b9af92f 100644 --- a/ext/pcre/tests/split.phpt +++ b/ext/pcre/tests/split.phpt @@ -3,7 +3,6 @@ preg_split() --FILE-- <?php -var_dump(preg_split()); var_dump(preg_split('/*/', 'x')); var_dump(preg_split('/[\s, ]+/', 'x yy,zzz')); @@ -17,10 +16,7 @@ var_dump(preg_split('/\d*/', 'ab2c3u', -1, PREG_SPLIT_NO_EMPTY)); ?> --EXPECTF-- -Warning: preg_split() expects at least 2 parameters, 0 given in %ssplit.php on line 3 -bool(false) - -Warning: preg_split(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %ssplit.php on line 4 +Warning: preg_split(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %ssplit.php on line %d bool(false) array(3) { [0]=> diff --git a/ext/pcre/tests/split2.phpt b/ext/pcre/tests/split2.phpt index 5c77c6d1bc..3d9714a420 100644 --- a/ext/pcre/tests/split2.phpt +++ b/ext/pcre/tests/split2.phpt @@ -13,14 +13,13 @@ var_dump(preg_split('/(\d*)/', 'ab2c3u', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPL var_dump(preg_split('/(\d*)/', 'ab2c3u', -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE)); -var_dump(preg_last_error(1)); ini_set('pcre.recursion_limit', 1); var_dump(preg_last_error() == PREG_NO_ERROR); var_dump(preg_split('/(\d*)/', 'ab2c3u')); var_dump(preg_last_error() == PREG_RECURSION_LIMIT_ERROR); ?> ---EXPECTF-- +--EXPECT-- array(15) { [0]=> string(0) "" @@ -306,9 +305,6 @@ array(6) { int(5) } } - -Warning: preg_last_error() expects exactly 0 parameters, 1 given in %s on line %d -NULL bool(true) bool(false) bool(true) |
