Skip to content

Commit aa4e638

Browse files
committed
FixedArray stuff
Some conversions, some trying to wrap my brain around, maybe a bugfix also
1 parent ac44eff commit aa4e638

17 files changed

+149
-114
lines changed

ext/spl/spl_fixedarray.c

Lines changed: 61 additions & 42 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

@@ -527,14 +545,14 @@ SPL_METHOD(SplFixedArray, __construct)
527545
{
528546
zval *object = ZEND_THIS;
529547
spl_fixedarray_object *intern;
530-
zend_long size = 0;
548+
zend_long size = 1;
531549

532550
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &size) == FAILURE) {
533551
RETURN_THROWS();
534552
}
535553

536-
if (size < 0) {
537-
zend_value_error("array size cannot be less than zero");
554+
if (size <= 0) {
555+
zend_argument_value_error(1, "must be greater than 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);
@@ -714,8 +733,8 @@ SPL_METHOD(SplFixedArray, setSize)
714733
RETURN_THROWS();
715734
}
716735

717-
if (size < 0) {
718-
zend_value_error("array size cannot be less than zero");
736+
if (size <= 0) {
737+
zend_argument_value_error(1, "must be greater than 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__construct_param_null.phpt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ PHPNW Test Fest 2009 - Jordan Hatch
55
--FILE--
66
<?php
77

8-
$array = new SplFixedArray( NULL );
9-
10-
print_r( $array );
8+
try {
9+
$array = new SplFixedArray( NULL );
10+
} catch (\ValueError $e) {
11+
echo $e->getMessage() . \PHP_EOL;
12+
}
1113

1214
?>
1315
--EXPECT--
14-
SplFixedArray Object
15-
(
16-
)
16+
SplFixedArray::__construct(): Argument #1 ($size) must be greater than 0

ext/spl/tests/SplFixedArray_setSize_param_null.phpt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@ PHPNW Testfest 2009 - Adrian Hardy
55
--FILE--
66
<?php
77
$fixed_array = new SplFixedArray(2);
8-
$fixed_array->setSize(null);
8+
try {
9+
$fixed_array->setSize(null);
10+
} catch (\ValueError $e) {
11+
echo $e->getMessage() . \PHP_EOL;
12+
}
913
var_dump($fixed_array);
14+
1015
?>
1116
--EXPECT--
12-
object(SplFixedArray)#1 (0) {
17+
SplFixedArray::setSize(): Argument #1 ($size) must be greater than 0
18+
object(SplFixedArray)#1 (2) {
19+
[0]=>
20+
NULL
21+
[1]=>
22+
NULL
1323
}

ext/spl/tests/SplFixedArray_toArray_empty.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ Gabriel Caruso (carusogabriel34@gmail.com)
55
--FILE--
66
<?php var_dump((new SplFixedArray())->toArray()); ?>
77
--EXPECT--
8-
array(0) {
8+
array(1) {
9+
[0]=>
10+
NULL
911
}

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

0 commit comments

Comments
 (0)