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 7cceda1

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

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
@@ -2124,14 +2124,27 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type)
21242124
}
21252125
/* }}} */
21262126

2127+
/* Returns the relative position for the current iterator position. */
2128+
static zend_long spl_limit_it_relative_pos(spl_dual_it_object *intern)
2129+
{
2130+
return intern->current.pos - intern->u.limit.offset;
2131+
}
2132+
2133+
/* Returns the relative position for an arbitrary position. */
2134+
static zend_long spl_limit_it_relative_pos_for(spl_dual_it_object *intern, zend_long pos)
2135+
{
2136+
return pos - intern->u.limit.offset;
2137+
}
2138+
21272139
static inline zend_result spl_limit_it_valid(spl_dual_it_object *intern)
21282140
{
21292141
/* FAILURE / SUCCESS */
2130-
if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) {
2142+
if (intern->u.limit.count != -1 &&
2143+
spl_limit_it_relative_pos(intern) >= intern->u.limit.count) {
21312144
return FAILURE;
2132-
} else {
2133-
return spl_dual_it_valid(intern);
21342145
}
2146+
2147+
return spl_dual_it_valid(intern);
21352148
}
21362149

21372150
static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
@@ -2143,7 +2156,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
21432156
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);
21442157
return;
21452158
}
2146-
if (pos-intern->u.limit.offset >= intern->u.limit.count && intern->u.limit.count != -1) {
2159+
if (spl_limit_it_relative_pos_for(intern, pos) >= intern->u.limit.count && intern->u.limit.count != -1) {
21472160
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);
21482161
return;
21492162
}
@@ -2200,7 +2213,7 @@ PHP_METHOD(LimitIterator, valid)
22002213
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
22012214

22022215
/* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/
2203-
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);
2216+
RETURN_BOOL((intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
22042217
} /* }}} */
22052218

22062219
/* {{{ Move the iterator forward */
@@ -2213,7 +2226,7 @@ PHP_METHOD(LimitIterator, next)
22132226
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
22142227

22152228
spl_dual_it_next(intern, 1);
2216-
if (intern->u.limit.count == -1 || intern->current.pos<intern->u.limit.offset+ intern->u.limit.count) {
2229+
if (intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) {
22172230
spl_dual_it_fetch(intern, 1);
22182231
}
22192232
} /* }}} */

‎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 によって変換されたページ (->オリジナル) /