]> granicus.if.org Git - php/commitdiff
Throw exception from FETCH_CLASS_NAME
authorNikita Popov <nikic@php.net>
Tue, 5 May 2015 16:36:06 +0000 (18:36 +0200)
committerNikita Popov <nikic@php.net>
Tue, 5 May 2015 19:14:03 +0000 (21:14 +0200)
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
Zend/zend_vm_execute.h

index 7d449f40c8f78c83ea77fa3795ae1f1e176c4fad..089987817ac1bcea57483472cdc0df69a4521af4 100644 (file)
@@ -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();
 }
index 2e2f0209bf86eb52e79682440558047ae33005ce..3a61b5702f29acc18f335dd7ce89305f6f1067c3 100644 (file)
@@ -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();
 }