Skip to content

Commit b383ddf

Browse files
committed
Fixed bug #62477 LimitIterator int overflow
1 parent bcf5853 commit b383ddf

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

ext/spl/spl_iterators.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,12 +1380,31 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
13801380
intern->dit_type = dit_type;
13811381
switch (dit_type) {
13821382
case DIT_LimitIterator: {
1383+
zval *tmp_offset, *tmp_count;
13831384
intern->u.limit.offset = 0; /* start at beginning */
13841385
intern->u.limit.count = -1; /* get all */
1385-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &zobject, ce_inner, &intern->u.limit.offset, &intern->u.limit.count) == FAILURE) {
1386+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|zz", &zobject, ce_inner, &tmp_offset, &tmp_count) == FAILURE) {
13861387
zend_restore_error_handling(&error_handling TSRMLS_CC);
13871388
return NULL;
13881389
}
1390+
if (tmp_offset && Z_TYPE_P(tmp_offset) != IS_NULL) {
1391+
if (Z_TYPE_P(tmp_offset) != IS_LONG) {
1392+
zend_throw_exception(spl_ce_OutOfRangeException, "offset param must be of type int", 0 TSRMLS_CC);
1393+
zend_restore_error_handling(&error_handling TSRMLS_CC);
1394+
return NULL;
1395+
} else {
1396+
intern->u.limit.offset = Z_LVAL_P(tmp_offset);
1397+
}
1398+
}
1399+
if (tmp_count && Z_TYPE_P(tmp_count) != IS_NULL) {
1400+
if (Z_TYPE_P(tmp_count) != IS_LONG) {
1401+
zend_throw_exception(spl_ce_OutOfRangeException, "count param must be of type int", 0 TSRMLS_CC);
1402+
zend_restore_error_handling(&error_handling TSRMLS_CC);
1403+
return NULL;
1404+
} else {
1405+
intern->u.limit.count = Z_LVAL_P(tmp_count);
1406+
}
1407+
}
13891408
if (intern->u.limit.offset < 0) {
13901409
zend_throw_exception(spl_ce_OutOfRangeException, "Parameter offset must be >= 0", 0 TSRMLS_CC);
13911410
zend_restore_error_handling(&error_handling TSRMLS_CC);

ext/spl/spl_iterators.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ typedef struct _spl_dual_it_object {
128128
uint str_key_len;
129129
ulong int_key;
130130
int key_type; /* HASH_KEY_IS_STRING or HASH_KEY_IS_LONG */
131-
int pos;
131+
long pos;
132132
} current;
133133
dual_it_type dit_type;
134134
union {

ext/spl/tests/bug62477_1.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #62477 LimitIterator int overflow when float is passed (1)
3+
--FILE--
4+
<?php
5+
6+
$it = new LimitIterator(new ArrayIterator(array(42)), 10000000000000000000);
7+
--EXPECTF--
8+
Fatal error: Uncaught exception 'OutOfRangeException' with message 'offset param must be of type int' in %sbug62477_1.php:%d
9+
Stack trace:
10+
#0 %sbug62477_1.php(%d): LimitIterator->__construct(Object(ArrayIterator), %f)
11+
#1 {main}
12+
thrown in %sbug62477_1.php on line %d

ext/spl/tests/bug62477_2.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #62477 LimitIterator int overflow when float is passed (2)
3+
--FILE--
4+
<?php
5+
6+
$it = new LimitIterator(new ArrayIterator(array(42)), 0, 10000000000000000000);
7+
--EXPECTF--
8+
Fatal error: Uncaught exception 'OutOfRangeException' with message 'count param must be of type int' in %sbug62477_2.php:%d
9+
Stack trace:
10+
#0 %sbug62477_2.php(%d): LimitIterator->__construct(Object(ArrayIterator), 0, %f)
11+
#1 {main}
12+
thrown in %sbug62477_2.php on line %d

0 commit comments

Comments
 (0)