]> granicus.if.org Git - php/commitdiff
Fixed bug #32429 (method_exists() always return TRUE if __call method exists)
authorDmitry Stogov <dmitry@php.net>
Tue, 26 Apr 2005 08:47:31 +0000 (08:47 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 26 Apr 2005 08:47:31 +0000 (08:47 +0000)
NEWS
Zend/tests/bug32429.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c

diff --git a/NEWS b/NEWS
index 7b69b76d6ab65c23f6c9e002811f1751caf6aa43..4cec0987a935cc45106e2327ba08ad3f6bbd71a5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -109,6 +109,8 @@ PHP                                                                        NEWS
 - Fixed ZTS destruction. (Marcus)
 - Fixed bug #32491 (File upload error - unable to create a temporary file).
   (Uwe Schindler)
+- Fixed bug #32429 (method_exists() always return TRUE if __call method
+  exists). (Dmitry)
 - Fixed bug #32109 ($_POST is not populated in multithreaded environment).
   (Moriyoshi)
 - Fixed bug #31478 (segfault with empty() / isset()). (Moriyoshi)
diff --git a/Zend/tests/bug32429.phpt b/Zend/tests/bug32429.phpt
new file mode 100644 (file)
index 0000000..db5dc7d
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #32429 (method_exists() always return TRUE if __call method exists)
+--FILE--
+<?php
+
+class TestClass {
+       public function __construct() {
+               var_dump(method_exists($this, 'test'));
+
+               if (method_exists($this, 'test')) {
+                       $this->test();
+               }
+       }
+
+       public function __call($name, $args) {
+               throw new Exception('Call to undefined method'.get_class($this).'::'.$name.'()');
+       }
+}
+
+try {
+       $test = new TestClass;
+} catch (Exception $e) {
+  exit($e->getMessage());
+}
+
+?>
+--EXPEXT--
+bool(false)
index efb4467c3846cf334ef0a579d08d8d76530af710..d5604c447b8f47ad9ab3c8490d24f7ca3526e66b 100644 (file)
@@ -880,11 +880,20 @@ ZEND_FUNCTION(method_exists)
                efree(lcname);
                RETURN_TRUE;
        } else {
+               union _zend_function *func = NULL;
                efree(lcname);
+
                if (Z_TYPE_PP(klass) == IS_OBJECT 
                && Z_OBJ_HT_PP(klass)->get_method != NULL
-               && Z_OBJ_HT_PP(klass)->get_method(klass, Z_STRVAL_PP(method_name), Z_STRLEN_PP(method_name) TSRMLS_CC) != NULL
+               && (func = Z_OBJ_HT_PP(klass)->get_method(klass, Z_STRVAL_PP(method_name), Z_STRLEN_PP(method_name) TSRMLS_CC)) != NULL
                ) {
+                       if (func->type == ZEND_INTERNAL_FUNCTION 
+                       && ((zend_internal_function*)func)->handler == zend_std_call_user_call
+                       ) {
+                               efree(((zend_internal_function*)func)->function_name);
+                               efree(func);
+                               RETURN_FALSE;
+                       }
                        RETURN_TRUE;
                }
        }