]> granicus.if.org Git - php/commitdiff
Fix segfaults when calling "ctors statically"
authorHannes Magnusson <bjori@php.net>
Mon, 11 Feb 2008 15:46:10 +0000 (15:46 +0000)
committerHannes Magnusson <bjori@php.net>
Mon, 11 Feb 2008 15:46:10 +0000 (15:46 +0000)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index a89f6d7660c2338c9b6346baec1eca96d605c1da..1ba98ea52a25ae8ebf9d219fd909ecfc43fc1424 100644 (file)
@@ -1963,8 +1963,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (OP2_TYPE != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
index d31e9cb5f60c26ac2fa9bb41e4743b53fc10f61f..d9482e304a0708f714ae30e3e3673e1531f37610 100644 (file)
@@ -148,6 +148,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                        zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
                } else {
                        /* FIXME: output identifiers properly */
+                       /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
                        zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
                }
        }
@@ -2432,13 +2433,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_CONST != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -2993,13 +3003,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_TMP_VAR != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -3449,13 +3468,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_VAR != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -3662,13 +3690,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_UNUSED != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -4086,13 +4123,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_CV != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -9931,13 +9977,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_CONST != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -11732,13 +11787,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_TMP_VAR != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -13503,13 +13567,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_VAR != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -14387,13 +14460,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_UNUSED != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {
@@ -15859,13 +15941,22 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
-               if (IS_CV != IS_UNUSED &&
-                   EG(This) &&
+               if (EG(This) &&
                    Z_OBJ_HT_P(EG(This))->get_class_entry &&
                    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
                    /* We are calling method of the other (incompatible) class,
                       but passing $this. This is done for compatibility with php-4. */
-                       zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+                       int severity;
+                       char *verb;
+                       if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+                               severity = E_STRICT;
+                               verb = "should not";
+                       } else {
+                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+                               severity = E_ERROR;
+                               verb = "cannot";
+                       }
+                       zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
                }
                if ((EX(object) = EG(This))) {