From e3f2351d045a7aadf7e59b9302d361ddc51904b8 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:38:06 +0100 Subject: [PATCH 1/2] Remove array_pad's arbitrary length restriction The error message was wrong; it *is* possible to use a larger length. Furthermore, there is an arbitrary restriction on the new array's length. Fix both by checking the length against HT_MAX_SIZE. --- ext/standard/array.c | 9 +++++---- ext/standard/tests/array/array_pad.phpt | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 96a32da8e0552..c8afc08cffa62 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4344,13 +4344,14 @@ PHP_FUNCTION(array_pad) Z_PARAM_ZVAL(pad_value) ZEND_PARSE_PARAMETERS_END(); + if (pad_size < Z_L(-HT_MAX_SIZE) || pad_size > Z_L(HT_MAX_SIZE)) { + zend_argument_value_error(2, "must not exceed the maximum allowed array size"); + RETURN_THROWS(); + } + /* Do some initial calculations */ input_size = zend_hash_num_elements(Z_ARRVAL_P(input)); pad_size_abs = ZEND_ABS(pad_size); - if (pad_size_abs < 0 || pad_size_abs - input_size > Z_L(1048576)) { - zend_argument_value_error(2, "must be less than or equal to 1048576"); - RETURN_THROWS(); - } if (input_size >= pad_size_abs) { /* Copy the original array */ diff --git a/ext/standard/tests/array/array_pad.phpt b/ext/standard/tests/array/array_pad.phpt index 5abcbac87ef7d..1eab84831cd0c 100644 --- a/ext/standard/tests/array/array_pad.phpt +++ b/ext/standard/tests/array/array_pad.phpt @@ -84,4 +84,4 @@ array(4) { [3]=> float(2) } -array_pad(): Argument #2 ($length) must be less than or equal to 1048576 +array_pad(): Argument #2 ($length) is too large because it results in a padding of 1999997 elements, which is larger than the allowed 1048576 elements From 56f3ef496e0c967f085bb2c19cdaca8213b29e33 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 22 Dec 2022 20:20:20 +0100 Subject: [PATCH 2/2] Split array_pad() tests and add more edge case tests --- ext/standard/tests/array/array_pad.phpt | 7 ------- .../array/array_pad_too_large_padding.phpt | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 ext/standard/tests/array/array_pad_too_large_padding.phpt diff --git a/ext/standard/tests/array/array_pad.phpt b/ext/standard/tests/array/array_pad.phpt index 1eab84831cd0c..67cb423497ffb 100644 --- a/ext/standard/tests/array/array_pad.phpt +++ b/ext/standard/tests/array/array_pad.phpt @@ -13,12 +13,6 @@ var_dump(array_pad(array("", -1, 2.0), 2, array())); var_dump(array_pad(array("", -1, 2.0), -3, array())); var_dump(array_pad(array("", -1, 2.0), -4, array())); -try { - var_dump(array_pad(array("", -1, 2.0), 2000000, 0)); -} catch (\ValueError $e) { - echo $e->getMessage() . "\n"; -} - ?> --EXPECT-- array(1) { @@ -84,4 +78,3 @@ array(4) { [3]=> float(2) } -array_pad(): Argument #2 ($length) is too large because it results in a padding of 1999997 elements, which is larger than the allowed 1048576 elements diff --git a/ext/standard/tests/array/array_pad_too_large_padding.phpt b/ext/standard/tests/array/array_pad_too_large_padding.phpt new file mode 100644 index 0000000000000..3a45e834f9a01 --- /dev/null +++ b/ext/standard/tests/array/array_pad_too_large_padding.phpt @@ -0,0 +1,20 @@ +--TEST-- +array_pad() with too large padding should fail +--FILE-- +getMessage() . "\n"; + } +} + +test(PHP_INT_MIN); +test(PHP_INT_MAX); + +?> +--EXPECT-- +array_pad(): Argument #2 ($length) must not exceed the maximum allowed array size +array_pad(): Argument #2 ($length) must not exceed the maximum allowed array size