]> granicus.if.org Git - php/commitdiff
Detect overlarge step for character range()
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 16 Dec 2020 16:01:15 +0000 (17:01 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 16 Dec 2020 16:01:15 +0000 (17:01 +0100)
This was done for int and float ranges, but not char ranges.

Fixes oss-fuzz #28666.

ext/standard/array.c
ext/standard/tests/array/range_errors.phpt

index f99af846114dd57cb870ccd1d54cb12f8f709f33..3967d832429d036d3c75db656544c92a2145d437 100644 (file)
@@ -2756,7 +2756,7 @@ PHP_FUNCTION(range)
                high = (unsigned char)Z_STRVAL_P(zhigh)[0];
 
                if (low > high) {               /* Negative Steps */
-                       if (lstep <= 0) {
+                       if (low - high < lstep || lstep <= 0) {
                                err = 1;
                                goto err;
                        }
@@ -2773,7 +2773,7 @@ PHP_FUNCTION(range)
                                }
                        } ZEND_HASH_FILL_END();
                } else if (high > low) {        /* Positive Steps */
-                       if (lstep <= 0) {
+                       if (high - low < lstep || lstep <= 0) {
                                err = 1;
                                goto err;
                        }
index dd8b69a82a663d3ebc31dba6ef5cb16ca49d0d35..7bc552ee978f9a9306a9eec3610132b9bc866d78 100644 (file)
@@ -47,6 +47,20 @@ try {
     echo $e->getMessage(), "\n";
 }
 
+echo "\n\n-- Testing ( (low < high) && (high-low < step) ) for characters --\n";
+try {
+    var_dump(range('a', 'z', 100));
+} catch (\ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
+echo "\n\n-- Testing ( (low > high) && (low-high < step) ) for characters --\n";
+try {
+    var_dump(range('z', 'a', 100));
+} catch (\ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
 echo "\n-- Testing other conditions --\n";
 try {
     var_dump( range(-1, -2, 2) );
@@ -97,6 +111,14 @@ range(): Argument #3 ($step) must not exceed the specified range
 -- Testing ( (low > high) && (low-high < step) ) --
 range(): Argument #3 ($step) must not exceed the specified range
 
+
+-- Testing ( (low < high) && (high-low < step) ) for characters --
+range(): Argument #3 ($step) must not exceed the specified range
+
+
+-- Testing ( (low > high) && (low-high < step) ) for characters --
+range(): Argument #3 ($step) must not exceed the specified range
+
 -- Testing other conditions --
 range(): Argument #3 ($step) must not exceed the specified range
 range(): Argument #3 ($step) must be of type int|float, string given