Skip to content

Commit 107ddf7

Browse files
committed
Promote warnings to Error in SPL array and use new format
1 parent da9a9c8 commit 107ddf7

11 files changed

+82
-52
lines changed

ext/spl/spl_array.c

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ static zval *spl_array_get_dimension_ptr(int check_inherited, spl_array_object *
298298
}
299299

300300
if ((type == BP_VAR_W || type == BP_VAR_RW) && intern->nApplyCount > 0) {
301-
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
301+
zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited");
302302
return &EG(error_zval);
303303
}
304304

@@ -386,9 +386,8 @@ static zval *spl_array_get_dimension_ptr(int check_inherited, spl_array_object *
386386
ZVAL_DEREF(offset);
387387
goto try_again;
388388
default:
389-
zend_error(E_WARNING, "Illegal offset type");
390-
return (type == BP_VAR_W || type == BP_VAR_RW) ?
391-
&EG(error_zval) : &EG(uninitialized_zval);
389+
zend_type_error("Must be int|string, %s given", zend_zval_type_name(offset));
390+
return NULL;
392391
}
393392
} /* }}} */
394393

@@ -446,7 +445,8 @@ static zval *spl_array_read_dimension(zend_object *object, zval *offset, int typ
446445
return spl_array_read_dimension_ex(1, object, offset, type, rv);
447446
} /* }}} */
448447

449-
static void spl_array_write_dimension_ex(int check_inherited, zend_object *object, zval *offset, zval *value) /* {{{ */
448+
static void spl_array_write_dimension_ex(int check_inherited, zend_object *object,
449+
zval *offset, zval *value, uint32_t offset_arg_num) /* {{{ */
450450
{
451451
spl_array_object *intern = spl_array_from_obj(object);
452452
zend_long index;
@@ -467,7 +467,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec
467467
}
468468

469469
if (intern->nApplyCount > 0) {
470-
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
470+
zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited");
471471
return;
472472
}
473473

@@ -510,15 +510,23 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec
510510
ZVAL_DEREF(offset);
511511
goto try_again;
512512
default:
513-
zend_error(E_WARNING, "Illegal offset type");
514513
zval_ptr_dtor(value);
514+
/* If offset_arg_num is 0 this mean the offset comes from an index use in [offset] */
515+
if (offset_arg_num == 0) {
516+
zend_type_error("Offsets must be int|string, %s given",
517+
zend_zval_type_name(offset));
518+
} else {
519+
zend_argument_type_error(offset_arg_num, "must be int|string, %s given",
520+
zend_zval_type_name(offset));
521+
}
515522
return;
516523
}
517524
} /* }}} */
518525

519526
static void spl_array_write_dimension(zend_object *object, zval *offset, zval *value) /* {{{ */
520527
{
521-
spl_array_write_dimension_ex(1, object, offset, value);
528+
/* Pass 0 as offset arg position to inform it comes from this handler */
529+
spl_array_write_dimension_ex(1, object, offset, value, 0);
522530
} /* }}} */
523531

524532
static void spl_array_unset_dimension_ex(int check_inherited, zend_object *object, zval *offset) /* {{{ */
@@ -535,7 +543,7 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec
535543
}
536544

537545
if (intern->nApplyCount > 0) {
538-
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
546+
zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited");
539547
return;
540548
}
541549

@@ -596,7 +604,7 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec
596604
ZVAL_DEREF(offset);
597605
goto try_again;
598606
default:
599-
zend_error(E_WARNING, "Illegal offset type");
607+
zend_type_error("Must be int|string, %s given", zend_zval_type_name(offset));
600608
return;
601609
}
602610
} /* }}} */
@@ -672,7 +680,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zend_object *object,
672680
ZVAL_DEREF(offset);
673681
goto try_again;
674682
default:
675-
zend_error(E_WARNING, "Illegal offset type");
683+
zend_type_error("Must be int|string, %s given", zend_zval_type_name(offset));
676684
return 0;
677685
}
678686

@@ -733,7 +741,7 @@ SPL_METHOD(Array, offsetSet)
733741
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &index, &value) == FAILURE) {
734742
RETURN_THROWS();
735743
}
736-
spl_array_write_dimension_ex(0, Z_OBJ_P(ZEND_THIS), index, value);
744+
spl_array_write_dimension_ex(0, Z_OBJ_P(ZEND_THIS), index, value, 1);
737745
} /* }}} */
738746

739747
void spl_array_iterator_append(zval *object, zval *append_value) /* {{{ */
@@ -1103,9 +1111,14 @@ static void spl_array_it_rewind(zend_object_iterator *iter) /* {{{ */
11031111
/* }}} */
11041112

11051113
/* {{{ spl_array_set_array */
1106-
static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, int just_array) {
1114+
static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array,
1115+
zend_long ar_flags, int just_array, uint32_t arg_num) {
11071116
if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) {
1108-
zend_type_error("Passed variable is not an array or object");
1117+
if (arg_num == 0) {
1118+
zend_type_error("Passed variable must be array|object, %s given", zend_zval_type_name(array));
1119+
} else {
1120+
zend_argument_type_error(arg_num, "must be array|object, %s given", zend_zval_type_name(array));
1121+
}
11091122
return;
11101123
}
11111124

@@ -1134,8 +1147,13 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
11341147
} else {
11351148
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
11361149
if (handler != zend_std_get_properties) {
1137-
zend_type_error("Overloaded object of type %s is not compatible with %s",
1138-
ZSTR_VAL(Z_OBJCE_P(array)->name), ZSTR_VAL(intern->std.ce->name));
1150+
if (arg_num == 0) {
1151+
zend_type_error("Overloaded object of type %s must be compatible with %s",
1152+
ZSTR_VAL(Z_OBJCE_P(array)->name), ZSTR_VAL(intern->std.ce->name));
1153+
} else {
1154+
zend_argument_type_error(arg_num, "must be compatible with %s",
1155+
ZSTR_VAL(intern->std.ce->name));
1156+
}
11391157
return;
11401158
}
11411159
zval_ptr_dtor(&intern->array);
@@ -1166,7 +1184,7 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object,
11661184
spl_array_object *array_object = Z_SPLARRAY_P(object);
11671185

11681186
if (by_ref && (array_object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT)) {
1169-
zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0);
1187+
zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
11701188
return NULL;
11711189
}
11721190

@@ -1210,7 +1228,7 @@ SPL_METHOD(Array, __construct)
12101228

12111229
ar_flags &= ~SPL_ARRAY_INT_MASK;
12121230

1213-
spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1);
1231+
spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1, 1);
12141232
}
12151233
/* }}} */
12161234

@@ -1235,7 +1253,7 @@ SPL_METHOD(ArrayIterator, __construct)
12351253

12361254
ar_flags &= ~SPL_ARRAY_INT_MASK;
12371255

1238-
spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1);
1256+
spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1, 1);
12391257
}
12401258
/* }}} */
12411259

@@ -1314,12 +1332,12 @@ SPL_METHOD(Array, exchangeArray)
13141332
}
13151333

13161334
if (intern->nApplyCount > 0) {
1317-
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
1335+
zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited");
13181336
return;
13191337
}
13201338

13211339
RETVAL_ARR(zend_array_dup(spl_array_get_hash_table(intern)));
1322-
spl_array_set_array(object, intern, array, 0L, 1);
1340+
spl_array_set_array(object, intern, array, 0L, 1, 1);
13231341
}
13241342
/* }}} */
13251343

@@ -1379,7 +1397,8 @@ SPL_METHOD(Array, seek)
13791397
return; /* ok */
13801398
}
13811399
}
1382-
zend_value_error("Seek position " ZEND_LONG_FMT " is out of range", opos);
1400+
zend_argument_value_error(1, "position " ZEND_LONG_FMT " is out of range", opos);
1401+
RETURN_THROWS();
13831402
} /* }}} */
13841403

13851404
static zend_long spl_array_object_count_elements_helper(spl_array_object *intern) /* {{{ */
@@ -1731,7 +1750,7 @@ SPL_METHOD(Array, unserialize)
17311750
}
17321751

17331752
if (intern->nApplyCount > 0) {
1734-
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
1753+
zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited");
17351754
return;
17361755
}
17371756

@@ -1787,7 +1806,7 @@ SPL_METHOD(Array, unserialize)
17871806
ZVAL_NULL(array);
17881807
SEPARATE_ARRAY(&intern->array);
17891808
} else {
1790-
spl_array_set_array(object, intern, array, 0L, 1);
1809+
spl_array_set_array(object, intern, array, 0L, 1, 0);
17911810
}
17921811

17931812
if (*p != ';') {
@@ -1816,6 +1835,7 @@ SPL_METHOD(Array, unserialize)
18161835

18171836
outexcept:
18181837
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
1838+
/* TODO Use standard Error? */
18191839
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Error at offset " ZEND_LONG_FMT " of %zd bytes", (zend_long)((char*)p - buf), buf_len);
18201840
RETURN_THROWS();
18211841

@@ -1883,7 +1903,7 @@ SPL_METHOD(Array, __unserialize)
18831903
zval_ptr_dtor(&intern->array);
18841904
ZVAL_UNDEF(&intern->array);
18851905
} else {
1886-
spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1);
1906+
spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1, 0);
18871907
}
18881908

18891909
object_properties_load(&intern->std, Z_ARRVAL_P(members_zv));

ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ $ao = new ArrayObject([1, 2, 3]);
77
$i = 0;
88
$ao->uasort(function($a, $b) use ($ao, &$i) {
99
if ($i++ == 0) {
10-
$ao->exchangeArray([4, 5, 6]);
10+
try {
11+
$ao->exchangeArray([4, 5, 6]);
12+
} catch (\Error $e) {
13+
echo $e->getMessage() .\PHP_EOL;
14+
}
1115
var_dump($ao);
1216
}
1317
return $a <=> $b;
1418
});
1519

1620
?>
17-
--EXPECTF--
18-
Warning: Modification of ArrayObject during sorting is prohibited in %s on line %d
21+
--EXPECT--
22+
Modification of ArrayObject during sorting is prohibited
1923
object(ArrayObject)#1 (1) {
2024
["storage":"ArrayObject":private]=>
2125
array(3) {

ext/spl/tests/ArrayObject_illegal_offset_leak.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ Assignments to illegal ArrayObject offsets shouldn't leak
44
<?php
55

66
$ao = new ArrayObject([1, 2, 3]);
7-
$ao[[]] = new stdClass;
7+
try {
8+
$ao[[]] = new stdClass;
9+
} catch (\TypeError $e) {
10+
echo $e->getMessage() . \PHP_EOL;
11+
}
812

913
?>
10-
--EXPECTF--
11-
Warning: Illegal offset type in %s on line %d
14+
--EXPECT--
15+
Offsets must be int|string, array given

ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var_dump($ao);
1313

1414
?>
1515
--EXPECT--
16-
Overloaded object of type SplFixedArray is not compatible with ArrayObject
16+
ArrayObject::exchangeArray(): Argument #1 ($input) must be compatible with ArrayObject
1717
object(ArrayObject)#1 (1) {
1818
["storage":"ArrayObject":private]=>
1919
array(3) {

ext/spl/tests/arrayObject_exchangeArray_basic3.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ NULL
103103

104104

105105
--> exchangeArray() with bad arg type:
106-
Passed variable is not an array or object
106+
ArrayObject::exchangeArray(): Argument #1 ($input) must be array|object, null given
107107

108108
Warning: Undefined variable $copy in %s on line %d
109109
object(ArrayObject)#3 (1) {

ext/spl/tests/array_014.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ foreach($it as $v)
3737
int(11)
3838
int(5)
3939
int(4)
40-
Seek position -1 is out of range
41-
Seek position 12 is out of range
40+
ArrayIterator::seek(): Argument #1 ($position) position -1 is out of range
41+
ArrayIterator::seek(): Argument #1 ($position) position 12 is out of range
4242
int(0)
4343
int(1)
4444
int(2)

ext/spl/tests/array_019.phpt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,16 @@ class ArrayIteratorEx extends ArrayIterator
1616
}
1717

1818
$ar = new ArrayIteratorEx(array(4)); foreach($ar as $v) var_dump($v);
19-
$ar = new ArrayIteratorEx(array(5)); foreach($ar as &$v) var_dump($v);
19+
try {
20+
$ar = new ArrayIteratorEx(array(5)); foreach($ar as &$v) var_dump($v);
21+
} catch (\Error $e) {
22+
echo $e->getMessage() . \PHP_EOL;
23+
}
2024

2125
?>
22-
===DONE===
23-
--EXPECTF--
26+
--EXPECT--
2427
int(1)
2528
int(2)
2629
int(3)
2730
int(4)
28-
29-
Fatal error: Uncaught RuntimeException: An iterator cannot be used with foreach by reference in %s:%d
30-
Stack trace:
31-
#0 {main}
32-
thrown in %s on line %d
31+
An iterator cannot be used with foreach by reference

ext/spl/tests/bug67539.phpt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ function badsort($a, $b) {
99
$GLOBALS['it']->unserialize($GLOBALS['it']->serialize());
1010
return TRUE;
1111
}
12-
13-
$it->uksort('badsort');
14-
--EXPECTF--
15-
Warning: Modification of ArrayObject during sorting is prohibited in %sbug67539.php on line %d
12+
try {
13+
$it->uksort('badsort');
14+
} catch (\Error $e) {
15+
echo $e->getMessage() . \PHP_EOL;
16+
}
17+
--EXPECT--
18+
Modification of ArrayObject during sorting is prohibited

ext/spl/tests/bug70155.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ try {
1313

1414
?>
1515
--EXPECT--
16-
Overloaded object of type DateInterval is not compatible with ArrayObject
16+
Overloaded object of type DateInterval must be compatible with ArrayObject

ext/spl/tests/spl_iterator_getcallchildren.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ try {
3030
int(9)
3131
}
3232
int(7)
33-
Passed variable is not an array or object
33+
ArrayIterator::__construct(): Argument #1 ($array) must be array|object, int given

ext/spl/tests/unserialize_errors.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,17 @@ try {
114114
}
115115

116116
?>
117-
--EXPECTF--
117+
--EXPECT--
118118
ArrayObject:
119119
Incomplete or ill-typed serialization data
120120
Incomplete or ill-typed serialization data
121121
Incomplete or ill-typed serialization data
122-
Passed variable is not an array or object
122+
Passed variable must be array|object, int given
123123
ArrayIterator:
124124
Incomplete or ill-typed serialization data
125125
Incomplete or ill-typed serialization data
126126
Incomplete or ill-typed serialization data
127-
Passed variable is not an array or object
127+
Passed variable must be array|object, int given
128128
SplDoublyLinkedList:
129129
Incomplete or ill-typed serialization data
130130
Incomplete or ill-typed serialization data

0 commit comments

Comments
 (0)