diff --git a/Zend/tests/bug69124.phpt b/Zend/tests/bug69124.phpt new file mode 100644 index 00000000000..1959332fbfd --- /dev/null +++ b/Zend/tests/bug69124.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug 69124: Method name must be as string (invalid error message when using reference to a string) +--FILE-- +{$method}(); +} + +$instance = new Foo; +$method = "bar"; + +test($instance, $method); +?> +--EXPECT-- +Success diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 31d84fc5b1f..1ee827e908a 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -90,8 +90,6 @@ ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_l ZEND_API const char* zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end); ZEND_API const char* zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end); -END_EXTERN_C() - #if SIZEOF_ZEND_LONG == 4 # define ZEND_DOUBLE_FITS_LONG(d) (!((d) > ZEND_LONG_MAX || (d) < ZEND_LONG_MIN)) #else @@ -234,7 +232,6 @@ zend_memnrstr(const char *haystack, const char *needle, size_t needle_len, char } } -BEGIN_EXTERN_C() ZEND_API int increment_function(zval *op1); ZEND_API int decrement_function(zval *op2); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6c5566c3bfb..641316b6129 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1659,14 +1659,13 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST) ZEND_VM_C_LABEL(try_fetch_list): if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zend_free_op free_op2; - zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R); + zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), EX_CONSTANT(opline->op2), OP2_TYPE, BP_VAR_R); ZVAL_COPY(EX_VAR(opline->result.var), value); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { zval *result = EX_VAR(opline->result.var); - zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, GET_OP2_ZVAL_PTR(BP_VAR_R), BP_VAR_R, result); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result); if (retval) { if (result != retval) { @@ -2336,12 +2335,19 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP2_TYPE != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (OP2_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); @@ -3198,7 +3204,7 @@ ZEND_VM_C_LABEL(fcall_end): ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED) { -#if OP1_TYPE != IS_UNUSED +#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -4443,7 +4449,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSE if (OP1_TYPE == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED +#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) } else { ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT); #endif diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5938d6c391a..ef46d6cf6db 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4427,7 +4427,6 @@ static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_H try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), EX_CONSTANT(opline->op2), IS_CONST, BP_VAR_R); ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -4855,7 +4854,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_H if (IS_CONST == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CONST != IS_UNUSED +#if 0 || (IS_CONST != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -6374,7 +6373,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER static int ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if IS_CONST != IS_UNUSED +#if 0 || (IS_CONST != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -6503,7 +6502,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_ if (IS_CONST == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CONST != IS_UNUSED +#if 0 || (IS_CONST != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -7713,7 +7712,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND if (IS_CONST == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CONST != IS_UNUSED +#if 0 || (IS_CONST != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -8818,7 +8817,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_ if (IS_CONST == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CONST != IS_UNUSED +#if 0 || (IS_CONST != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -10002,7 +10001,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_TMP_VAR != IS_UNUSED +#if 0 || (IS_TMP_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -10501,7 +10500,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O static int ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if IS_TMP_VAR != IS_UNUSED +#if 0 || (IS_TMP_VAR != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -10630,7 +10629,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HA if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_TMP_VAR != IS_UNUSED +#if 0 || (IS_TMP_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -11084,7 +11083,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_TMP_VAR != IS_UNUSED +#if 0 || (IS_TMP_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -11509,7 +11508,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HA if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_TMP_VAR != IS_UNUSED +#if 0 || (IS_TMP_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -14273,7 +14272,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_VAR != IS_UNUSED +#if 0 || (IS_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -15571,7 +15570,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z static int ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if IS_VAR != IS_UNUSED +#if 0 || (IS_VAR != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -15700,7 +15699,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_VAR != IS_UNUSED +#if 0 || (IS_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -17167,7 +17166,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_VAR != IS_UNUSED +#if 0 || (IS_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -18634,7 +18633,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_VAR != IS_UNUSED +#if 0 || (IS_VAR != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -19710,12 +19709,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O function_name = EX_CONSTANT(opline->op2); - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_obj_zval_ptr_unused(execute_data); @@ -19937,7 +19943,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ if (IS_UNUSED == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_UNUSED != IS_UNUSED +#if 0 || (IS_UNUSED != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -20901,7 +20907,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPC static int ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if IS_UNUSED != IS_UNUSED +#if 0 || (IS_UNUSED != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -20942,7 +20948,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE if (IS_UNUSED == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_UNUSED != IS_UNUSED +#if 0 || (IS_UNUSED != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -21923,12 +21929,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_obj_zval_ptr_unused(execute_data); @@ -22052,7 +22065,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN if (IS_UNUSED == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_UNUSED != IS_UNUSED +#if 0 || (IS_UNUSED != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -23320,12 +23333,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_obj_zval_ptr_unused(execute_data); @@ -23450,7 +23470,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE if (IS_UNUSED == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_UNUSED != IS_UNUSED +#if 0 || (IS_UNUSED != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -26653,7 +26673,6 @@ static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), EX_CONSTANT(opline->op2), IS_CONST, BP_VAR_R); ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -26845,12 +26864,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD function_name = EX_CONSTANT(opline->op2); - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); @@ -27077,7 +27103,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND if (IS_CV == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CV != IS_UNUSED +#if 0 || (IS_CV != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -29252,7 +29278,7 @@ assign_dim_clean: static int ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if IS_CV != IS_UNUSED +#if 0 || (IS_CV != IS_UNUSED) USE_OPLINE #endif SAVE_OPLINE(); @@ -29381,7 +29407,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN if (IS_CV == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CV != IS_UNUSED +#if 0 || (IS_CV != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -31134,12 +31160,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); @@ -31366,7 +31399,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER if (IS_CV == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CV != IS_UNUSED +#if 0 || (IS_CV != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -33137,12 +33170,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); @@ -33371,7 +33411,7 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAN if (IS_CV == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); -#if 0 || IS_CV != IS_UNUSED +#if 0 || (IS_CV != IS_UNUSED) } else { return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #endif @@ -34772,7 +34812,6 @@ static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_ try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), EX_CONSTANT(opline->op2), IS_CONST, BP_VAR_R); ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -34812,12 +34851,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O function_name = EX_CONSTANT(opline->op2); - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -36430,12 +36476,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -37093,12 +37146,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Method name must be a string"); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } while (0); } object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index cad9e8b75b7..c3b16b34783 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -438,16 +438,16 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { "/FREE_OP2_IF_VAR\(\)/", "/FREE_OP1_VAR_PTR\(\)/", "/FREE_OP2_VAR_PTR\(\)/", - "/^#ifdef\s+ZEND_VM_SPEC\s*\n/m", - "/^#ifndef\s+ZEND_VM_SPEC\s*\n/m", + "/^#(\s*)ifdef\s+ZEND_VM_SPEC\s*\n/m", + "/^#(\s*)ifndef\s+ZEND_VM_SPEC\s*\n/m", "/\!defined\(ZEND_VM_SPEC\)/m", "/defined\(ZEND_VM_SPEC\)/m", "/ZEND_VM_C_LABEL\(\s*([A-Za-z_]*)\s*\)/m", "/ZEND_VM_C_GOTO\(\s*([A-Za-z_]*)\s*\)/m", - "/^#if\s+1\s*\\|\\|.*[^\\\\]$/m", - "/^#if\s+0\s*&&.*[^\\\\]$/m", - "/^#ifdef\s+ZEND_VM_EXPORT\s*\n/m", - "/^#ifndef\s+ZEND_VM_EXPORT\s*\n/m" + "/^#(\s*)if\s+1\s*\\|\\|.*[^\\\\]$/m", + "/^#(\s*)if\s+0\s*&&.*[^\\\\]$/m", + "/^#(\s*)ifdef\s+ZEND_VM_EXPORT\s*\n/m", + "/^#(\s*)ifndef\s+ZEND_VM_EXPORT\s*\n/m" ), array( $op1_type[$op1], @@ -476,16 +476,16 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $op2_free_op_if_var[$op2], $op1_free_op_var_ptr[$op1], $op2_free_op_var_ptr[$op2], - ($op1!="ANY"||$op2!="ANY")?"#if 1\n":"#if 0\n", - ($op1!="ANY"||$op2!="ANY")?"#if 0\n":"#if 1\n", + ($op1!="ANY"||$op2!="ANY")?"#\\1if 1\n":"#\\1if 0\n", + ($op1!="ANY"||$op2!="ANY")?"#\\1if 0\n":"#\\1if 1\n", ($op1!="ANY"||$op2!="ANY")?"0":"1", ($op1!="ANY"||$op2!="ANY")?"1":"0", "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2]):""), "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2]):""), - "#if 1", - "#if 0", - $export?"#if 1\n":"#if 0\n", - $export?"#if 0\n":"#if 1\n" + "#\\1if 1", + "#\\1if 0", + $export?"#\\1if 1\n":"#\\1if 0\n", + $export?"#\\1if 0\n":"#\\1if 1\n" ), $code); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 4b6deaf6488..fbc4f85205c 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3665,9 +3665,12 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez zval *z_timezone; zval *z_timezone_type; - if ((z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type")-1)) != NULL) { - if ((z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1)) != NULL) { - if(Z_TYPE_P(z_timezone_type) != IS_LONG) { + if ((z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type") - 1)) != NULL) { + if ((z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone") - 1)) != NULL) { + if (Z_TYPE_P(z_timezone_type) != IS_LONG) { + return FAILURE; + } + if (Z_TYPE_P(z_timezone) != IS_STRING) { return FAILURE; } if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone))) { diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 6b5aa993513..7be076cb7f5 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -250,6 +250,7 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_ISSET_ISEMPTY_DIM_OBJ: case ZEND_ADD_ARRAY_ELEMENT: case ZEND_INIT_ARRAY: + case ZEND_ASSIGN_DIM: case ZEND_UNSET_DIM: case ZEND_FETCH_DIM_R: case ZEND_FETCH_DIM_W: diff --git a/ext/opcache/tests/bug69125.phpt b/ext/opcache/tests/bug69125.phpt new file mode 100644 index 00000000000..913be01b00f --- /dev/null +++ b/ext/opcache/tests/bug69125.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #69125 (Array numeric string as key) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(4) "okey" +string(4) "okey" diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 8a6ecb5817c..502ec57f423 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1221,7 +1221,11 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su new_len = result_len + subject_len - start_offset; if (new_len > alloc_len) { alloc_len = new_len; /* now we know exactly how long it is */ - result = zend_string_realloc(result, alloc_len, 0); + if (NULL != result) { + result = zend_string_realloc(result, alloc_len, 0); + } else { + result = zend_string_alloc(alloc_len, 0); + } } /* stick that last bit of string on our output */ memcpy(&result->val[result_len], piece, subject_len - start_offset); diff --git a/ext/standard/tests/mail/bug69115.phpt b/ext/standard/tests/mail/bug69115.phpt new file mode 100644 index 00000000000..b22332c0915 --- /dev/null +++ b/ext/standard/tests/mail/bug69115.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #69115 crash in mail (plus indirect pcre test) +--FILE-- + +===DONE=== +--EXPECTF-- +%A +===DONE=== diff --git a/main/main.c b/main/main.c index 35fbcb731de..f74190cf062 100644 --- a/main/main.c +++ b/main/main.c @@ -1301,6 +1301,10 @@ PHPAPI char *php_get_current_user(void) efree(pwbuf); return ""; } + if (retpwptr == NULL) { + efree(pwbuf); + return ""; + } pwd = &_pw; #else if ((pwd=getpwuid(pstat->st_uid))==NULL) { diff --git a/win32/sendmail.c b/win32/sendmail.c index fd7424dda73..9035c7d37ec 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -292,7 +292,6 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message, efree(RPath); } if (headers) { - efree(headers); efree(headers_lc); } /* 128 is safe here, the specifier in snprintf isn't longer than that */