felipe                                   Fri, 11 Jun 2010 23:20:13 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=300392

Log:
- Fixed bug #52060 (Memory leak when passing a closure to method_exists())

Bug: http://bugs.php.net/52060 (Assigned) Memory leak when passing a closure to 
method_exists()
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug52060.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c
    A   php/php-src/trunk/Zend/tests/bug52060.phpt
    U   php/php-src/trunk/Zend/zend_builtin_functions.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-06-11 23:17:16 UTC (rev 300391)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-06-11 23:20:13 UTC (rev 300392)
@@ -71,6 +71,8 @@
   requests (Fixes CVE-2010-0397, bug #51288). (Raphael Geissert)
 - Fixed 64-bit integer overflow in mhash_keygen_s2k(). (Clément LECIGNE, Stas)

+- Fixed bug #52060 (Memory leak when passing a closure to method_exists()).
+  (Felipe)
 - Fixed bug #52019 (make lcov doesn't support TESTS variable anymore). 
(Patrick)
 - Fixed bug #52010 (open_basedir restrictions mismatch on vacuum command).
   (Ilia)

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug52060.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug52060.phpt                       
        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug52060.phpt       2010-06-11 
23:20:13 UTC (rev 300392)
@@ -0,0 +1,12 @@
+--TEST--
+Bug #52060 (Memory leak when passing a closure to method_exists())
+--FILE--
+<?php
+
+$closure = function($a) { echo $a; };
+
+var_dump(method_exists($closure, '__invoke')); // true
+
+?>
+--EXPECT--
+bool(true)


Property changes on: php/php-src/branches/PHP_5_3/Zend/tests/bug52060.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c  2010-06-11 
23:17:16 UTC (rev 300391)
+++ php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c  2010-06-11 
23:20:13 UTC (rev 300392)
@@ -26,6 +26,7 @@
 #include "zend_ini.h"
 #include "zend_exceptions.h"
 #include "zend_extensions.h"
+#include "zend_closures.h"

 #undef ZEND_TEST_EXCEPTIONS

@@ -1098,22 +1099,29 @@
                RETURN_TRUE;
        } else {
                union _zend_function *func = NULL;
-               efree(lcname);

                if (Z_TYPE_P(klass) == IS_OBJECT
                && Z_OBJ_HT_P(klass)->get_method != NULL
                && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, 
method_len TSRMLS_CC)) != NULL
                ) {
                        if (func->type == ZEND_INTERNAL_FUNCTION
-                       && ((zend_internal_function*)func)->handler == 
zend_std_call_user_call
+                       && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) 
!= 0
                        ) {
+                               /* Returns true to the fake Closure's __invoke 
*/
+                               RETVAL_BOOL((func->common.scope == 
zend_ce_closure
+                                       && (method_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+                                       && memcmp(lcname, 
ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
+
+                               efree(lcname);
                                
efree(((zend_internal_function*)func)->function_name);
                                efree(func);
-                               RETURN_FALSE;
+                               return;
                        }
+                       efree(lcname);
                        RETURN_TRUE;
                }
        }
+       efree(lcname);
        RETURN_FALSE;
 }
 /* }}} */

Added: php/php-src/trunk/Zend/tests/bug52060.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/bug52060.phpt                          (rev 0)
+++ php/php-src/trunk/Zend/tests/bug52060.phpt  2010-06-11 23:20:13 UTC (rev 
300392)
@@ -0,0 +1,12 @@
+--TEST--
+Bug #52060 (Memory leak when passing a closure to method_exists())
+--FILE--
+<?php
+
+$closure = function($a) { echo $a; };
+
+var_dump(method_exists($closure, '__invoke')); // true
+
+?>
+--EXPECT--
+bool(true)


Property changes on: php/php-src/trunk/Zend/tests/bug52060.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: php/php-src/trunk/Zend/zend_builtin_functions.c
===================================================================
--- php/php-src/trunk/Zend/zend_builtin_functions.c     2010-06-11 23:17:16 UTC 
(rev 300391)
+++ php/php-src/trunk/Zend/zend_builtin_functions.c     2010-06-11 23:20:13 UTC 
(rev 300392)
@@ -26,6 +26,7 @@
 #include "zend_ini.h"
 #include "zend_exceptions.h"
 #include "zend_extensions.h"
+#include "zend_closures.h"

 #undef ZEND_TEST_EXCEPTIONS

@@ -1104,22 +1105,29 @@
                RETURN_TRUE;
        } else {
                union _zend_function *func = NULL;
-               efree(lcname);

                if (Z_TYPE_P(klass) == IS_OBJECT
                && Z_OBJ_HT_P(klass)->get_method != NULL
                && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, 
method_len, NULL TSRMLS_CC)) != NULL
                ) {
                        if (func->type == ZEND_INTERNAL_FUNCTION
-                       && ((zend_internal_function*)func)->handler == 
zend_std_call_user_call
+                       && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) 
!= 0
                        ) {
+                               /* Returns true to the fake Closure's __invoke 
*/
+                               RETVAL_BOOL((func->common.scope == 
zend_ce_closure
+                                       && (method_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+                                       && memcmp(lcname, 
ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
+
+                               efree(lcname);
                                
efree(((zend_internal_function*)func)->function_name);
                                efree(func);
-                               RETURN_FALSE;
+                               return;
                        }
+                       efree(lcname);
                        RETURN_TRUE;
                }
        }
+       efree(lcname);
        RETURN_FALSE;
 }
 /* }}} */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to