Skip to content

Commit ec53b60

Browse files
committed
Merge branch 'PHP-5.3' of git.php.net:/php-src into PHP-5.3
2 parents 93fd9c7 + 38bf695 commit ec53b60

File tree

6 files changed

+123
-70
lines changed

6 files changed

+123
-70
lines changed

Zend/tests/bug63462.phpt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
--TEST--
2+
Test script to verify that magic methods should be called only once when accessing an unset property.
3+
--CREDITS--
4+
Marco Pivetta <ocramius@gmail.com>
5+
--FILE--
6+
<?php
7+
class Test {
8+
public $publicProperty;
9+
protected $protectedProperty;
10+
private $privateProperty;
11+
12+
public function __construct() {
13+
unset(
14+
$this->publicProperty,
15+
$this->protectedProperty,
16+
$this->privateProperty
17+
);
18+
}
19+
20+
function __get($name) {
21+
echo '__get ' . $name . "\n";
22+
return $this->$name;
23+
}
24+
25+
function __set($name, $value) {
26+
echo '__set ' . $name . "\n";
27+
$this->$name = $value;
28+
}
29+
30+
function __isset($name) {
31+
echo '__isset ' . $name . "\n";
32+
return isset($this->$name);
33+
}
34+
}
35+
36+
$test = new Test();
37+
38+
$test->nonExisting;
39+
$test->publicProperty;
40+
$test->protectedProperty;
41+
$test->privateProperty;
42+
isset($test->nonExisting);
43+
isset($test->publicProperty);
44+
isset($test->protectedProperty);
45+
isset($test->privateProperty);
46+
$test->nonExisting = 'value';
47+
$test->publicProperty = 'value';
48+
$test->protectedProperty = 'value';
49+
$test->privateProperty = 'value';
50+
51+
?>
52+
53+
--EXPECTF--
54+
__get nonExisting
55+
56+
Notice: Undefined property: Test::$nonExisting in %s on line %d
57+
__get publicProperty
58+
59+
Notice: Undefined property: Test::$publicProperty in %s on line %d
60+
__get protectedProperty
61+
62+
Notice: Undefined property: Test::$protectedProperty in %s on line %d
63+
__get privateProperty
64+
65+
Notice: Undefined property: Test::$privateProperty in %s on line %d
66+
__isset nonExisting
67+
__isset publicProperty
68+
__isset protectedProperty
69+
__isset privateProperty
70+
__set nonExisting
71+
__set publicProperty
72+
__set protectedProperty
73+
__set privateProperty
74+

Zend/zend_object_handlers.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ static int zend_get_property_guard(zend_object *zobj, zend_property_info *proper
296296
info.name = Z_STRVAL_P(member);
297297
info.name_length = Z_STRLEN_P(member);
298298
info.h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1);
299+
} else if(property_info->name[0] == '\0'){
300+
const char *class_name = NULL, *prop_name = NULL;
301+
zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
302+
if(class_name) {
303+
/* use unmangled name for protected properties */
304+
info.name = prop_name;
305+
info.name_length = strlen(prop_name);
306+
info.h = zend_get_hash_value(info.name, info.name_length+1);
307+
property_info = &info;
308+
}
299309
}
300310
if (!zobj->guards) {
301311
ALLOC_HASHTABLE(zobj->guards);

Zend/zend_vm_def.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -896,23 +896,12 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
896896
{
897897
zend_op *opline = EX(opline);
898898
zend_free_op free_op1;
899-
zval z_copy;
900899
zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);
901900

902-
if (OP1_TYPE != IS_CONST &&
903-
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
904-
if (OP1_TYPE == IS_TMP_VAR) {
905-
INIT_PZVAL(z);
906-
}
907-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
908-
zend_print_variable(&z_copy);
909-
zval_dtor(&z_copy);
910-
} else {
911-
zend_print_variable(z);
912-
}
913-
} else {
914-
zend_print_variable(z);
901+
if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
902+
INIT_PZVAL(z);
915903
}
904+
zend_print_variable(z);
916905

917906
FREE_OP1();
918907
ZEND_VM_NEXT_OPCODE();

Zend/zend_vm_execute.h

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,23 +1320,12 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
13201320
{
13211321
zend_op *opline = EX(opline);
13221322

1323-
zval z_copy;
13241323
zval *z = &opline->op1.u.constant;
13251324

1326-
if (IS_CONST != IS_CONST &&
1327-
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
1328-
if (IS_CONST == IS_TMP_VAR) {
1329-
INIT_PZVAL(z);
1330-
}
1331-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
1332-
zend_print_variable(&z_copy);
1333-
zval_dtor(&z_copy);
1334-
} else {
1335-
zend_print_variable(z);
1336-
}
1337-
} else {
1338-
zend_print_variable(z);
1325+
if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
1326+
INIT_PZVAL(z);
13391327
}
1328+
zend_print_variable(z);
13401329

13411330
ZEND_VM_NEXT_OPCODE();
13421331
}
@@ -4635,23 +4624,12 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
46354624
{
46364625
zend_op *opline = EX(opline);
46374626
zend_free_op free_op1;
4638-
zval z_copy;
46394627
zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
46404628

4641-
if (IS_TMP_VAR != IS_CONST &&
4642-
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
4643-
if (IS_TMP_VAR == IS_TMP_VAR) {
4644-
INIT_PZVAL(z);
4645-
}
4646-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
4647-
zend_print_variable(&z_copy);
4648-
zval_dtor(&z_copy);
4649-
} else {
4650-
zend_print_variable(z);
4651-
}
4652-
} else {
4653-
zend_print_variable(z);
4629+
if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
4630+
INIT_PZVAL(z);
46544631
}
4632+
zend_print_variable(z);
46554633

46564634
zval_dtor(free_op1.var);
46574635
ZEND_VM_NEXT_OPCODE();
@@ -7898,23 +7876,12 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
78987876
{
78997877
zend_op *opline = EX(opline);
79007878
zend_free_op free_op1;
7901-
zval z_copy;
79027879
zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
79037880

7904-
if (IS_VAR != IS_CONST &&
7905-
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
7906-
if (IS_VAR == IS_TMP_VAR) {
7907-
INIT_PZVAL(z);
7908-
}
7909-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
7910-
zend_print_variable(&z_copy);
7911-
zval_dtor(&z_copy);
7912-
} else {
7913-
zend_print_variable(z);
7914-
}
7915-
} else {
7916-
zend_print_variable(z);
7881+
if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
7882+
INIT_PZVAL(z);
79177883
}
7884+
zend_print_variable(z);
79187885

79197886
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
79207887
ZEND_VM_NEXT_OPCODE();
@@ -21823,23 +21790,12 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
2182321790
{
2182421791
zend_op *opline = EX(opline);
2182521792

21826-
zval z_copy;
2182721793
zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
2182821794

21829-
if (IS_CV != IS_CONST &&
21830-
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
21831-
if (IS_CV == IS_TMP_VAR) {
21832-
INIT_PZVAL(z);
21833-
}
21834-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
21835-
zend_print_variable(&z_copy);
21836-
zval_dtor(&z_copy);
21837-
} else {
21838-
zend_print_variable(z);
21839-
}
21840-
} else {
21841-
zend_print_variable(z);
21795+
if (IS_CV == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
21796+
INIT_PZVAL(z);
2184221797
}
21798+
zend_print_variable(z);
2184321799

2184421800
ZEND_VM_NEXT_OPCODE();
2184521801
}

ext/spl/spl_directory.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,10 @@ static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TS
18731873
spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
18741874

18751875
if (type == IS_STRING) {
1876+
if (Z_OBJCE_P(readobj)->__tostring) {
1877+
return std_object_handlers.cast_object(readobj, writeobj, type TSRMLS_CC);
1878+
}
1879+
18761880
switch (intern->type) {
18771881
case SPL_FS_INFO:
18781882
case SPL_FS_FILE:

ext/spl/tests/bug64023.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #64023: Overloading __toString() in SplFileInfo has no effect
3+
--FILE--
4+
<?php
5+
class A extends \SplFileInfo
6+
{
7+
public function __toString() {return ' -expected- ';}
8+
}
9+
10+
$a = new A('/');
11+
12+
// Works
13+
echo $a, $a->__toString(), $a->__toString() . '', "\n";
14+
15+
// Does not work - outputs parent::__toString()
16+
echo $a . '', "\n";
17+
18+
--EXPECT--
19+
-expected- -expected- -expected-
20+
-expected-

0 commit comments

Comments
 (0)