Skip to content

Commit 2642794

Browse files
committed
Merge branch 'PHP-5.4' of git.php.net:/php-src into PHP-5.4
2 parents a85ae16 + 5382e15 commit 2642794

14 files changed

+298
-115
lines changed

NEWS

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ PHP NEWS
33
?? ??? 2012, PHP 5.4.12
44

55
- Core:
6+
. Fixed bug #64011 (get_html_translation_table() output incomplete with
7+
HTML_ENTITIES and ISO-8859-1). (Gustavo)
68
. Fixed bug #63982 (isset() inconsistently produces a fatal error on
79
protected property). (Stas)
810
. Fixed bug #63943 (Bad warning text from strpos() on empty needle).
@@ -11,6 +13,10 @@ PHP NEWS
1113
. Fixed bug #63893 (Poor efficiency of strtr() using array with keys of very
1214
different length). (Gustavo)
1315
. Fixed bug #63882 (zend_std_compare_objects crash on recursion). (Dmitry)
16+
. Fixed bug #63462 (Magic methods called twice for unset protected
17+
properties). (Stas)
18+
. Fixed bug #62524 (fopen follows redirects for non-3xx statuses).
19+
(Wes Mason)
1420
. Support BITMAPV5HEADER in getimagesize(). (AsamK, Lars)
1521

1622
- Date:
@@ -38,7 +44,7 @@ PHP NEWS
3844
. Fixed bug #63916 (PDO::PARAM_INT casts to 32bit int internally even
3945
on 64bit builds in pdo_sqlite). (srgoogleguy, Lars)
4046

41-
?? ??? 2012, PHP 5.4.11
47+
17 Jan 2012, PHP 5.4.11
4248

4349
- Core:
4450
. Fixed bug #63762 (Sigsegv when Exception::$trace is changed by user).

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
@@ -393,6 +393,16 @@ static int zend_get_property_guard(zend_object *zobj, zend_property_info *proper
393393
info.name = Z_STRVAL_P(member);
394394
info.name_length = Z_STRLEN_P(member);
395395
info.h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1);
396+
} else if(property_info->name[0] == '\0'){
397+
const char *class_name = NULL, *prop_name = NULL;
398+
zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
399+
if(class_name) {
400+
/* use unmangled name for protected properties */
401+
info.name = prop_name;
402+
info.name_length = strlen(prop_name);
403+
info.h = zend_get_hash_value(info.name, info.name_length+1);
404+
property_info = &info;
405+
}
396406
}
397407
if (!zobj->guards) {
398408
ALLOC_HASHTABLE(zobj->guards);

Zend/zend_vm_def.h

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -974,27 +974,15 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
974974
{
975975
USE_OPLINE
976976
zend_free_op free_op1;
977-
zval z_copy;
978977
zval *z;
979978

980979
SAVE_OPLINE();
981980
z = GET_OP1_ZVAL_PTR(BP_VAR_R);
982981

983-
if (OP1_TYPE != IS_CONST &&
984-
UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) &&
985-
Z_OBJ_HT_P(z)->get_method != NULL) {
986-
if (OP1_TYPE == IS_TMP_VAR) {
987-
INIT_PZVAL(z);
988-
}
989-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
990-
zend_print_variable(&z_copy);
991-
zval_dtor(&z_copy);
992-
} else {
993-
zend_print_variable(z);
994-
}
995-
} else {
996-
zend_print_variable(z);
982+
if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
983+
INIT_PZVAL(z);
997984
}
985+
zend_print_variable(z);
998986

999987
FREE_OP1();
1000988
CHECK_EXCEPTION();

Zend/zend_vm_execute.h

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,27 +2024,15 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
20242024
{
20252025
USE_OPLINE
20262026

2027-
zval z_copy;
20282027
zval *z;
20292028

20302029
SAVE_OPLINE();
20312030
z = opline->op1.zv;
20322031

2033-
if (IS_CONST != IS_CONST &&
2034-
UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) &&
2035-
Z_OBJ_HT_P(z)->get_method != NULL) {
2036-
if (IS_CONST == IS_TMP_VAR) {
2037-
INIT_PZVAL(z);
2038-
}
2039-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
2040-
zend_print_variable(&z_copy);
2041-
zval_dtor(&z_copy);
2042-
} else {
2043-
zend_print_variable(z);
2044-
}
2045-
} else {
2046-
zend_print_variable(z);
2032+
if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
2033+
INIT_PZVAL(z);
20472034
}
2035+
zend_print_variable(z);
20482036

20492037
CHECK_EXCEPTION();
20502038
ZEND_VM_NEXT_OPCODE();
@@ -6443,27 +6431,15 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
64436431
{
64446432
USE_OPLINE
64456433
zend_free_op free_op1;
6446-
zval z_copy;
64476434
zval *z;
64486435

64496436
SAVE_OPLINE();
64506437
z = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
64516438

6452-
if (IS_TMP_VAR != IS_CONST &&
6453-
UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) &&
6454-
Z_OBJ_HT_P(z)->get_method != NULL) {
6455-
if (IS_TMP_VAR == IS_TMP_VAR) {
6456-
INIT_PZVAL(z);
6457-
}
6458-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
6459-
zend_print_variable(&z_copy);
6460-
zval_dtor(&z_copy);
6461-
} else {
6462-
zend_print_variable(z);
6463-
}
6464-
} else {
6465-
zend_print_variable(z);
6439+
if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
6440+
INIT_PZVAL(z);
64666441
}
6442+
zend_print_variable(z);
64676443

64686444
zval_dtor(free_op1.var);
64696445
CHECK_EXCEPTION();
@@ -10761,27 +10737,15 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
1076110737
{
1076210738
USE_OPLINE
1076310739
zend_free_op free_op1;
10764-
zval z_copy;
1076510740
zval *z;
1076610741

1076710742
SAVE_OPLINE();
1076810743
z = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
1076910744

10770-
if (IS_VAR != IS_CONST &&
10771-
UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) &&
10772-
Z_OBJ_HT_P(z)->get_method != NULL) {
10773-
if (IS_VAR == IS_TMP_VAR) {
10774-
INIT_PZVAL(z);
10775-
}
10776-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
10777-
zend_print_variable(&z_copy);
10778-
zval_dtor(&z_copy);
10779-
} else {
10780-
zend_print_variable(z);
10781-
}
10782-
} else {
10783-
zend_print_variable(z);
10745+
if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
10746+
INIT_PZVAL(z);
1078410747
}
10748+
zend_print_variable(z);
1078510749

1078610750
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
1078710751
CHECK_EXCEPTION();
@@ -26741,27 +26705,15 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
2674126705
{
2674226706
USE_OPLINE
2674326707

26744-
zval z_copy;
2674526708
zval *z;
2674626709

2674726710
SAVE_OPLINE();
2674826711
z = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
2674926712

26750-
if (IS_CV != IS_CONST &&
26751-
UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) &&
26752-
Z_OBJ_HT_P(z)->get_method != NULL) {
26753-
if (IS_CV == IS_TMP_VAR) {
26754-
INIT_PZVAL(z);
26755-
}
26756-
if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
26757-
zend_print_variable(&z_copy);
26758-
zval_dtor(&z_copy);
26759-
} else {
26760-
zend_print_variable(z);
26761-
}
26762-
} else {
26763-
zend_print_variable(z);
26713+
if (IS_CV == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
26714+
INIT_PZVAL(z);
2676426715
}
26716+
zend_print_variable(z);
2676526717

2676626718
CHECK_EXCEPTION();
2676726719
ZEND_VM_NEXT_OPCODE();

ext/spl/spl_directory.c

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

18761876
if (type == IS_STRING) {
1877+
if (Z_OBJCE_P(readobj)->__tostring) {
1878+
return std_object_handlers.cast_object(readobj, writeobj, type TSRMLS_CC);
1879+
}
1880+
18771881
switch (intern->type) {
18781882
case SPL_FS_INFO:
18791883
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-

ext/standard/html.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,8 +1628,8 @@ PHP_FUNCTION(get_html_translation_table)
16281628
unsigned i, j, k,
16291629
max_i, max_j, max_k;
16301630
/* no mapping to unicode required */
1631-
if (CHARSET_SINGLE_BYTE(charset)) {
1632-
max_i = 1; max_j = 1; max_k = 64;
1631+
if (CHARSET_SINGLE_BYTE(charset)) { /* ISO-8859-1 */
1632+
max_i = 1; max_j = 4; max_k = 64;
16331633
} else {
16341634
max_i = 0x1E; max_j = 64; max_k = 64;
16351635
}

ext/standard/http_fopen_wrapper.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
113113
int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
114114
int follow_location = 1;
115115
php_stream_filter *transfer_encoding = NULL;
116+
int response_code;
116117

117118
tmp_line[0] = '\0';
118119

@@ -657,7 +658,6 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
657658

658659
if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) {
659660
zval *http_response;
660-
int response_code;
661661

662662
if (tmp_line_len > 9) {
663663
response_code = atoi(tmp_line + 9);
@@ -731,7 +731,9 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
731731
http_header_line[http_header_line_length] = '\0';
732732

733733
if (!strncasecmp(http_header_line, "Location: ", 10)) {
734-
if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) {
734+
/* we only care about Location for 300, 301, 302, 303 and 307 */
735+
/* see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 */
736+
if ((response_code >= 300 && response_code < 304 || 307 == response_code) && context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) {
735737
SEPARATE_ZVAL(tmpzval);
736738
convert_to_long_ex(tmpzval);
737739
follow_location = Z_LVAL_PP(tmpzval);

0 commit comments

Comments
 (0)