Skip to content

Commit c18c3b7

Browse files
Fix GH-19577: avoid integer overflow when using a small offset and PHP_INT_MAX with LimitIterator
1 parent 96c0bc5 commit c18c3b7

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ PHP NEWS
2323

2424
- Standard:
2525
. Fixed bug GH-16649 (UAF during array_splice). (alexandre-daubois)
26+
. Fixed bug GH-19577 (Avoid integer overflow when using a small offset
27+
and PHP_INT_MAX with LimitIterator). (alexandre-daubois)
2628

2729
- Tidy:
2830
. Fixed GH-19021 build issue with libtidy in regard of tidyOptIsReadonly

ext/spl/spl_iterators.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,11 +2212,12 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type)
22122212
static inline int spl_limit_it_valid(spl_dual_it_object *intern)
22132213
{
22142214
/* FAILURE / SUCCESS */
2215-
if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) {
2215+
if (intern->u.limit.count != -1 &&
2216+
(intern->current.pos - intern->u.limit.offset) >= intern->u.limit.count) {
22162217
return FAILURE;
2217-
} else {
2218-
return spl_dual_it_valid(intern);
22192218
}
2219+
2220+
return spl_dual_it_valid(intern);
22202221
}
22212222

22222223
static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
@@ -2289,7 +2290,7 @@ PHP_METHOD(LimitIterator, valid)
22892290
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
22902291

22912292
/* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/
2292-
RETURN_BOOL((intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
2293+
RETURN_BOOL((intern->u.limit.count == -1 || (intern->current.pos - intern->u.limit.offset) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
22932294
} /* }}} */
22942295

22952296
/* {{{ Move the iterator forward */
@@ -2304,7 +2305,7 @@ PHP_METHOD(LimitIterator, next)
23042305
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
23052306

23062307
spl_dual_it_next(intern, 1);
2307-
if (intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) {
2308+
if (intern->u.limit.count == -1 || (intern->current.pos - intern->u.limit.offset) < intern->u.limit.count) {
23082309
spl_dual_it_fetch(intern, 1);
23092310
}
23102311
} /* }}} */

ext/spl/tests/gh19577.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-19577: Integer overflow in LimitIterator with small offset and PHP_INT_MAX count
3+
--FILE--
4+
<?php
5+
6+
$it = new ArrayIterator(array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'));
7+
$it = new LimitIterator($it, 2, PHP_INT_MAX);
8+
9+
foreach($it as $val => $key) {
10+
echo "Key: $val, Value: $key\n";
11+
}
12+
13+
?>
14+
--EXPECT--
15+
Key: 2, Value: C
16+
Key: 3, Value: D

0 commit comments

Comments
 (0)