Skip to content

Promote warnings to errors in range() #4573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2704,8 +2704,9 @@ PHP_FUNCTION(array_fill_keys)
#define RANGE_CHECK_DOUBLE_INIT_ARRAY(start, end) do { \
double __calc_size = ((start - end) / step) + 1; \
if (__calc_size >= (double)HT_MAX_SIZE) { \
php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=%0.0f end=%0.0f", end, start); \
RETURN_FALSE; \
zend_throw_error(NULL, \
"The supplied range exceeds the maximum array size: start=%0.0f end=%0.0f", end, start); \
return; \
} \
size = (uint32_t)_php_math_round(__calc_size, 0, PHP_ROUND_HALF_UP); \
array_init_size(return_value, size); \
Expand All @@ -2715,15 +2716,16 @@ PHP_FUNCTION(array_fill_keys)
#define RANGE_CHECK_LONG_INIT_ARRAY(start, end) do { \
zend_ulong __calc_size = ((zend_ulong) start - end) / lstep; \
if (__calc_size >= HT_MAX_SIZE - 1) { \
php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \
RETURN_FALSE; \
zend_throw_error(NULL, \
"The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \
return; \
} \
size = (uint32_t)(__calc_size + 1); \
array_init_size(return_value, size); \
zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); \
} while (0)

/* {{{ proto array|false range(mixed low, mixed high[, int step])
/* {{{ proto array range(mixed low, mixed high[, int step])
Create an array containing the range of integers or characters from low to high (inclusive) */
PHP_FUNCTION(range)
{
Expand Down Expand Up @@ -2812,8 +2814,8 @@ PHP_FUNCTION(range)
high = zval_get_double(zhigh);

if (zend_isinf(high) || zend_isinf(low)) {
php_error_docref(NULL, E_WARNING, "Invalid range supplied: start=%0.0f end=%0.0f", low, high);
RETURN_FALSE;
zend_throw_error(NULL, "Invalid range supplied: start=%0.0f end=%0.0f", low, high);
return;
}

if (low > high) { /* Negative steps */
Expand Down Expand Up @@ -2905,8 +2907,8 @@ PHP_FUNCTION(range)
}
err:
if (err) {
php_error_docref(NULL, E_WARNING, "step exceeds the specified range");
RETURN_FALSE;
zend_throw_error(NULL, "step exceeds the specified range");
return;
}
}
/* }}} */
Expand Down
10 changes: 7 additions & 3 deletions ext/standard/tests/array/range_bug70239_0.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 1
--FILE--
<?php
range(0, pow(2.0, 100000000));
try {
range(0, pow(2.0, 100000000));
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
?>
===DONE===
--EXPECTF--
Warning: range(): Invalid range supplied: start=0 end=inf in %srange_bug70239_0.php on line %d
--EXPECT--
Invalid range supplied: start=0 end=inf
===DONE===
10 changes: 7 additions & 3 deletions ext/standard/tests/array/range_bug70239_1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 2
--FILE--
<?php
range(pow(2.0, 100000000), pow(2.0, 100000000) + 1);
try {
range(pow(2.0, 100000000), pow(2.0, 100000000) + 1);
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
?>
===DONE===
--EXPECTF--
Warning: range(): Invalid range supplied: start=inf end=inf in %srange_bug70239_1.php on line %d
--EXPECT--
Invalid range supplied: start=inf end=inf
===DONE===
9 changes: 6 additions & 3 deletions ext/standard/tests/array/range_bug70239_2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 3
--FILE--
<?php
var_dump(range(0, PHP_INT_MAX));
try {
var_dump(range(0, PHP_INT_MAX));
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
?>
===DONE===
--EXPECTF--
Warning: range(): The supplied range exceeds the maximum array size: start=0 end=%d in %srange_bug70239_2.php on line %d
bool(false)
The supplied range exceeds the maximum array size: start=0 end=%d
===DONE===
9 changes: 6 additions & 3 deletions ext/standard/tests/array/range_bug70239_3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 4
--FILE--
<?php
var_dump(range(PHP_INT_MIN, 0));
try {
var_dump(range(PHP_INT_MIN, 0));
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
?>
===DONE===
--EXPECTF--
Warning: range(): The supplied range exceeds the maximum array size: start=-%d end=0 in %srange_bug70239_3.php on line %d
bool(false)
The supplied range exceeds the maximum array size: start=-%d end=0
===DONE===
119 changes: 74 additions & 45 deletions ext/standard/tests/array/range_errors.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,82 @@ precision=14

echo "\n*** Testing error conditions ***\n";

echo "\n-- Testing ( (low < high) && (step = 0) ) --";
var_dump( range(1, 2, 0) );
var_dump( range("a", "b", 0) );
echo "\n-- Testing ( (low < high) && (step = 0) ) --\n";
try {
var_dump( range(1, 2, 0) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n\n-- Testing ( (low > high) && (step = 0) ) --";
var_dump( range(2, 1, 0) );
var_dump( range("b", "a", 0) );
try {
var_dump( range("a", "b", 0) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n\n-- Testing ( (low < high) && (high-low < step) ) --";
var_dump( range(1.0, 7.0, 6.5) );
echo "\n\n-- Testing ( (low > high) && (step = 0) ) --\n";
try {
var_dump( range(2, 1, 0) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n\n-- Testing ( (low > high) && (low-high < step) ) --";
var_dump( range(7.0, 1.0, 6.5) );
try {
var_dump( range("b", "a", 0) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n\n-- Testing ( (low < high) && (high-low < step) ) --\n";
try {
var_dump( range(1.0, 7.0, 6.5) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n\n-- Testing ( (low > high) && (low-high < step) ) --\n";
try {
var_dump( range(7.0, 1.0, 6.5) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n-- Testing other conditions --\n";
try {
var_dump( range(-1, -2, 2) );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

echo "\n-- Testing other conditions --";
var_dump( range(-1, -2, 2) );
try {
var_dump( range("a", "j", "z") );
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

try {
var_dump( range(0, 1, "140962482048819216326.24") );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

try {
var_dump( range(0, 1, "140962482048819216326.24.") );
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}
var_dump( range(0, 1, "140962482048819216326.24") );
var_dump( range(0, 1, "140962482048819216326.24.") );

echo "\n-- Testing Invalid steps --";
echo "\n-- Testing Invalid steps --\n";
$step_arr = array( "string", NULL, FALSE, "", "\0" );

foreach( $step_arr as $step ) {
try {
var_dump( range( 1, 5, $step ) );
} catch (TypeError $e) {
} catch (\TypeError $e) {
echo $e->getMessage(), "\n";
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}
}
Expand All @@ -48,50 +93,34 @@ echo "Done\n";
*** Testing error conditions ***

-- Testing ( (low < high) && (step = 0) ) --
Warning: range(): step exceeds the specified range in %s on line %d
bool(false)

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range
step exceeds the specified range


-- Testing ( (low > high) && (step = 0) ) --
Warning: range(): step exceeds the specified range in %s on line %d
bool(false)

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range
step exceeds the specified range


-- Testing ( (low < high) && (high-low < step) ) --
Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range


-- Testing ( (low > high) && (low-high < step) ) --
Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range

-- Testing other conditions --
Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range
range() expects parameter 3 to be int or float, string given

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
step exceeds the specified range

Notice: A non well formed numeric value encountered in %s on line %d
step exceeds the specified range

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)

-- Testing Invalid steps --range() expects parameter 3 to be int or float, string given

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)

Warning: range(): step exceeds the specified range in %s on line %d
bool(false)
-- Testing Invalid steps --
range() expects parameter 3 to be int or float, string given
step exceeds the specified range
step exceeds the specified range
range() expects parameter 3 to be int or float, string given
range() expects parameter 3 to be int or float, string given
Done