cseiler Tue Jun 30 17:14:38 2009 UTC
Added files: (Branch: PHP_5_3)
/php-src/ext/spl/tests spl_autoload_013.phpt spl_autoload_014.phpt
Modified files:
/php-src NEWS
/php-src/ext/spl php_spl.c
/php-src/ext/spl/tests spl_autoload_bug48541.phpt
Log:
MFH: spl_autoload_unregister/spl_autoload_functions and closures
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.659&r2=1.2027.2.547.2.965.2.660&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.965.2.659
php-src/NEWS:1.2027.2.547.2.965.2.660
--- php-src/NEWS:1.2027.2.547.2.965.2.659 Tue Jun 30 16:17:30 2009
+++ php-src/NEWS Tue Jun 30 17:14:37 2009
@@ -2,6 +2,9 @@
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2009, PHP 5.3.1
+- Fixed spl_autoload_unregister/spl_autoad_functions wrt. Closures and
+ Functors. (Christian Seiler)
+
- Fixed bug #48681 (openssl signature verification for tar archives broken).
(Greg)
- Fixed bug #47351 (Memory leak in DateTime). (Derick, Tobias John)
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/php_spl.c?r1=1.52.2.28.2.17.2.38&r2=1.52.2.28.2.17.2.39&diff_format=u
Index: php-src/ext/spl/php_spl.c
diff -u php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.38
php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.39
--- php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.38 Sat Jun 13 17:30:50 2009
+++ php-src/ext/spl/php_spl.c Tue Jun 30 17:14:37 2009
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_spl.c,v 1.52.2.28.2.17.2.38 2009/06/13 17:30:50 cellog Exp $ */
+/* $Id: php_spl.c,v 1.52.2.28.2.17.2.39 2009/06/30 17:14:37 cseiler Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -509,10 +509,10 @@
alfi.closure = zcallable;
Z_ADDREF_P(zcallable);
- lc_name = erealloc(lc_name, func_name_len + 2 +
sizeof(zcallable->value.obj.handle));
- memcpy(lc_name + func_name_len,
&(zcallable->value.obj.handle),
- sizeof(zcallable->value.obj.handle));
- func_name_len += sizeof(zcallable->value.obj.handle);
+ lc_name = erealloc(lc_name, func_name_len + 2 +
sizeof(zend_object_handle));
+ memcpy(lc_name + func_name_len,
&Z_OBJ_HANDLE_P(zcallable),
+ sizeof(zend_object_handle));
+ func_name_len += sizeof(zend_object_handle);
lc_name[func_name_len] = '\0';
}
@@ -579,6 +579,7 @@
{
char *func_name, *error = NULL;
int func_name_len;
+ char *lc_name = NULL;
zval *zcallable;
int success = FAILURE;
zend_function *spl_func_ptr;
@@ -604,10 +605,20 @@
efree(error);
}
- zend_str_tolower(func_name, func_name_len);
+ lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
+ zend_str_tolower_copy(lc_name, func_name, func_name_len);
+ efree(func_name);
+
+ if (Z_TYPE_P(zcallable) == IS_OBJECT) {
+ lc_name = erealloc(lc_name, func_name_len + 2 +
sizeof(zend_object_handle));
+ memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable),
+ sizeof(zend_object_handle));
+ func_name_len += sizeof(zend_object_handle);
+ lc_name[func_name_len] = '\0';
+ }
if (SPL_G(autoload_functions)) {
- if (func_name_len == sizeof("spl_autoload_call")-1 &&
!strcmp(func_name, "spl_autoload_call")) {
+ if (func_name_len == sizeof("spl_autoload_call")-1 &&
!strcmp(lc_name, "spl_autoload_call")) {
/* remove all */
zend_hash_destroy(SPL_G(autoload_functions));
FREE_HASHTABLE(SPL_G(autoload_functions));
@@ -616,16 +627,16 @@
success = SUCCESS;
} else {
/* remove specific */
- success = zend_hash_del(SPL_G(autoload_functions),
func_name, func_name_len+1);
+ success = zend_hash_del(SPL_G(autoload_functions),
lc_name, func_name_len+1);
if (success != SUCCESS && obj_ptr) {
- func_name = erealloc(func_name, func_name_len +
1 + sizeof(zend_object_handle));
- memcpy(func_name + func_name_len,
&Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
+ lc_name = erealloc(lc_name, func_name_len + 2 +
sizeof(zend_object_handle));
+ memcpy(lc_name + func_name_len,
&Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
func_name_len += sizeof(zend_object_handle);
- func_name[func_name_len] = '\0';
- success =
zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1);
+ lc_name[func_name_len] = '\0';
+ success =
zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1);
}
}
- } else if (func_name_len == sizeof("spl_autoload")-1 &&
!strcmp(func_name, "spl_autoload")) {
+ } else if (func_name_len == sizeof("spl_autoload")-1 &&
!strcmp(lc_name, "spl_autoload")) {
/* register single spl_autoload() */
zend_hash_find(EG(function_table), "spl_autoload",
sizeof("spl_autoload"), (void **) &spl_func_ptr);
@@ -635,7 +646,7 @@
}
}
- efree(func_name);
+ efree(lc_name);
RETURN_BOOL(success == SUCCESS);
} /* }}} */
@@ -663,7 +674,10 @@
zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions),
&function_pos);
while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions),
&function_pos) == SUCCESS) {
zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi,
&function_pos);
- if (alfi->func_ptr->common.scope) {
+ if (alfi->closure) {
+ Z_ADDREF_P(alfi->closure);
+ add_next_index_zval(return_value,
alfi->closure);
+ } else if (alfi->func_ptr->common.scope) {
zval *tmp;
MAKE_STD_ZVAL(tmp);
array_init(tmp);
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/spl_autoload_bug48541.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u
Index: php-src/ext/spl/tests/spl_autoload_bug48541.phpt
diff -u php-src/ext/spl/tests/spl_autoload_bug48541.phpt:1.1.2.2
php-src/ext/spl/tests/spl_autoload_bug48541.phpt:1.1.2.3
--- php-src/ext/spl/tests/spl_autoload_bug48541.phpt:1.1.2.2 Sat Jun 13
17:30:50 2009
+++ php-src/ext/spl/tests/spl_autoload_bug48541.phpt Tue Jun 30 17:14:37 2009
@@ -2,23 +2,38 @@
SPL: spl_autoload_register() Bug #48541: registering multiple closures fails
with memleaks
--FILE--
<?php
+
+class X {
+ public function getClosure() {
+ return function($class) {
+ echo "a2 called\n";
+ };
+ }
+}
+
$a = function ($class) {
echo "a called\n";
};
+$x = new X;
+$a2 = $x->getClosure();
$b = function ($class) {
eval('class ' . $class . '{function __construct(){echo "foo\n";}}');
echo "b called\n";
};
spl_autoload_register($a);
+spl_autoload_register($a2);
spl_autoload_register($b);
$c = $a;
+$c2 = $a2;
spl_autoload_register($c);
+spl_autoload_register($c2);
$c = new foo;
?>
===DONE===
--EXPECT--
a called
+a2 called
b called
foo
===DONE===
\ No newline at end of file
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/spl_autoload_013.phpt?view=markup&rev=1.1
Index: php-src/ext/spl/tests/spl_autoload_013.phpt
+++ php-src/ext/spl/tests/spl_autoload_013.phpt
--TEST--
SPL: spl_autoload_functions() with closures and invokables
--FILE--
<?php
$closure = function($class) {
echo "a called\n";
};
class Autoloader {
private $dir;
public function __construct($dir) {
$this->dir = $dir;
}
public function __invoke($class) {
var_dump("{$this->dir}/$class.php");
}
}
$al1 = new Autoloader('d1');
$al2 = new Autoloader('d2');
spl_autoload_register($closure);
spl_autoload_register($al1);
spl_autoload_register($al2);
var_dump(spl_autoload_functions());
?>
===DONE===
--EXPECTF--
array(3) {
[0]=>
object(Closure)#%d (2) {
["this"]=>
NULL
["parameter"]=>
array(1) {
["$class"]=>
string(10) "<required>"
}
}
[1]=>
object(Autoloader)#%d (1) {
[u"dir":u"Autoloader":private]=>
unicode(2) "d1"
}
[2]=>
object(Autoloader)#%d (1) {
[u"dir":u"Autoloader":private]=>
unicode(2) "d2"
}
}
===DONE===
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/spl_autoload_014.phpt?view=markup&rev=1.1
Index: php-src/ext/spl/tests/spl_autoload_014.phpt
+++ php-src/ext/spl/tests/spl_autoload_014.phpt
--TEST--
SPL: spl_autoload_unregister() with closures and invokables
--FILE--
<?php
$closure = function($class) {
echo "closure called with class $class\n";
};
class Autoloader {
private $dir;
public function __construct($dir) {
$this->dir = $dir;
}
public function __invoke($class) {
echo ("Autoloader('{$this->dir}') called with $class\n");
}
}
class WorkingAutoloader {
public function __invoke($class) {
echo ("WorkingAutoloader() called with $class\n");
eval("class $class { }");
}
}
$al1 = new Autoloader('d1');
$al2 = new WorkingAutoloader('d2');
spl_autoload_register($closure);
spl_autoload_register($al1);
spl_autoload_register($al2);
$x = new TestX;
spl_autoload_unregister($closure);
spl_autoload_unregister($al1);
$y = new TestY;
?>
===DONE===
--EXPECT--
closure called with class TestX
Autoloader('d1') called with TestX
WorkingAutoloader() called with TestX
WorkingAutoloader() called with TestY
===DONE===
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php