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