From 52123ae828ce0ee7832cf090090d777f5576c33a Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 9 Nov 2025 00:39:18 +0100 Subject: [PATCH 1/2] standard: Remove redundant code in range() If we use signed integers (which fit the unsigned chars), then we can avoid the extra checks. Also move an exception check to the proper place. --- ext/standard/array.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 3a782ec1ea40..ebbddc896269 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -3040,9 +3040,9 @@ PHP_FUNCTION(range) if (start_type == IS_STRING || end_type == IS_STRING) { php_error_docref(NULL, E_WARNING, "Argument #3 ($step) must be of type int when generating an array" " of characters, inputs converted to 0"); - } - if (UNEXPECTED(EG(exception))) { - RETURN_THROWS(); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } end_type = IS_LONG; start_type = IS_LONG; @@ -3050,8 +3050,8 @@ PHP_FUNCTION(range) } /* Generate array of characters */ - unsigned char low = (unsigned char)Z_STRVAL_P(user_start)[0]; - unsigned char high = (unsigned char)Z_STRVAL_P(user_end)[0]; + int low = Z_STRVAL_P(user_start)[0]; + int high = Z_STRVAL_P(user_end)[0]; /* Decreasing char range */ if (low > high) { @@ -3062,12 +3062,9 @@ PHP_FUNCTION(range) array_init_size(return_value, (uint32_t)(((low - high) / step) + 1)); zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { - for (; low >= high; low -= (unsigned int)step) { + for (; low >= high; low -= step) { ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low)); ZEND_HASH_FILL_NEXT(); - if (((signed int)low - step) < 0) { - break; - } } } ZEND_HASH_FILL_END(); } else if (high > low) { /* Increasing char range */ @@ -3080,12 +3077,9 @@ PHP_FUNCTION(range) array_init_size(return_value, (uint32_t)(((high - low) / step) + 1)); zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { - for (; low <= high; low += (unsigned int)step) { + for (; low <= high; low += step) { ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low)); ZEND_HASH_FILL_NEXT(); - if (((signed int)low + step) > 255) { - break; - } } } ZEND_HASH_FILL_END(); } else { From 08478c79cf2eef7b49bc32593950cacfea992abf Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 9 Nov 2025 11:32:06 +0100 Subject: [PATCH 2/2] [ci skip] comment --- ext/standard/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index ebbddc896269..eac3d516e3f8 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -3049,7 +3049,7 @@ PHP_FUNCTION(range) goto handle_numeric_inputs; } - /* Generate array of characters */ + /* Generate array of characters, as ints to make bounds checking possible in the loop condition */ int low = Z_STRVAL_P(user_start)[0]; int high = Z_STRVAL_P(user_end)[0];