From 38c19d43c10fd41063ea0ef60f41da23e098678e Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 14 Aug 2015 14:12:22 +0200 Subject: [PATCH] fix array size calculation for range, related to bug #70239 --- ext/standard/array.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index ddbbe4cafe..b6684c8dca 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1637,6 +1637,16 @@ PHP_FUNCTION(array_fill_keys) } /* }}} */ +#define RANGE_CHECK_INIT_ARRAY(start, end) do { \ + double __calc_size = ((start - end) / step) + 1; \ + if (fabs(__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", start > end ? end : start, start > end ? start : end); \ + RETURN_FALSE; \ + } \ + array_init_size(return_value, (uint32_t)fabs(__calc_size)); \ + zend_hash_real_init(Z_ARRVAL_P(return_value), 1); \ + } while (0) + /* {{{ 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) @@ -1752,8 +1762,7 @@ double_str: goto err; } - array_init_size(return_value, (uint32_t)(((low - high) / step) + 1)); - zend_hash_real_init(Z_ARRVAL_P(return_value), 1); + RANGE_CHECK_INIT_ARRAY(low, high); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { for (value = low; value >= (high - DOUBLE_DRIFT_FIX); value = low - (++i * step)) { Z_DVAL(tmp) = value; @@ -1766,8 +1775,7 @@ double_str: goto err; } - array_init_size(return_value, (uint32_t)(((high - low) / step) + 1)); - zend_hash_real_init(Z_ARRVAL_P(return_value), 1); + RANGE_CHECK_INIT_ARRAY(high, low); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) { Z_DVAL(tmp) = value; @@ -1793,8 +1801,8 @@ long_str: err = 1; goto err; } - array_init_size(return_value, (uint32_t)(((low - high) / lstep) + 1)); - zend_hash_real_init(Z_ARRVAL_P(return_value), 1); + + RANGE_CHECK_INIT_ARRAY(low, high); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { for (; low >= high; low -= lstep) { Z_LVAL(tmp) = (zend_long)low; @@ -1806,8 +1814,8 @@ long_str: err = 1; goto err; } - array_init_size(return_value, (uint32_t)(((high - low) / lstep) + 1)); - zend_hash_real_init(Z_ARRVAL_P(return_value), 1); + + RANGE_CHECK_INIT_ARRAY(high, low); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { for (; low <= high; low += lstep) { Z_LVAL(tmp) = (zend_long)low; @@ -1828,6 +1836,8 @@ err: } /* }}} */ +#undef RANGE_CHECK_INIT_ARRAY + static void php_array_data_shuffle(zval *array) /* {{{ */ { uint32_t idx, j, n_elems; -- 2.40.0