From b5c313805f88a2cceb660f7255501c23614e5a35 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 24 Apr 2025 20:09:22 +0200 Subject: [PATCH] Fix GH-18421: Integer overflow with large numbers in LimitIterator Since we already know that `pos < intern->u.limit.offset` at this point, we can reverse the expression. --- ext/spl/spl_iterators.c | 2 +- ext/spl/tests/gh18421.phpt | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/gh18421.phpt diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 185c84433473..d41dbee81c38 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2228,7 +2228,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos) zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is below the offset " ZEND_LONG_FMT, pos, intern->u.limit.offset); return; } - if (pos >= intern->u.limit.offset + intern->u.limit.count && intern->u.limit.count != -1) { + if (pos - intern->u.limit.offset >= intern->u.limit.count && intern->u.limit.count != -1) { zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is behind offset " ZEND_LONG_FMT " plus count " ZEND_LONG_FMT, pos, intern->u.limit.offset, intern->u.limit.count); return; } diff --git a/ext/spl/tests/gh18421.phpt b/ext/spl/tests/gh18421.phpt new file mode 100644 index 000000000000..42584ef8aacc --- /dev/null +++ b/ext/spl/tests/gh18421.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-18421 (Integer overflow with large numbers in LimitIterator) +--FILE-- + 0, 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5); +try { + foreach (new LimitIterator(new ArrayIterator($a), PHP_INT_MAX, PHP_INT_MAX) as $k => $v) + { + } +} catch (OutOfBoundsException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +Seek position %d is out of range