diff options
| author | Felipe Pena <felipe@php.net> | 2008-08-22 00:54:00 +0000 |
|---|---|---|
| committer | Felipe Pena <felipe@php.net> | 2008-08-22 00:54:00 +0000 |
| commit | 65cc4f2e86ba3bf38cf67b807daef1ad6e3989d5 (patch) | |
| tree | 3bbb1c30f8e54b490c46ae3e6e6a3e28365a83f2 | |
| parent | adfa214688b0baa9141422770dd2eb91b491335d (diff) | |
| download | php-git-65cc4f2e86ba3bf38cf67b807daef1ad6e3989d5.tar.gz | |
- Fixed bug #45862 (get_class_vars is inconsistent with 'protected' and 'private' variables)
- Added some tests
| -rw-r--r-- | Zend/tests/bug45862.phpt | 43 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_001.phpt | 33 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_002.phpt | 49 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_003.phpt | 47 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_004.phpt | 67 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_005.phpt | 39 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_006.phpt | 48 | ||||
| -rw-r--r-- | Zend/tests/get_class_vars_007.phpt | 41 | ||||
| -rw-r--r-- | Zend/zend_builtin_functions.c | 28 |
9 files changed, 384 insertions, 11 deletions
diff --git a/Zend/tests/bug45862.phpt b/Zend/tests/bug45862.phpt new file mode 100644 index 0000000000..4f4dfe46d6 --- /dev/null +++ b/Zend/tests/bug45862.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #45862 (get_class_vars is inconsistent with 'protected' and 'private' variables) +--FILE-- +<?php + +class Ancestor { + function test() { + var_dump(get_class_vars("Tester")); + var_dump(Tester::$prot); + } +} + +class Tester extends Ancestor { + static protected $prot = "protected var"; + static private $priv = "private var"; +} + +class Child extends Tester { + function test() { var_dump(get_class_vars("Tester")); } +} + +echo "\n From parent scope\n"; +$parent = new Ancestor(); +$parent->test(); +echo "\n From child scope\n"; +$child = new Child(); +$child->test(); + +?> +--EXPECT-- + + From parent scope +array(1) { + [u"prot"]=> + unicode(13) "protected var" +} +unicode(13) "protected var" + + From child scope +array(1) { + [u"prot"]=> + unicode(13) "protected var" +} diff --git a/Zend/tests/get_class_vars_001.phpt b/Zend/tests/get_class_vars_001.phpt new file mode 100644 index 0000000000..3066f8eba5 --- /dev/null +++ b/Zend/tests/get_class_vars_001.phpt @@ -0,0 +1,33 @@ +--TEST-- +get_class_vars(): Simple test +--FILE-- +<?php + +class A { + public $a = 1; + private $b = 2; + private $c = 3; +} + +class B extends A { + static public $aa = 4; + static private $bb = 5; + static protected $cc = 6; +} + + +var_dump(get_class_vars('A')); +var_dump(get_class_vars('B')); + +?> +--EXPECT-- +array(1) { + [u"a"]=> + int(1) +} +array(2) { + [u"a"]=> + int(1) + [u"aa"]=> + int(4) +} diff --git a/Zend/tests/get_class_vars_002.phpt b/Zend/tests/get_class_vars_002.phpt new file mode 100644 index 0000000000..7fe1b7606f --- /dev/null +++ b/Zend/tests/get_class_vars_002.phpt @@ -0,0 +1,49 @@ +--TEST-- +get_class_vars(): Testing the scope +--FILE-- +<?php + +class A { + public $a = 1; + private $b = 2; + private $c = 3; +} + +class B extends A { + static public $aa = 4; + static private $bb = 5; + static protected $cc = 6; +} + +class C extends B { + public function __construct() { + var_dump(get_class_vars('A')); + var_dump(get_class_vars('B')); + + var_dump($this->a, $this->b, $this->c); + } +} + +new C; + +?> +--EXPECTF-- +array(1) { + [u"a"]=> + int(1) +} +array(3) { + [u"a"]=> + int(1) + [u"aa"]=> + int(4) + [u"cc"]=> + int(6) +} + +Notice: Undefined property: C::$b in %s on line %d + +Notice: Undefined property: C::$c in %s on line %d +int(1) +NULL +NULL diff --git a/Zend/tests/get_class_vars_003.phpt b/Zend/tests/get_class_vars_003.phpt new file mode 100644 index 0000000000..9ffe9bf530 --- /dev/null +++ b/Zend/tests/get_class_vars_003.phpt @@ -0,0 +1,47 @@ +--TEST-- +get_class_vars(): Testing the scope +--FILE-- +<?php + +class A { + public $a = 1; + private $b = 2; + private $c = 3; +} + +class B extends A { + static public $aa = 4; + static private $bb = 5; + static protected $cc = 6; + + protected function __construct() { + var_dump(get_class_vars('C')); + } +} + +class C extends B { + public $aaa = 7; + private $bbb = 8; + protected $ccc = 9; + + public function __construct() { + parent::__construct(); + } +} + +new C; + +?> +--EXPECT-- +array(5) { + [u"aaa"]=> + int(7) + [u"ccc"]=> + int(9) + [u"a"]=> + int(1) + [u"aa"]=> + int(4) + [u"cc"]=> + int(6) +} diff --git a/Zend/tests/get_class_vars_004.phpt b/Zend/tests/get_class_vars_004.phpt new file mode 100644 index 0000000000..258984c132 --- /dev/null +++ b/Zend/tests/get_class_vars_004.phpt @@ -0,0 +1,67 @@ +--TEST-- +get_class_vars(): Testing the scope +--FILE-- +<?php + +class A { + public $a = 1; + static public $A = 2; + + private $b = 3; + static private $B = 4; + + protected $c = 5; + static protected $C = 6; + + public function __construct() { + var_dump(get_class_vars('A')); + } + + static public function test() { + var_dump(get_class_vars('A')); + } +} + +var_dump(get_class_vars('A')); + +new A; + +var_dump(A::test()); + +?> +--EXPECT-- +array(2) { + [u"a"]=> + int(1) + [u"A"]=> + int(2) +} +array(6) { + [u"a"]=> + int(1) + [u"b"]=> + int(3) + [u"c"]=> + int(5) + [u"A"]=> + int(2) + [u"B"]=> + int(4) + [u"C"]=> + int(6) +} +array(6) { + [u"a"]=> + int(1) + [u"b"]=> + int(3) + [u"c"]=> + int(5) + [u"A"]=> + int(2) + [u"B"]=> + int(4) + [u"C"]=> + int(6) +} +NULL diff --git a/Zend/tests/get_class_vars_005.phpt b/Zend/tests/get_class_vars_005.phpt new file mode 100644 index 0000000000..b3acf943c7 --- /dev/null +++ b/Zend/tests/get_class_vars_005.phpt @@ -0,0 +1,39 @@ +--TEST-- +get_class_vars(): Testing visibility +--FILE-- +<?php + +class A { + protected $a = 1; + private $b = 2; +} + +class B extends A { + private $c = 3; + public function __construct() { + var_dump(get_class_vars('A')); + var_dump(get_class_vars('B')); + } +} + +var_dump(get_class_vars('A')); +var_dump(get_class_vars('B')); + +new B; + +?> +--EXPECT-- +array(0) { +} +array(0) { +} +array(1) { + [u"a"]=> + int(1) +} +array(2) { + [u"c"]=> + int(3) + [u"a"]=> + int(1) +} diff --git a/Zend/tests/get_class_vars_006.phpt b/Zend/tests/get_class_vars_006.phpt new file mode 100644 index 0000000000..8948399c27 --- /dev/null +++ b/Zend/tests/get_class_vars_006.phpt @@ -0,0 +1,48 @@ +--TEST-- +get_class_vars(): Testing visibility +--FILE-- +<?php + +class A { + protected $a = 1; +} + +class B extends A { } + +class C extends B { } + +var_dump(get_class_vars('A')); +var_dump(get_class_vars('B')); +var_dump(get_class_vars('C')); + +print "---\n"; + +class D extends B { + public function __construct() { + var_dump(get_class_vars('A')); + var_dump(get_class_vars('B')); + var_dump(get_class_vars('C')); + } +} + +new D; + +?> +--EXPECT-- +array(0) { +} +array(0) { +} +array(0) { +} +--- +array(1) { + [u"a"]=> + int(1) +} +array(1) { + [u"a"]=> + int(1) +} +array(0) { +} diff --git a/Zend/tests/get_class_vars_007.phpt b/Zend/tests/get_class_vars_007.phpt new file mode 100644 index 0000000000..97d9230489 --- /dev/null +++ b/Zend/tests/get_class_vars_007.phpt @@ -0,0 +1,41 @@ +--TEST-- +get_class_vars(): Testing with static properties +--FILE-- +<?php + +class A { + static public $a, $aa; + static private $b, $bb; + static protected $c, $cc; + + static public function test() { + var_dump(get_class_vars(__CLASS__)); + } +} + +var_dump(get_class_vars('A')); +var_dump(A::test()); + +?> +--EXPECT-- +array(2) { + [u"a"]=> + NULL + [u"aa"]=> + NULL +} +array(6) { + [u"a"]=> + NULL + [u"aa"]=> + NULL + [u"b"]=> + NULL + [u"bb"]=> + NULL + [u"c"]=> + NULL + [u"cc"]=> + NULL +} +NULL diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index b2daf3c489..3857afdddc 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -972,8 +972,6 @@ ZEND_FUNCTION(is_a) /* {{{ add_class_vars */ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *return_value TSRMLS_DC) { - int instanceof = EG(scope) && instanceof_function(EG(scope), ce TSRMLS_CC); - if (zend_hash_num_elements(properties) > 0) { HashPosition pos; zval **prop; @@ -982,21 +980,29 @@ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *re while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) { zstr key, class_name, prop_name; uint key_len; - ulong num_index; + ulong num_index, h; + int prop_name_len = 0; zval *prop_copy; zend_uchar key_type; + zend_property_info *property_info; key_type = zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos); zend_hash_move_forward_ex(properties, &pos); + zend_u_unmangle_property_name(key_type, key, key_len-1, &class_name, &prop_name); - if (class_name.v) { - if (class_name.s[0] != '*' && strcmp(class_name.s, ce->name.s)) { - /* filter privates from base classes */ - continue; - } else if (!instanceof) { - /* filter protected if not inside class */ - continue; - } + prop_name_len = ZSTR_LEN(key_type, prop_name); + + h = zend_u_get_hash_value(key_type, prop_name, prop_name_len+1); + if (zend_u_hash_quick_find(&ce->properties_info, key_type, prop_name, prop_name_len+1, h, (void **) &property_info) == FAILURE) { + continue; + } + + if (property_info->flags & ZEND_ACC_SHADOW) { + continue; + } else if ((property_info->flags & ZEND_ACC_PRIVATE) && EG(scope) != ce) { + continue; + } else if ((property_info->flags & ZEND_ACC_PROTECTED) && zend_check_protected(ce, EG(scope)) == 0) { + continue; } /* copy: enforce read only access */ |
