mirror of
https://github.com/php/php-src.git
synced 2025-01-25 05:04:20 +08:00
MFH:
- Fixed bug #45862 (get_class_vars is inconsistent with 'protected' and 'private' variables) - Added some tests
This commit is contained in:
parent
a7d2377ce4
commit
317b48f3af
43
Zend/tests/bug45862.phpt
Normal file
43
Zend/tests/bug45862.phpt
Normal file
@ -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) {
|
||||
["prot"]=>
|
||||
string(13) "protected var"
|
||||
}
|
||||
string(13) "protected var"
|
||||
|
||||
From child scope
|
||||
array(1) {
|
||||
["prot"]=>
|
||||
string(13) "protected var"
|
||||
}
|
33
Zend/tests/get_class_vars_001.phpt
Normal file
33
Zend/tests/get_class_vars_001.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["aa"]=>
|
||||
int(4)
|
||||
}
|
49
Zend/tests/get_class_vars_002.phpt
Normal file
49
Zend/tests/get_class_vars_002.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
array(3) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["aa"]=>
|
||||
int(4)
|
||||
["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
|
47
Zend/tests/get_class_vars_003.phpt
Normal file
47
Zend/tests/get_class_vars_003.phpt
Normal file
@ -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) {
|
||||
["aaa"]=>
|
||||
int(7)
|
||||
["ccc"]=>
|
||||
int(9)
|
||||
["a"]=>
|
||||
int(1)
|
||||
["aa"]=>
|
||||
int(4)
|
||||
["cc"]=>
|
||||
int(6)
|
||||
}
|
67
Zend/tests/get_class_vars_004.phpt
Normal file
67
Zend/tests/get_class_vars_004.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["A"]=>
|
||||
int(2)
|
||||
}
|
||||
array(6) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
int(3)
|
||||
["c"]=>
|
||||
int(5)
|
||||
["A"]=>
|
||||
int(2)
|
||||
["B"]=>
|
||||
int(4)
|
||||
["C"]=>
|
||||
int(6)
|
||||
}
|
||||
array(6) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
int(3)
|
||||
["c"]=>
|
||||
int(5)
|
||||
["A"]=>
|
||||
int(2)
|
||||
["B"]=>
|
||||
int(4)
|
||||
["C"]=>
|
||||
int(6)
|
||||
}
|
||||
NULL
|
39
Zend/tests/get_class_vars_005.phpt
Normal file
39
Zend/tests/get_class_vars_005.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
["c"]=>
|
||||
int(3)
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
48
Zend/tests/get_class_vars_006.phpt
Normal file
48
Zend/tests/get_class_vars_006.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
array(1) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
}
|
||||
array(0) {
|
||||
}
|
41
Zend/tests/get_class_vars_007.phpt
Normal file
41
Zend/tests/get_class_vars_007.phpt
Normal file
@ -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) {
|
||||
["a"]=>
|
||||
NULL
|
||||
["aa"]=>
|
||||
NULL
|
||||
}
|
||||
array(6) {
|
||||
["a"]=>
|
||||
NULL
|
||||
["aa"]=>
|
||||
NULL
|
||||
["b"]=>
|
||||
NULL
|
||||
["bb"]=>
|
||||
NULL
|
||||
["c"]=>
|
||||
NULL
|
||||
["cc"]=>
|
||||
NULL
|
||||
}
|
||||
NULL
|
@ -977,8 +977,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;
|
||||
@ -987,20 +985,28 @@ 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) {
|
||||
char *key, *class_name, *prop_name;
|
||||
uint key_len;
|
||||
ulong num_index;
|
||||
ulong num_index, h;
|
||||
int prop_name_len = 0;
|
||||
zval *prop_copy;
|
||||
zend_property_info *property_info;
|
||||
|
||||
zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos);
|
||||
zend_hash_move_forward_ex(properties, &pos);
|
||||
|
||||
zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
|
||||
if (class_name) {
|
||||
if (class_name[0] != '*' && strcmp(class_name, ce->name)) {
|
||||
/* filter privates from base classes */
|
||||
continue;
|
||||
} else if (!instanceof) {
|
||||
/* filter protected if not inside class */
|
||||
continue;
|
||||
}
|
||||
prop_name_len = strlen(prop_name);
|
||||
|
||||
h = zend_get_hash_value(prop_name, prop_name_len+1);
|
||||
if (zend_hash_quick_find(&ce->properties_info, 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user