Skip to content

Commit 9da14e3

Browse files
committed
FixedArray stuff
Some conversions, some trying to wrap my brain around, maybe a bugfix also
1 parent 107ddf7 commit 9da14e3

13 files changed

+105
-79
lines changed

ext/spl/spl_fixedarray.c

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
237237
}
238238

239239
if (!parent) { /* this must never happen */
240-
php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray");
240+
zend_throw_error(NULL, "Internal compiler error, Class is not child of SplFixedArray");
241241
}
242242

243243
funcs_ptr = class_type->iterator_funcs_ptr;
@@ -307,25 +307,37 @@ static zend_object *spl_fixedarray_object_clone(zend_object *old_object) /* {{{
307307
}
308308
/* }}} */
309309

310-
static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset) /* {{{ */
310+
static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern,
311+
zval *offset, uint32_t offset_arg_num) /* {{{ */
311312
{
312313
zend_long index;
313314

314315
/* we have to return NULL on error here to avoid memleak because of
315316
* ZE duplicating uninitialized_zval_ptr */
316317
if (!offset) {
317-
zend_value_error("Index invalid or out of range");
318+
zend_throw_error(NULL, "Must provided an index to read");
318319
return NULL;
319320
}
320321

321322
if (Z_TYPE_P(offset) != IS_LONG) {
322323
index = spl_offset_convert_to_long(offset);
324+
if (index == -1) {
325+
if (offset_arg_num == 0) {
326+
zend_value_error("Offset must be numeric");
327+
} else {
328+
zend_argument_value_error(offset_arg_num, "must be numeric");
329+
}
330+
}
323331
} else {
324332
index = Z_LVAL_P(offset);
325333
}
326334

327335
if (index < 0 || index >= intern->array.size) {
328-
zend_value_error("Index invalid or out of range");
336+
if (offset_arg_num == 0) {
337+
zend_value_error("Offset is out of range");
338+
} else {
339+
zend_argument_value_error(offset_arg_num, "is out of range");
340+
}
329341
return NULL;
330342
} else {
331343
return &intern->array.elements[index];
@@ -339,20 +351,20 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off
339351
{
340352
spl_fixedarray_object *intern;
341353

354+
if (!offset) {
355+
/* This emits a Notice
356+
Indirect modification of overloaded element of SplFixedArray has no effect */
357+
return &EG(uninitialized_zval);
358+
}
359+
342360
intern = spl_fixed_array_from_obj(object);
343361

344362
if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension(object, offset, 0)) {
345363
return &EG(uninitialized_zval);
346364
}
347365

348366
if (intern->fptr_offset_get) {
349-
zval tmp;
350-
if (!offset) {
351-
ZVAL_NULL(&tmp);
352-
offset = &tmp;
353-
} else {
354-
SEPARATE_ARG_IF_REF(offset);
355-
}
367+
SEPARATE_ARG_IF_REF(offset);
356368
zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", rv, offset);
357369
zval_ptr_dtor(offset);
358370
if (!Z_ISUNDEF_P(rv)) {
@@ -361,19 +373,16 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off
361373
return &EG(uninitialized_zval);
362374
}
363375

364-
return spl_fixedarray_object_read_dimension_helper(intern, offset);
376+
return spl_fixedarray_object_read_dimension_helper(intern, offset, 0);
365377
}
366378
/* }}} */
367379

368-
static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value) /* {{{ */
380+
static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern,
381+
zval *offset, zval *value, uint32_t offset_arg_num) /* {{{ */
369382
{
370383
zend_long index;
371384

372-
if (!offset) {
373-
/* '$array[] = value' syntax is not supported */
374-
zend_value_error("Index invalid or out of range");
375-
return;
376-
}
385+
ZEND_ASSERT(offset != NULL);
377386

378387
if (Z_TYPE_P(offset) != IS_LONG) {
379388
index = spl_offset_convert_to_long(offset);
@@ -382,7 +391,11 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
382391
}
383392

384393
if (index < 0 || index >= intern->array.size) {
385-
zend_value_error("Index invalid or out of range");
394+
if (offset_arg_num == 0) {
395+
zend_value_error("Offset is out of range");
396+
} else {
397+
zend_argument_value_error(offset_arg_num, "is out of range");
398+
}
386399
return;
387400
} else {
388401
zval_ptr_dtor(&(intern->array.elements[index]));
@@ -394,29 +407,30 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
394407
static void spl_fixedarray_object_write_dimension(zend_object *object, zval *offset, zval *value) /* {{{ */
395408
{
396409
spl_fixedarray_object *intern;
397-
zval tmp;
410+
411+
/* '$array[] = value' syntax is not supported */
412+
if (!offset) {
413+
zend_throw_error(NULL, "Dynamic allocation is forbidden");
414+
return;
415+
}
398416

399417
intern = spl_fixed_array_from_obj(object);
400418

401419
if (intern->fptr_offset_set) {
402-
if (!offset) {
403-
ZVAL_NULL(&tmp);
404-
offset = &tmp;
405-
} else {
406-
SEPARATE_ARG_IF_REF(offset);
407-
}
420+
SEPARATE_ARG_IF_REF(offset);
408421
SEPARATE_ARG_IF_REF(value);
409422
zend_call_method_with_2_params(object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value);
410423
zval_ptr_dtor(value);
411424
zval_ptr_dtor(offset);
412425
return;
413426
}
414427

415-
spl_fixedarray_object_write_dimension_helper(intern, offset, value);
428+
spl_fixedarray_object_write_dimension_helper(intern, offset, value, 0);
416429
}
417430
/* }}} */
418431

419-
static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *intern, zval *offset) /* {{{ */
432+
static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *intern,
433+
zval *offset, uint32_t offset_arg_num) /* {{{ */
420434
{
421435
zend_long index;
422436

@@ -427,7 +441,11 @@ static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_o
427441
}
428442

429443
if (index < 0 || index >= intern->array.size) {
430-
zend_value_error("Index invalid or out of range");
444+
if (offset_arg_num == 0) {
445+
zend_value_error("Offset is out of range");
446+
} else {
447+
zend_argument_value_error(offset_arg_num, "is out of range");
448+
}
431449
return;
432450
} else {
433451
zval_ptr_dtor(&(intern->array.elements[index]));
@@ -449,7 +467,7 @@ static void spl_fixedarray_object_unset_dimension(zend_object *object, zval *off
449467
return;
450468
}
451469

452-
spl_fixedarray_object_unset_dimension_helper(intern, offset);
470+
spl_fixedarray_object_unset_dimension_helper(intern, offset, 0);
453471
}
454472
/* }}} */
455473

@@ -534,7 +552,7 @@ SPL_METHOD(SplFixedArray, __construct)
534552
}
535553

536554
if (size < 0) {
537-
zend_value_error("array size cannot be less than zero");
555+
zend_argument_value_error(1, "must be greater than or equal to 0");
538556
RETURN_THROWS();
539557
}
540558

@@ -645,6 +663,7 @@ SPL_METHOD(SplFixedArray, fromArray)
645663

646664
ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(data), num_index, str_index) {
647665
if (str_index != NULL || (zend_long)num_index < 0) {
666+
/* TODO Better error message? */
648667
zend_value_error("array must contain only positive integer keys");
649668
RETURN_THROWS();
650669
}
@@ -656,7 +675,7 @@ SPL_METHOD(SplFixedArray, fromArray)
656675

657676
tmp = max_index + 1;
658677
if (tmp <= 0) {
659-
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "integer overflow detected");
678+
zend_throw_error(NULL, "Integer overflow detected");
660679
RETURN_THROWS();
661680
}
662681
spl_fixedarray_init(&array, tmp);
@@ -715,7 +734,7 @@ SPL_METHOD(SplFixedArray, setSize)
715734
}
716735

717736
if (size < 0) {
718-
zend_value_error("array size cannot be less than zero");
737+
zend_argument_value_error(1, "must be greater than or equal to 0");
719738
RETURN_THROWS();
720739
}
721740

@@ -754,7 +773,7 @@ SPL_METHOD(SplFixedArray, offsetGet)
754773
}
755774

756775
intern = Z_SPLFIXEDARRAY_P(ZEND_THIS);
757-
value = spl_fixedarray_object_read_dimension_helper(intern, zindex);
776+
value = spl_fixedarray_object_read_dimension_helper(intern, zindex, 1);
758777

759778
if (value) {
760779
ZVAL_COPY_DEREF(return_value, value);
@@ -775,7 +794,7 @@ SPL_METHOD(SplFixedArray, offsetSet)
775794
}
776795

777796
intern = Z_SPLFIXEDARRAY_P(ZEND_THIS);
778-
spl_fixedarray_object_write_dimension_helper(intern, zindex, value);
797+
spl_fixedarray_object_write_dimension_helper(intern, zindex, value, 1);
779798

780799
} /* }}} */
781800

@@ -791,7 +810,7 @@ SPL_METHOD(SplFixedArray, offsetUnset)
791810
}
792811

793812
intern = Z_SPLFIXEDARRAY_P(ZEND_THIS);
794-
spl_fixedarray_object_unset_dimension_helper(intern, zindex);
813+
spl_fixedarray_object_unset_dimension_helper(intern, zindex, 1);
795814

796815
} /* }}} */
797816

@@ -844,7 +863,7 @@ static zval *spl_fixedarray_it_get_current_data(zend_object_iterator *iter) /* {
844863

845864
ZVAL_LONG(&zindex, object->current);
846865

847-
data = spl_fixedarray_object_read_dimension_helper(object, &zindex);
866+
data = spl_fixedarray_object_read_dimension_helper(object, &zindex, 0);
848867

849868
if (data == NULL) {
850869
data = &EG(uninitialized_zval);
@@ -948,7 +967,7 @@ SPL_METHOD(SplFixedArray, current)
948967

949968
ZVAL_LONG(&zindex, intern->current);
950969

951-
value = spl_fixedarray_object_read_dimension_helper(intern, &zindex);
970+
value = spl_fixedarray_object_read_dimension_helper(intern, &zindex, 0);
952971

953972
if (value) {
954973
ZVAL_COPY_DEREF(return_value, value);
@@ -974,7 +993,7 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob
974993
spl_fixedarray_it *iterator;
975994

976995
if (by_ref) {
977-
zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0);
996+
zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
978997
return NULL;
979998
}
980999

ext/spl/tests/SplArray_fromArray.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ $splArray = new SplFixedArray();
99

1010
try {
1111
$splArray->fromArray($array);
12-
} catch (Exception $e) {
12+
} catch (Error $e) {
1313
echo $e->getMessage();
1414
}
1515
?>
1616
--EXPECT--
17-
integer overflow detected
17+
Integer overflow detected

ext/spl/tests/SplFixedArray_setSize_param_null.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PHPNW Testfest 2009 - Adrian Hardy
77
$fixed_array = new SplFixedArray(2);
88
$fixed_array->setSize(null);
99
var_dump($fixed_array);
10+
1011
?>
1112
--EXPECT--
1213
object(SplFixedArray)#1 (0) {

ext/spl/tests/bug53362.phpt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,24 @@ class obj extends SplFixedArray{
1111

1212
$obj = new obj;
1313

14-
$obj[]=2;
15-
$obj[]=2;
16-
$obj[]=2;
14+
try {
15+
$obj[]=2;
16+
} catch (\Error $e) {
17+
echo $e->getMessage() . \PHP_EOL;
18+
}
19+
try {
20+
$obj[]=2;
21+
} catch (\Error $e) {
22+
echo $e->getMessage() . \PHP_EOL;
23+
}
24+
try {
25+
$obj[]=2;
26+
} catch (\Error $e) {
27+
echo $e->getMessage() . \PHP_EOL;
28+
}
1729

1830
?>
1931
--EXPECT--
20-
NULL
21-
NULL
22-
NULL
32+
Dynamic allocation is forbidden
33+
Dynamic allocation is forbidden
34+
Dynamic allocation is forbidden

ext/spl/tests/bug64106.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,4 @@ $array[][1] = 10;
1212

1313
?>
1414
--EXPECTF--
15-
NULL
16-
1715
Notice: Indirect modification of overloaded element of MyFixedArray has no effect in %s on line %d

ext/spl/tests/fixedarray_001.phpt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ try {
1919
} catch (\ValueError $e) {
2020
echo $e->getMessage() . PHP_EOL;
2121
}
22-
2322
$a->setSize(10);
2423

2524

@@ -46,9 +45,9 @@ $a[0] = "valueNew";
4645
var_dump($b[0]);
4746
?>
4847
--EXPECT--
49-
Index invalid or out of range
50-
Index invalid or out of range
51-
Index invalid or out of range
48+
Offset is out of range
49+
Offset is out of range
50+
Offset is out of range
5251
string(6) "value0"
5352
string(6) "value2"
5453
string(6) "value3"

ext/spl/tests/fixedarray_002.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ var_dump(count($a), $a->getSize(), count($a) == $a->getSize());
7070
?>
7171
--EXPECT--
7272
A::offsetSet
73-
Index invalid or out of range
73+
SplFixedArray::offsetSet(): Argument #1 ($index) is out of range
7474
A::offsetGet
75-
Index invalid or out of range
75+
SplFixedArray::offsetGet(): Argument #1 ($index) must be numeric
7676
A::offsetUnset
77-
Index invalid or out of range
77+
SplFixedArray::offsetUnset(): Argument #1 ($index) is out of range
7878
A::offsetSet
7979
A::offsetSet
8080
A::offsetSet

ext/spl/tests/fixedarray_004.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ $a = new SplFixedArray(10);
77

88
try {
99
$a[] = 1;
10-
} catch (\ValueError $e) {
10+
} catch (\Error $e) {
1111
echo $e->getMessage() . PHP_EOL;
1212
}
1313

1414
?>
1515
--EXPECT--
16-
Index invalid or out of range
16+
Dynamic allocation is forbidden

ext/spl/tests/fixedarray_006.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ try {
1010
for ($i = 0; $i < 100; $i++) {
1111
$a[] = new stdClass;
1212
}
13-
} catch (\ValueError $e) {
13+
} catch (\Error $e) {
1414
echo $e->getMessage(), "\n";
1515
}
1616

1717
?>
1818
--EXPECT--
19-
Index invalid or out of range
19+
Dynamic allocation is forbidden

0 commit comments

Comments
 (0)