Skip to content

Commit 67d7d03

Browse files
committed
Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all undefined variables)
The get_zval_ptr_ptr of spl_array handler should act as same as the vm's
1 parent 5dc2cef commit 67d7d03

File tree

3 files changed

+90
-32
lines changed

3 files changed

+90
-32
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ PHP NEWS
4545
. Fixed bug (segfault due to retval is not initialized). (Laruence)
4646

4747
- SPL:
48+
. Bug #62987 (Assigning to ArrayObject[null][something] overrides all
49+
undefined variables). (Laruence)
4850
. Fixed bug #62904 (Crash when cloning an object which inherits SplFixedArray)
4951
(Laruence)
5052
. Fixed bug #62616 (ArrayIterator::count() from IteratorIterator instance

ext/spl/spl_array.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -312,38 +312,41 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
312312
long index;
313313
HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
314314

315-
/* We cannot get the pointer pointer so we don't allow it here for now
316-
if (check_inherited && intern->fptr_offset_get) {
317-
return zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", NULL, offset);
318-
}*/
319-
320315
if (!offset) {
321316
return &EG(uninitialized_zval_ptr);
322317
}
323318

324319
if ((type == BP_VAR_W || type == BP_VAR_RW) && (ht->nApplyCount > 0)) {
325320
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
326-
return &EG(uninitialized_zval_ptr);;
321+
return &EG(error_zval_ptr);;
327322
}
328323

329324
switch(Z_TYPE_P(offset)) {
325+
case IS_NULL:
326+
Z_STRVAL_P(offset) = "";
327+
Z_STRLEN_P(offset) = 0;
330328
case IS_STRING:
331329
if (zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval) == FAILURE) {
332-
if (type == BP_VAR_W || type == BP_VAR_RW) {
333-
zval *value;
334-
ALLOC_INIT_ZVAL(value);
335-
zend_symtable_update(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void**)&value, sizeof(void*), NULL);
336-
zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval);
337-
return retval;
338-
} else {
339-
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(offset));
340-
return &EG(uninitialized_zval_ptr);
330+
switch (type) {
331+
case BP_VAR_R:
332+
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(offset));
333+
case BP_VAR_UNSET:
334+
case BP_VAR_IS:
335+
retval = &EG(uninitialized_zval_ptr);
336+
break;
337+
case BP_VAR_RW:
338+
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
339+
case BP_VAR_W: {
340+
zval *value;
341+
ALLOC_INIT_ZVAL(value);
342+
zend_symtable_update(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void**)&value, sizeof(void*), (void **)&retval);
343+
}
341344
}
342-
} else {
343-
return retval;
344345
}
345-
case IS_DOUBLE:
346+
return retval;
346347
case IS_RESOURCE:
348+
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(offset), Z_LVAL_P(offset));
349+
case IS_DOUBLE:
347350
case IS_BOOL:
348351
case IS_LONG:
349352
if (offset->type == IS_DOUBLE) {
@@ -352,23 +355,27 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
352355
index = Z_LVAL_P(offset);
353356
}
354357
if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {
355-
if (type == BP_VAR_W || type == BP_VAR_RW) {
356-
zval *value;
357-
ALLOC_INIT_ZVAL(value);
358-
zend_hash_index_update(ht, index, (void**)&value, sizeof(void*), NULL);
359-
zend_hash_index_find(ht, index, (void **) &retval);
360-
return retval;
361-
} else {
362-
zend_error(E_NOTICE, "Undefined offset: %ld", index);
363-
return &EG(uninitialized_zval_ptr);
358+
switch (type) {
359+
case BP_VAR_R:
360+
zend_error(E_NOTICE, "Undefined offset: %ld", index);
361+
case BP_VAR_UNSET:
362+
case BP_VAR_IS:
363+
retval = &EG(uninitialized_zval_ptr);
364+
break;
365+
case BP_VAR_RW:
366+
zend_error(E_NOTICE, "Undefined offset: %ld", index);
367+
case BP_VAR_W: {
368+
zval *value;
369+
ALLOC_INIT_ZVAL(value);
370+
zend_hash_index_update(ht, index, (void**)&value, sizeof(void*), (void **)&retval);
371+
}
364372
}
365-
} else {
366-
return retval;
367373
}
368-
break;
374+
return retval;
369375
default:
370376
zend_error(E_WARNING, "Illegal offset type");
371-
return &EG(uninitialized_zval_ptr);
377+
return (type == BP_VAR_W || type == BP_VAR_RW) ?
378+
&EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
372379
}
373380
} /* }}} */
374381

@@ -664,7 +671,6 @@ SPL_METHOD(Array, offsetSet)
664671
spl_array_write_dimension_ex(0, getThis(), index, value TSRMLS_CC);
665672
} /* }}} */
666673

667-
668674
void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC) /* {{{ */
669675
{
670676
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);

ext/spl/tests/bug62978.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
Bug #62987 (Assigning to ArrayObject[null][something] overrides all undefined variables)
3+
--FILE--
4+
<?php
5+
$a = new ArrayObject();
6+
7+
$b = array();
8+
9+
$a[null]['hurr'] = 'durr';
10+
11+
var_dump($a['epic_magic']);
12+
var_dump($b['epic_magic']);
13+
var_dump($c['epic_magic']); // Undefined var!!
14+
15+
$d = array();
16+
var_dump($a['epic_magic']); // more magic!
17+
var_dump($d['epic_magic']);
18+
19+
$e = 'srsly?';
20+
var_dump($a['epic_magic']); // srsly.
21+
var_dump(isset($a['epic_magic']));
22+
23+
$fp = fopen(__FILE__, 'r');
24+
var_dump($a[$fp]);
25+
26+
fclose($fp);
27+
--EXPECTF--
28+
Notice: Undefined index: epic_magic in %sbug62978.php on line %d
29+
NULL
30+
31+
Notice: Undefined index: epic_magic in %sbug62978.php on line %d
32+
NULL
33+
34+
Notice: Undefined variable: c in %sbug62978.php on line %d
35+
NULL
36+
37+
Notice: Undefined index: epic_magic in %sbug62978.php on line %d
38+
NULL
39+
40+
Notice: Undefined index: epic_magic in %sbug62978.php on line %d
41+
NULL
42+
43+
Notice: Undefined index: epic_magic in %sbug62978.php on line %d
44+
NULL
45+
bool(false)
46+
47+
Strict Standards: Resource ID#%d used as offset, casting to integer (%d) in %sbug62978.php on line %d
48+
49+
Notice: Undefined offset: %d in %sbug62978.php on line %d
50+
NULL

0 commit comments

Comments
 (0)