From dc546bdc4d8182f92c6113dcc9f515843708036c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 5 May 2015 18:36:06 +0200 Subject: [PATCH] Throw exception from FETCH_CLASS_NAME Instead of empty strings. This does not affect the existing case of __CLASS__ in traits as a scope will always exists in that case. --- Zend/zend_vm_def.h | 46 +++++++++++++++++++++++++----------------- Zend/zend_vm_execute.h | 46 +++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7d449f40c8..089987817a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7841,27 +7841,35 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY) ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY) { + uint32_t fetch_type; USE_OPLINE - if (EG(scope) && EG(scope)->name) { - switch (opline->extended_value) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (EG(scope)->parent) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name); - } else { - ZVAL_EMPTY_STRING(EX_VAR(opline->result.var)); - } - break; - case ZEND_FETCH_CLASS_STATIC: - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } else { - ZVAL_EMPTY_STRING(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + fetch_type = opline->extended_value; + + if (UNEXPECTED(EG(scope) == NULL)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot use \"%s\" when no class scope is active", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + HANDLE_EXCEPTION(); + } + + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(EG(scope)->parent == NULL)) { + zend_error(E_EXCEPTION | E_ERROR, + "Cannot use \"parent\" when current class scope has no parent"); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() } ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2e2f0209bf..3a61b5702f 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1790,27 +1790,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + uint32_t fetch_type; USE_OPLINE - if (EG(scope) && EG(scope)->name) { - switch (opline->extended_value) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (EG(scope)->parent) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name); - } else { - ZVAL_EMPTY_STRING(EX_VAR(opline->result.var)); - } - break; - case ZEND_FETCH_CLASS_STATIC: - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } else { - ZVAL_EMPTY_STRING(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + fetch_type = opline->extended_value; + + if (UNEXPECTED(EG(scope) == NULL)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot use \"%s\" when no class scope is active", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + HANDLE_EXCEPTION(); + } + + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(EG(scope)->parent == NULL)) { + zend_error(E_EXCEPTION | E_ERROR, + "Cannot use \"parent\" when current class scope has no parent"); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() } ZEND_VM_NEXT_OPCODE(); } -- 2.40.0