Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c1fa560

Browse files
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-19577: avoid integer overflow when using a small offset and PHP_INT_MAX with LimitIterator (#19585)
2 parents c34558d + 7cceda1 commit c1fa560

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

‎ext/spl/spl_iterators.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,14 +2115,27 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type)
21152115
}
21162116
/* }}} */
21172117

2118+
/* Returns the relative position for the current iterator position. */
2119+
static zend_long spl_limit_it_relative_pos(spl_dual_it_object *intern)
2120+
{
2121+
return intern->current.pos - intern->u.limit.offset;
2122+
}
2123+
2124+
/* Returns the relative position for an arbitrary position. */
2125+
static zend_long spl_limit_it_relative_pos_for(spl_dual_it_object *intern, zend_long pos)
2126+
{
2127+
return pos - intern->u.limit.offset;
2128+
}
2129+
21182130
static inline zend_result spl_limit_it_valid(spl_dual_it_object *intern)
21192131
{
21202132
/* FAILURE / SUCCESS */
2121-
if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) {
2133+
if (intern->u.limit.count != -1 &&
2134+
spl_limit_it_relative_pos(intern) >= intern->u.limit.count) {
21222135
return FAILURE;
2123-
} else {
2124-
return spl_dual_it_valid(intern);
21252136
}
2137+
2138+
return spl_dual_it_valid(intern);
21262139
}
21272140

21282141
static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
@@ -2134,7 +2147,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
21342147
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);
21352148
return;
21362149
}
2137-
if (pos-intern->u.limit.offset >= intern->u.limit.count && intern->u.limit.count != -1) {
2150+
if (spl_limit_it_relative_pos_for(intern, pos) >= intern->u.limit.count && intern->u.limit.count != -1) {
21382151
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);
21392152
return;
21402153
}
@@ -2191,7 +2204,7 @@ PHP_METHOD(LimitIterator, valid)
21912204
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
21922205

21932206
/* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/
2194-
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);
2207+
RETURN_BOOL((intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
21952208
} /* }}} */
21962209

21972210
/* {{{ Move the iterator forward */
@@ -2204,7 +2217,7 @@ PHP_METHOD(LimitIterator, next)
22042217
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
22052218

22062219
spl_dual_it_next(intern, 1);
2207-
if (intern->u.limit.count == -1 || intern->current.pos<intern->u.limit.offset+ intern->u.limit.count) {
2220+
if (intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) {
22082221
spl_dual_it_fetch(intern, 1);
22092222
}
22102223
} /* }}} */

‎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)

AltStyle によって変換されたページ (->オリジナル) /