From c56701690a184c13fa850e9946f09bac7172c604 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 16 Dec 2020 17:01:15 +0100 Subject: [PATCH] Detect overlarge step for character range() This was done for int and float ranges, but not char ranges. Fixes oss-fuzz #28666. --- ext/standard/array.c | 4 ++-- ext/standard/tests/array/range_errors.phpt | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index f99af84611..3967d83242 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -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; } diff --git a/ext/standard/tests/array/range_errors.phpt b/ext/standard/tests/array/range_errors.phpt index dd8b69a82a..7bc552ee97 100644 --- a/ext/standard/tests/array/range_errors.phpt +++ b/ext/standard/tests/array/range_errors.phpt @@ -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 -- 2.50.1