From: Nikita Popov Date: Wed, 8 Jun 2016 13:33:11 +0000 (+0200) Subject: Followup for bug #53432 X-Git-Tag: php-7.1.0alpha3~42^2~43 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=766ad0d97058610280ef6e9bb431fcaca4b6cb53;p=php Followup for bug #53432 Assign-ops and nested accesses now get the same treatment. --- diff --git a/Zend/tests/bug53432.phpt b/Zend/tests/bug53432.phpt index f3e9159ab0..83df599313 100644 --- a/Zend/tests/bug53432.phpt +++ b/Zend/tests/bug53432.phpt @@ -27,6 +27,22 @@ try { } var_dump($str); +$str = ''; +try { + var_dump($str[0] += 1); +} catch (Error $e) { + echo "Error: {$e->getMessage()}\n"; +} +var_dump($str); + +$str = ''; +try { + var_dump($str[0][0] = 'a'); +} catch (Error $e) { + echo "Error: {$e->getMessage()}\n"; +} +var_dump($str); + ?> --EXPECTF-- string(1) "a" @@ -43,3 +59,7 @@ string(1) "a" string(1) "a" Error: [] operator not supported for strings string(0) "" +Error: Cannot use assign-op operators with string offsets +string(0) "" +Error: Cannot use string offset as an array +string(0) "" diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 8d97845bad..683f674d96 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1710,15 +1710,7 @@ fetch_from_array: goto try_array; } } - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto fetch_from_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (dim == NULL) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -1778,7 +1770,9 @@ convert_to_array: } if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (type != BP_VAR_UNSET) { - goto convert_to_array; + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto fetch_from_array; } else { /* for read-mode only */ ZVAL_NULL(result); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index bcc8fe4ed6..abd75db36d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -819,7 +819,10 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - ZEND_VM_C_GOTO(assign_dim_op_convert_to_array); +ZEND_VM_C_LABEL(assign_dim_op_convert_to_array): + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZEND_VM_C_GOTO(assign_dim_op_new_array); } } @@ -829,15 +832,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (OP1_TYPE != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -ZEND_VM_C_LABEL(assign_dim_op_convert_to_array): - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - ZEND_VM_C_GOTO(assign_dim_op_new_array); - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (OP2_TYPE == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cfac4e7e54..948d98cc4d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -17150,7 +17150,10 @@ assign_dim_op_new_array: } } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -17160,15 +17163,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_VAR != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -20640,7 +20635,10 @@ assign_dim_op_new_array: } } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -20650,15 +20648,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_VAR != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -22008,7 +21998,10 @@ assign_dim_op_new_array: } } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -22018,15 +22011,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_VAR != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -25023,7 +25008,10 @@ assign_dim_op_new_array: } } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -25033,15 +25021,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_VAR != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -27969,7 +27949,10 @@ assign_dim_op_new_array: } } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -27979,15 +27962,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_UNUSED != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -30799,7 +30774,10 @@ assign_dim_op_new_array: } } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -30809,15 +30787,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_UNUSED != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -31584,7 +31554,10 @@ assign_dim_op_new_array: } } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -31594,15 +31567,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_UNUSED != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -34082,7 +34047,10 @@ assign_dim_op_new_array: } } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -34092,15 +34060,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_UNUSED != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -38842,7 +38802,10 @@ assign_dim_op_new_array: } } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -38852,15 +38815,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_CV != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -43521,7 +43476,10 @@ assign_dim_op_new_array: } } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -43531,15 +43489,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_CV != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -45882,7 +45832,10 @@ assign_dim_op_new_array: } } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -45892,15 +45845,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_CV != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -49970,7 +49915,10 @@ assign_dim_op_new_array: } } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); - goto assign_dim_op_convert_to_array; +assign_dim_op_convert_to_array: + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto assign_dim_op_new_array; } } @@ -49980,15 +49928,7 @@ assign_dim_op_new_array: value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op); } else if (IS_CV != IS_UNUSED) { - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else {