mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-19577: avoid integer overflow when using a small offset and PHP_INT_MAX with LimitIterator (#19585)
This commit is contained in:
committed by
GitHub
parent
d10ff9bbd8
commit
05133ac962
2
NEWS
2
NEWS
@@ -35,6 +35,8 @@ PHP NEWS
|
||||
|
||||
- Standard:
|
||||
. Fixed bug GH-16649 (UAF during array_splice). (alexandre-daubois)
|
||||
. Fixed bug GH-19577 (Avoid integer overflow when using a small offset
|
||||
and PHP_INT_MAX with LimitIterator). (alexandre-daubois)
|
||||
|
||||
- Streams:
|
||||
. Remove incorrect call to zval_ptr_dtor() in user_wrapper_metadata().
|
||||
|
||||
@@ -2209,14 +2209,27 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Returns the relative position for the current iterator position. */
|
||||
static zend_long spl_limit_it_relative_pos(spl_dual_it_object *intern)
|
||||
{
|
||||
return intern->current.pos - intern->u.limit.offset;
|
||||
}
|
||||
|
||||
/* Returns the relative position for an arbitrary position. */
|
||||
static zend_long spl_limit_it_relative_pos_for(spl_dual_it_object *intern, zend_long pos)
|
||||
{
|
||||
return pos - intern->u.limit.offset;
|
||||
}
|
||||
|
||||
static inline int spl_limit_it_valid(spl_dual_it_object *intern)
|
||||
{
|
||||
/* FAILURE / SUCCESS */
|
||||
if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) {
|
||||
if (intern->u.limit.count != -1 &&
|
||||
spl_limit_it_relative_pos(intern) >= intern->u.limit.count) {
|
||||
return FAILURE;
|
||||
} else {
|
||||
return spl_dual_it_valid(intern);
|
||||
}
|
||||
|
||||
return spl_dual_it_valid(intern);
|
||||
}
|
||||
|
||||
static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
|
||||
@@ -2228,7 +2241,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 (spl_limit_it_relative_pos_for(intern, pos) >= 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;
|
||||
}
|
||||
@@ -2289,7 +2302,7 @@ PHP_METHOD(LimitIterator, valid)
|
||||
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
|
||||
|
||||
/* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/
|
||||
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);
|
||||
RETURN_BOOL((intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ Move the iterator forward */
|
||||
@@ -2304,7 +2317,7 @@ PHP_METHOD(LimitIterator, next)
|
||||
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);
|
||||
|
||||
spl_dual_it_next(intern, 1);
|
||||
if (intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) {
|
||||
if (intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) {
|
||||
spl_dual_it_fetch(intern, 1);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
16
ext/spl/tests/gh19577.phpt
Normal file
16
ext/spl/tests/gh19577.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
GH-19577: Integer overflow in LimitIterator with small offset and PHP_INT_MAX count
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$it = new ArrayIterator(array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'));
|
||||
$it = new LimitIterator($it, 2, PHP_INT_MAX);
|
||||
|
||||
foreach($it as $val => $key) {
|
||||
echo "Key: $val, Value: $key\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Key: 2, Value: C
|
||||
Key: 3, Value: D
|
||||
Reference in New Issue
Block a user