]> granicus.if.org Git - php/commitdiff
fix bug #46381 (wrong $this passed to internal methods causes segfault)
authorAntony Dovgal <tony2001@php.net>
Fri, 24 Oct 2008 13:55:37 +0000 (13:55 +0000)
committerAntony Dovgal <tony2001@php.net>
Fri, 24 Oct 2008 13:55:37 +0000 (13:55 +0000)
Zend/tests/bug46381.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug46381.phpt b/Zend/tests/bug46381.phpt
new file mode 100644 (file)
index 0000000..7d12a14
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+Bug #46381 (wrong $this passed to internal methods causes segfault)
+--SKIPIF--
+<?php if (!extension_loaded("spl")) die("skip SPL is no available"); ?>
+--FILE--
+<?php
+
+class test {
+       public function test() {
+               return ArrayIterator::current();
+       }
+}
+$test = new test();
+$test->test();
+
+echo "Done\n";
+?>
+--EXPECTF--    
+Done
index 4fa0941b8ac9842e9b11fc08762022adb44bc609..f5abbca325b1866c4bdda381cff36b0b465835c7 100644 (file)
@@ -1825,7 +1825,17 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, ANY, CONST|TMP|VAR|UNUSED|CV)
                    !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))) {
index b48dfcc45c0faf6a24f373c4a8e4d5fb75d4596f..fe5f3d3df733bb60714d359b06ddab5e0a227991 100644 (file)
@@ -710,7 +710,17 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                    !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))) {
@@ -911,7 +921,17 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
                    !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))) {
@@ -1072,7 +1092,17 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                    !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))) {
@@ -1232,7 +1262,17 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
                    !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))) {
@@ -1325,7 +1365,17 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                    !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))) {