From a4bb03a84b8a1d81d896fb7a8bf3267cdafc5405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 26 Sep 2026 09:44:28 +0200 Subject: [PATCH] standard: Take `HashTable*` instead of `zval*` in `php_explode()` (#23910) --- UPGRADING.INTERNALS | 4 ++++ ext/standard/php_string.h | 2 +- ext/standard/string.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 4b5eed39a7b5..a97aa97e5283 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -29,6 +29,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES 3. Module changes ======================== +- Standard: + . php_explode() now takes a HashTable* instead of a zval* to store the + resulting parts. It already expected the zval* to be IS_ARRAY. + ======================== 4. OpCode changes ======================== diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 412a4a4fa7a6..7b8f8a8d3da7 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -50,7 +50,7 @@ PHPAPI zend_string *php_trim(zend_string *str, const char *what, size_t what_len PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len); PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_t allow_len, bool allow_tag_spaces); PHPAPI void php_implode(const zend_string *delim, HashTable *arr, zval *return_value); -PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit); +PHPAPI void php_explode(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit); PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); diff --git a/ext/standard/string.c b/ext/standard/string.c index bfe0c71795bf..ddd3f31bf14f 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -875,7 +875,7 @@ PHP_FUNCTION(wordwrap) /* }}} */ /* {{{ php_explode */ -PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit) +PHPAPI void php_explode(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit) { const char *p1 = ZSTR_VAL(str); const char *endp = ZSTR_VAL(str) + ZSTR_LEN(str); @@ -884,10 +884,10 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return if (p2 == NULL) { ZVAL_STR_COPY(&tmp, str); - zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); + zend_hash_next_index_insert_new(parts, &tmp); } else { - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { + zend_hash_real_init_packed(parts); + ZEND_HASH_FILL_PACKED(parts) { do { ZEND_HASH_FILL_GROW(); ZEND_HASH_FILL_SET_STR(zend_string_init_fast(p1, p2 - p1)); @@ -907,7 +907,7 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return /* }}} */ /* {{{ php_explode_negative_limit */ -PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit) +static void php_explode_negative_limit(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit) { #define EXPLODE_ALLOC_STEP 64 const char *p1 = ZSTR_VAL(str); @@ -939,7 +939,7 @@ PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *st /* limit is at least -1 therefore no need of bounds checking : i will be always less than found */ for (i = 0; i < to_return; i++) { /* this checks also for to_return > 0 */ ZVAL_STRINGL_FAST(&tmp, positions[i], (positions[i+1] - ZSTR_LEN(delim)) - positions[i]); - zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); + zend_hash_next_index_insert_new(parts, &tmp); } efree((void *)positions); } @@ -977,9 +977,9 @@ PHP_FUNCTION(explode) } if (limit > 1) { - php_explode(delim, str, return_value, limit); + php_explode(delim, str, Z_ARRVAL_P(return_value), limit); } else if (limit < 0) { - php_explode_negative_limit(delim, str, return_value, limit); + php_explode_negative_limit(delim, str, Z_ARRVAL_P(return_value), limit); } else { ZVAL_STR_COPY(&tmp, str); zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);