diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 6abdc98bd6d..8f72164a269 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -979,6 +979,13 @@ PHP_FUNCTION(unpack) zend_string *buf; zend_long ipos, opos; + + if (size > INT_MAX / 2) { + zend_string_release(real_name); + zend_argument_value_error(1, "repeater must be less than or equal to %d", INT_MAX / 2); + RETURN_THROWS(); + } + /* If size was given take minimum of len and size */ if (size >= 0 && len > (size * 2)) { len = size * 2; diff --git a/ext/standard/tests/strings/gh15613.phpt b/ext/standard/tests/strings/gh15613.phpt new file mode 100644 index 00000000000..8f40ee820c9 --- /dev/null +++ b/ext/standard/tests/strings/gh15613.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-15613 overflow on hex strings repeater value +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- +getMessage() . PHP_EOL; +} + +try { + unpack('H2147483647', str_repeat('X', 2**31 + 10)); +} catch (\ValueError $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +unpack(): Argument #1 ($format) repeater must be less than or equal to %d +unpack(): Argument #1 ($format) repeater must be less than or equal to %d