From: Dmitry Stogov Date: Thu, 18 Feb 2016 20:14:46 +0000 (+0300) Subject: Better fix for bug #71622 (Strings used in pass-as-reference cannot be used to invoke... X-Git-Tag: php-7.0.5RC1~91 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=25fbb06e2dde2ec8d15d90aee8eb08df63f346d9;p=php Better fix for bug #71622 (Strings used in pass-as-reference cannot be used to invoke C::$callable()) --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ed7e180818..5984b9d9c7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3052,19 +3052,23 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE != IS_CONST) { - if (OP2_TYPE & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); - FREE_OP2(); - HANDLE_EXCEPTION(); + zend_throw_error(NULL, "Function name must be a string"); + FREE_OP2(); + HANDLE_EXCEPTION(); + } while (0); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 78cf48fa6c..36bcd9452b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5646,19 +5646,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C function_name = EX_CONSTANT(opline->op2); if (IS_CONST != IS_CONST) { - if (IS_CONST & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -7630,19 +7634,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C function_name = NULL; if (IS_UNUSED != IS_CONST) { - if (IS_UNUSED & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + do { + if (IS_UNUSED & (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; + } + } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -9376,19 +9384,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); if (IS_CV != IS_CONST) { - if (IS_CV & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -11187,19 +11199,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); + zend_throw_error(NULL, "Function name must be a string"); + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } while (0); } } @@ -17527,19 +17543,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V function_name = EX_CONSTANT(opline->op2); if (IS_CONST != IS_CONST) { - if (IS_CONST & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -19158,19 +19178,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V function_name = NULL; if (IS_UNUSED != IS_CONST) { - if (IS_UNUSED & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + do { + if (IS_UNUSED & (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; + } + } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -20782,19 +20806,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); if (IS_CV != IS_CONST) { - if (IS_CV & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); + zend_throw_error(NULL, "Function name must be a string"); - HANDLE_EXCEPTION(); + HANDLE_EXCEPTION(); + } while (0); } } @@ -22355,19 +22383,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + 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; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - zend_throw_error(NULL, "Function name must be a string"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); + zend_throw_error(NULL, "Function name must be a string"); + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } while (0); } }