This change was discussed a while ago in the "negative string
offsets" thread.
This commit is contained in:
Nikita Popov 2016-02-14 16:49:36 +01:00
parent 33aba29768
commit 945a83103d
5 changed files with 420 additions and 594 deletions

2
NEWS
View File

@ -10,6 +10,8 @@ PHP NEWS
. Change statement and fcall extension handlers to accept frame. (Joe)
. Implemented safe execution timeout handling, that prevents random crashes
after "Maximum execution time exceeded" error. (Dmitry)
. Fixed bug #53432 (Assignment via string index access on an empty string
converts to array). (Nikita)
. Fixed bug #62210 (Exceptions can leak temporary variables). (Dmitry, Bob)
. Fixed bug #62814 (It is possible to stiffen child class members visibility).
(Nikita)

45
Zend/tests/bug53432.phpt Normal file
View File

@ -0,0 +1,45 @@
--TEST--
Bug #53432: Assignment via string index access on an empty string converts to array
--FILE--
<?php
$str = '';
var_dump($str[0] = 'a');
var_dump($str);
$str = '';
var_dump($str[5] = 'a');
var_dump($str);
$str = '';
var_dump($str[-1] = 'a');
var_dump($str);
$str = '';
var_dump($str['foo'] = 'a');
var_dump($str);
$str = '';
try {
var_dump($str[] = 'a');
} catch (Error $e) {
echo "Error: {$e->getMessage()}\n";
}
var_dump($str);
?>
--EXPECTF--
string(1) "a"
string(1) "a"
string(1) "a"
string(6) " a"
Warning: Illegal string offset: -1 in %s on line %d
NULL
string(0) ""
Warning: Illegal string offset 'foo' in %s on line %d
string(1) "a"
string(1) "a"
Error: [] operator not supported for strings
string(0) ""

View File

@ -12,7 +12,7 @@ foreach ($testvalues as $testvalue) {
}
echo "\n*** Indexing - Testing reference assignment with key ***\n";
$testvalues=array(null, 0, 1, true, false,'',0.1,array());
$testvalues=array(null, 0, 1, true, false,0.1,array());
foreach ($testvalues as $testvalue) {
$testvalue['foo']=&$array;
@ -20,7 +20,7 @@ foreach ($testvalues as $testvalue) {
}
echo "*** Indexing - Testing value assignment no key ***\n";
$array=array(1);
$testvalues=array(null, 0, 1, true, false,'',0.1,array());
$testvalues=array(null, 0, 1, true, false,0.1,array());
foreach ($testvalues as $testvalue) {
$testvalue[]=$array;
@ -28,7 +28,7 @@ foreach ($testvalues as $testvalue) {
}
echo "\n*** Indexing - Testing reference assignment no key ***\n";
$testvalues=array(null, 0, 1, true, false,'',0.1,array());
$testvalues=array(null, 0, 1, true, false,0.1,array());
foreach ($testvalues as $testvalue) {
$testvalue[]=&$array;
@ -63,13 +63,11 @@ array(1) {
int(1)
}
}
array(1) {
["foo"]=>
array(1) {
[0]=>
int(1)
}
}
Warning: Illegal string offset 'foo' in %s on line %d
Notice: Array to string conversion in %s on line %d
string(1) "A"
Warning: Illegal string offset 'foo' in %s on line %d
@ -110,13 +108,6 @@ array(1) {
int(1)
}
}
array(1) {
["foo"]=>
&array(1) {
[0]=>
int(1)
}
}
Warning: Cannot use a scalar value as an array in %s on line %d
float(0.1)
@ -151,13 +142,6 @@ array(1) {
int(1)
}
}
array(1) {
[0]=>
array(1) {
[0]=>
int(1)
}
}
Warning: Cannot use a scalar value as an array in %s on line %d
float(0.1)
@ -193,13 +177,6 @@ array(1) {
int(1)
}
}
array(1) {
[0]=>
&array(1) {
[0]=>
int(1)
}
}
Warning: Cannot use a scalar value as an array in %s on line %d
float(0.1)
@ -211,4 +188,4 @@ array(1) {
}
}
Done
Done

View File

@ -2380,27 +2380,21 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
FREE_OP_DATA();
}
} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
if (OP2_TYPE == IS_UNUSED) {
zend_throw_error(NULL, "[] operator not supported for strings");
FREE_UNFETCHED_OP_DATA();
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
} else {
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
FREE_OP_DATA();
}
if (OP2_TYPE == IS_UNUSED) {
zend_throw_error(NULL, "[] operator not supported for strings");
FREE_UNFETCHED_OP_DATA();
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
} else {
zval_ptr_dtor_nogc(object_ptr);
ZEND_VM_C_LABEL(assign_dim_convert_to_array):
ZVAL_NEW_ARR(object_ptr);
zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
ZEND_VM_C_GOTO(try_assign_dim_array);
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
FREE_OP_DATA();
}
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
ZEND_VM_C_GOTO(assign_dim_convert_to_array);
ZVAL_NEW_ARR(object_ptr);
zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
ZEND_VM_C_GOTO(try_assign_dim_array);
} else {
if (OP1_TYPE != IS_VAR || UNEXPECTED(!Z_ISERROR_P(object_ptr))) {
zend_error(E_WARNING, "Cannot use a scalar value as an array");

File diff suppressed because it is too large Load Diff