summaryrefslogtreecommitdiff
path: root/ext/reflection
diff options
context:
space:
mode:
Diffstat (limited to 'ext/reflection')
-rwxr-xr-xext/reflection/config.m42
-rwxr-xr-xext/reflection/config.w322
-rw-r--r--ext/reflection/php_reflection.c73
-rw-r--r--ext/reflection/php_reflection.h2
-rw-r--r--ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt15
-rw-r--r--ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt8
-rw-r--r--ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt4
-rw-r--r--ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt18
-rw-r--r--ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt15
-rw-r--r--ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt17
-rw-r--r--ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt4
-rw-r--r--ext/reflection/tests/bug46064.phpt13
-rw-r--r--ext/reflection/tests/bug46064_2.phpt12
-rw-r--r--ext/reflection/tests/bug47254.phpt42
-rw-r--r--ext/reflection/tests/bug48757.phpt21
-rw-r--r--ext/reflection/tests/bug49074.phpt31
-rw-r--r--ext/reflection/tests/bug49092.phpt12
17 files changed, 239 insertions, 52 deletions
diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4
index a3ccc0f07..fb0cf4fd0 100755
--- a/ext/reflection/config.m4
+++ b/ext/reflection/config.m4
@@ -1,4 +1,4 @@
-dnl $Id: config.m4,v 1.4.2.3.2.1.2.3 2008/05/02 23:05:05 tony2001 Exp $
+dnl $Id: config.m4 258935 2008-05-02 23:05:05Z tony2001 $
dnl config.m4 for extension reflection
AC_DEFINE(HAVE_REFLECTION, 1, [Whether Reflection is enabled])
diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32
index 11c7bccfa..fc368b8a2 100755
--- a/ext/reflection/config.w32
+++ b/ext/reflection/config.w32
@@ -1,4 +1,4 @@
-// $Id: config.w32,v 1.2.2.2.2.1.2.3 2008/06/23 10:22:42 pajoye Exp $
+// $Id: config.w32 261527 2008-06-23 10:22:42Z pajoye $
// vim:ft=javascript
EXTENSION("reflection", "php_reflection.c", false /* never shared */);
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index de1a2f08d..77af950df 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -20,7 +20,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_reflection.c,v 1.164.2.33.2.45.2.58 2009/06/16 14:33:33 felipe Exp $ */
+/* $Id: php_reflection.c 287991 2009-09-03 14:02:51Z sebastian $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -533,23 +533,25 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
string_init(&dyn);
count = 0;
- zend_hash_internal_pointer_reset_ex(properties, &pos);
+ if (properties && zend_hash_num_elements(properties)) {
+ zend_hash_internal_pointer_reset_ex(properties, &pos);
- while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
- char *prop_name;
- uint prop_name_size;
- ulong index;
+ while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
+ char *prop_name;
+ uint prop_name_size;
+ ulong index;
- if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
- if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
- if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
- count++;
- _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
+ if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
+ if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
+ if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
+ count++;
+ _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
+ }
}
+ efree(prop_name);
}
- efree(prop_name);
+ zend_hash_move_forward_ex(properties, &pos);
}
- zend_hash_move_forward_ex(properties, &pos);
}
string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
@@ -1514,8 +1516,18 @@ ZEND_METHOD(reflection_function, __construct)
fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC);
Z_ADDREF_P(closure);
} else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) {
+ char *nsname;
+
lcname = zend_str_tolower_dup(name_str, name_len);
- if (zend_hash_find(EG(function_table), lcname, name_len + 1, (void **)&fptr) == FAILURE) {
+
+ /* Ignore leading "\" */
+ nsname = lcname;
+ if (lcname[0] == '\\') {
+ nsname = &lcname[1];
+ name_len--;
+ }
+
+ if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) {
efree(lcname);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Function %s() does not exist", name_str);
@@ -1717,7 +1729,7 @@ ZEND_METHOD(reflection_function, getStaticVariables)
}
/* }}} */
-/* {{{ proto public mixed ReflectionFunction::invoke(mixed* args)
+/* {{{ proto public mixed ReflectionFunction::invoke([mixed* args])
Invokes the function */
ZEND_METHOD(reflection_function, invoke)
{
@@ -1732,7 +1744,7 @@ ZEND_METHOD(reflection_function, invoke)
METHOD_NOTSTATIC(reflection_function_ptr);
GET_REFLECTION_OBJECT_PTR(fptr);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &params, &num_args) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
return;
}
@@ -1754,7 +1766,9 @@ ZEND_METHOD(reflection_function, invoke)
result = zend_call_function(&fci, &fcc TSRMLS_CC);
- efree(params);
+ if (num_args) {
+ efree(params);
+ }
if (result == FAILURE) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
@@ -2660,11 +2674,11 @@ ZEND_METHOD(reflection_method, invokeArgs)
{
if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Trying to invoke abstract method %s::%s",
+ "Trying to invoke abstract method %s::%s()",
mptr->common.scope->name, mptr->common.function_name);
} else {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Trying to invoke %s method %s::%s from scope %s",
+ "Trying to invoke %s method %s::%s() from scope %s",
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
mptr->common.scope->name, mptr->common.function_name,
Z_OBJCE_P(getThis())->name);
@@ -2691,7 +2705,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
if (!object) {
efree(params);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Trying to invoke non static method %s::%s without an object",
+ "Trying to invoke non static method %s::%s() without an object",
mptr->common.scope->name, mptr->common.function_name);
return;
}
@@ -3026,6 +3040,7 @@ ZEND_METHOD(reflection_class, getStaticProperties)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
GET_REFLECTION_OBJECT_PTR(ce);
zend_update_class_constants(ce TSRMLS_CC);
@@ -3041,12 +3056,20 @@ ZEND_METHOD(reflection_class, getStaticProperties)
if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) {
char *prop_name, *class_name;
+ zval *prop_copy;
zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
- zval_add_ref(value);
+ /* filter privates from base classes */
+ if (!(class_name && class_name[0] != '*' && strcmp(class_name, ce->name))) {
+ /* copy: enforce read only access */
+ ALLOC_ZVAL(prop_copy);
+ *prop_copy = **value;
+ zval_copy_ctor(prop_copy);
+ INIT_PZVAL(prop_copy);
- zend_hash_update(Z_ARRVAL_P(return_value), prop_name, strlen(prop_name)+1, value, sizeof(zval *), NULL);
+ add_assoc_zval(return_value, prop_name, prop_copy);
+ }
}
zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos);
}
@@ -5008,7 +5031,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
ZEND_ARG_INFO(0, name)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invoke, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
ZEND_ARG_INFO(0, args)
ZEND_END_ARG_INFO()
@@ -5442,7 +5465,7 @@ PHP_MINFO_FUNCTION(reflection) /* {{{ */
php_info_print_table_start();
php_info_print_table_header(2, "Reflection", "enabled");
- php_info_print_table_row(2, "Version", "$Revision: 1.164.2.33.2.45.2.58 $");
+ php_info_print_table_row(2, "Version", "$Revision: 287991 $");
php_info_print_table_end();
} /* }}} */
@@ -5456,7 +5479,7 @@ zend_module_entry reflection_module_entry = { /* {{{ */
NULL,
NULL,
PHP_MINFO(reflection),
- "$Revision: 1.164.2.33.2.45.2.58 $",
+ "$Revision: 287991 $",
STANDARD_MODULE_PROPERTIES
}; /* }}} */
diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h
index e38ee3663..d280a9f4e 100644
--- a/ext/reflection/php_reflection.h
+++ b/ext/reflection/php_reflection.h
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_reflection.h,v 1.4.2.3.2.2.2.2 2008/12/31 11:15:42 sebastian Exp $ */
+/* $Id: php_reflection.h 272370 2008-12-31 11:15:49Z sebastian $ */
#ifndef PHP_REFLECTION_H
#define PHP_REFLECTION_H
diff --git a/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt
new file mode 100644
index 000000000..6b440cfe0
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Reflection class can not be cloned
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection)) print 'skip';
+?>
+--FILE--
+<?php
+$rc = new ReflectionClass("stdClass");
+$rc2 = clone($rc);
+--EXPECTF--
+Fatal error: Trying to clone an uncloneable object of class ReflectionClass in %s on line %d
diff --git a/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt
index 3bf8f77ec..e19db8118 100644
--- a/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt
+++ b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt
@@ -109,13 +109,12 @@ Array
(
[statPubC] => stat pubC in B
[statProtC] => stat protC in B
- [statPrivC] => stat privC in A
+ [statPrivC] => stat privC in B
[statPubB] => stat pubB in B
[statProtB] => stat protB in B
[statPrivB] => stat privB in B
[statPubA] => stat pubA in A
[statProtA] => stat protA in A
- [statPrivA] => stat privA in A
)
@@ -146,13 +145,11 @@ Array
(
[statPubC] => stat pubC in C
[statProtC] => stat protC in C
- [statPrivC] => stat privC in A
+ [statPrivC] => stat privC in C
[statPubB] => stat pubB in B
[statProtB] => stat protB in B
- [statPrivB] => stat privB in B
[statPubA] => stat pubA in A
[statProtA] => stat protA in A
- [statPrivA] => stat privA in A
)
@@ -195,4 +192,3 @@ Array
[protC] => protC in X
[privC] => privC in X
)
-
diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt
index 70a3bab9c..082ef676c 100644
--- a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt
+++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt
@@ -67,11 +67,11 @@ Array
)
Array
(
- [privateOverridden] => new value 4
+ [privateOverridden] => new value 5
[protectedOverridden] => new value 6
[publicOverridden] => new value 7
)
Set non-existent values from A with no default value:
Class A does not have a property named protectedOverridden
-Class A does not have a property named privateOverridden \ No newline at end of file
+Class A does not have a property named privateOverridden
diff --git a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt
new file mode 100644
index 000000000..eeaf8d382
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Reflection::isClosure
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) {
+ print 'skip';
+}
+?>
+--FILE--
+<?php
+$closure = function($param) { return "this is a closure"; };
+$rc = new ReflectionFunction($closure);
+echo var_dump($rc->isClosure());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt
new file mode 100644
index 000000000..31d37a85f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionFunction::isDeprecated
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) print 'skip';
+?>
+--FILE--
+<?php
+$rc = new ReflectionFunction('ereg');
+echo var_dump($rc->isDeprecated());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt
new file mode 100644
index 000000000..c71b96b8e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionFunction::isDisabled
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection')) print 'skip';
+?>
+--INI--
+disable_functions=is_file
+--FILE--
+<?php
+$rc = new ReflectionFunction('is_file');
+echo var_dump($rc->isDisabled());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
index a0a336a9a..513cc1845 100644
--- a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
@@ -109,9 +109,9 @@ NULL
NULL
Private method:
-string(84) "Trying to invoke private method TestClass::privateMethod from scope ReflectionMethod"
+string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod"
Abstract method:
-string(51) "Trying to invoke abstract method AbstractClass::foo"
+string(53) "Trying to invoke abstract method AbstractClass::foo()"
Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d
diff --git a/ext/reflection/tests/bug46064.phpt b/ext/reflection/tests/bug46064.phpt
index 89c5af37d..510e71b00 100644
--- a/ext/reflection/tests/bug46064.phpt
+++ b/ext/reflection/tests/bug46064.phpt
@@ -37,10 +37,6 @@ class bar extends test {
$this->foobar = 2;
$this->a = 200;
- $p = new reflectionproperty($this, 'a');
- $p->setAccessible(true);
- var_dump($p->getValue($this), $p->isDefault(), $p->isPublic());
-
$p = new reflectionproperty($this, 'foobar');
var_dump($p->getValue($this), $p->isDefault(), $p->isPublic());
}
@@ -49,8 +45,9 @@ class bar extends test {
new bar;
?>
+===DONE===
--EXPECTF--
-object(ReflectionProperty)#2 (2) {
+object(ReflectionProperty)#%d (2) {
["name"]=>
string(1) "z"
["class"]=>
@@ -67,15 +64,13 @@ array(1) {
int(1000)
---------------------------
string(30) "Property x::$zz does not exist"
-object(ReflectionProperty)#3 (2) {
+object(ReflectionProperty)#%d (2) {
["name"]=>
string(3) "zzz"
["class"]=>
string(1) "x"
}
-int(200)
-bool(true)
-bool(false)
int(2)
bool(false)
bool(true)
+===DONE===
diff --git a/ext/reflection/tests/bug46064_2.phpt b/ext/reflection/tests/bug46064_2.phpt
index 832d13c41..da14148a7 100644
--- a/ext/reflection/tests/bug46064_2.phpt
+++ b/ext/reflection/tests/bug46064_2.phpt
@@ -36,14 +36,15 @@ class test extends bar {
new test;
?>
---EXPECT--
-object(ReflectionProperty)#3 (2) {
+===DONE===
+--EXPECTF--
+object(ReflectionProperty)#%d (2) {
["name"]=>
string(4) "test"
["class"]=>
string(3) "foo"
}
-object(ReflectionProperty)#5 (2) {
+object(ReflectionProperty)#%d (2) {
["name"]=>
string(1) "a"
["class"]=>
@@ -56,17 +57,18 @@ bool(true)
bool(false)
array(2) {
[0]=>
- &object(ReflectionProperty)#6 (2) {
+ &object(ReflectionProperty)#%d (2) {
["name"]=>
string(1) "b"
["class"]=>
string(4) "test"
}
[1]=>
- &object(ReflectionProperty)#7 (2) {
+ &object(ReflectionProperty)#%d (2) {
["name"]=>
string(1) "a"
["class"]=>
string(4) "test"
}
}
+===DONE=== \ No newline at end of file
diff --git a/ext/reflection/tests/bug47254.phpt b/ext/reflection/tests/bug47254.phpt
new file mode 100644
index 000000000..4bcce1bb7
--- /dev/null
+++ b/ext/reflection/tests/bug47254.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #47254
+--CREDITS--
+Sebastian Schürmann
+sebs@php.net
+Testfest 2009 Munich
+--FILE--
+<?php
+class A
+{
+ protected function a() {}
+
+}
+
+class B extends A
+{
+ public function b() {}
+}
+
+$B = new B();
+$R = new ReflectionObject($B);
+$m = $R->getMethods();
+print_r($m);
+
+?>
+--CLEAN--
+--EXPECT--
+Array
+(
+ [0] => ReflectionMethod Object
+ (
+ [name] => b
+ [class] => B
+ )
+
+ [1] => ReflectionMethod Object
+ (
+ [name] => a
+ [class] => A
+ )
+
+)
diff --git a/ext/reflection/tests/bug48757.phpt b/ext/reflection/tests/bug48757.phpt
new file mode 100644
index 000000000..a5ced91d3
--- /dev/null
+++ b/ext/reflection/tests/bug48757.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #48757 (ReflectionFunction::invoke() parameter issues)
+--FILE--
+<?php
+function test() {
+ echo "Hello World\n";
+}
+
+function another_test($parameter) {
+ var_dump($parameter);
+}
+
+$func = new ReflectionFunction('test');
+$func->invoke();
+
+$func = new ReflectionFunction('another_test');
+$func->invoke('testing');
+?>
+--EXPECT--
+Hello World
+string(7) "testing"
diff --git a/ext/reflection/tests/bug49074.phpt b/ext/reflection/tests/bug49074.phpt
new file mode 100644
index 000000000..7ce23b41e
--- /dev/null
+++ b/ext/reflection/tests/bug49074.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #49074 (private class static fields can be modified by using reflection)
+--FILE--
+<?php
+class Test {
+ private static $data1 = 1;
+ private static $data4 = 4;
+}
+
+class Test2 extends Test {
+ private static $data2 = 2;
+ public static $data3 = 3;
+}
+
+$r = new ReflectionClass('Test2');
+$m = $r->getStaticProperties();
+
+$m['data1'] = 100;
+$m['data2'] = 200;
+$m['data3'] = 300;
+$m['data4'] = 400;
+
+var_dump($r->getStaticProperties());
+?>
+--EXPECT--
+array(2) {
+ ["data2"]=>
+ int(2)
+ ["data3"]=>
+ int(3)
+}
diff --git a/ext/reflection/tests/bug49092.phpt b/ext/reflection/tests/bug49092.phpt
new file mode 100644
index 000000000..460a13127
--- /dev/null
+++ b/ext/reflection/tests/bug49092.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Bug #49092 (ReflectionFunction fails to work with functions in fully qualified namespaces)
+--FILE--
+<?php
+namespace ns;
+function func(){}
+new \ReflectionFunction('ns\func');
+new \ReflectionFunction('\ns\func');
+echo "Ok\n"
+?>
+--EXPECT--
+Ok