Commit a91d913901a for php.net
commit a91d913901a532e9fef67940942b6274a3fe2bf2
Author: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Thu Apr 24 20:09:22 2025 +0200
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.
Closes GH-18424.
diff --git a/NEWS b/NEWS
index 409972a1fe9..bc5a597b619 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ PHP NEWS
inaccurate sunrise and sunset times, but other calculated times are
correct) (JiriJozif).
+- SPL:
+ . Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator).
+ (nielsdos)
+
- Standard:
. Fixed bug GH-17403 (Potential deadlock when putenv fails). (nielsdos)
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index 185c8443347..d41dbee81c3 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 00000000000..42584ef8aac
--- /dev/null
+++ b/ext/spl/tests/gh18421.phpt
@@ -0,0 +1,17 @@
+--TEST--
+GH-18421 (Integer overflow with large numbers in LimitIterator)
+--FILE--
+<?php
+
+$a = array('zero' => 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