Skip to content

Commit cdacda7

Browse files
committed
Merge branch 'PHP-5.5' of https://git.php.net/push/php-src into PHP-5.5
* 'PHP-5.5' of https://git.php.net/push/php-src: Fix tests after laruence unserialize change Fix get_property_ptr_ptr declaration in simplexml Update NEWS Fixed confused exception message while user threw exception Fixed bug #64354 (Unserialize array of objects whose class can't be autoloaded fail) Fix date use NEWS only Fixed bug #61025 (__invoke() visibility not honored)
2 parents 5543035 + 9490118 commit cdacda7

17 files changed

+250
-386
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 20??, PHP 5.5.0 Beta 1
44

5+
- Core:
6+
. Fixed bug #64354 (Unserialize array of objects whose class can't
7+
be autoloaded fail). (Laruence)
8+
59

610
07 Mar 2013, PHP 5.5.0 Alpha 6
711

812
- Core:
13+
. Fixed bug #61025 (__invoke() visibility not honored). (Laruence)
914
. Fixed bug #49348 (Uninitialized ++$foo->bar; does not cause a notice).
1015
(Stas)
1116

NEWS-5.5

Lines changed: 0 additions & 344 deletions
This file was deleted.

Zend/tests/bug61025.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Bug #61025 (__invoke() visibility not honored)
3+
--FILE--
4+
<?php
5+
6+
Interface InvokeAble {
7+
static function __invoke();
8+
}
9+
10+
class Bar {
11+
private function __invoke() {
12+
return __CLASS__;
13+
}
14+
}
15+
16+
$b = new Bar;
17+
echo $b();
18+
19+
echo $b->__invoke();
20+
21+
?>
22+
--EXPECTF--
23+
Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d
24+
25+
Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d
26+
Bar
27+
Fatal error: Call to private method Bar::__invoke() from context '' in %sbug61025.php on line %d

Zend/tests/bug64354.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail)
3+
--FILE--
4+
<?php
5+
class B implements Serializable {
6+
public function serialize() {
7+
throw new Exception("serialize");
8+
return NULL;
9+
}
10+
11+
public function unserialize($data) {
12+
}
13+
}
14+
15+
$data = array(new B);
16+
17+
try {
18+
serialize($data);
19+
} catch (Exception $e) {
20+
var_dump($e->getMessage());
21+
}
22+
?>
23+
--EXPECTF--
24+
string(9) "serialize"

Zend/tests/generators/errors/serialize_unserialize_error.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ Stack trace:
3838
#1 %s(%d): unserialize('O:9:"Generator"...')
3939
#2 {main}
4040

41-
42-
Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d
4341
exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
4442
Stack trace:
4543
#0 %s(%d): unserialize('C:9:"Generator"...')

Zend/zend_closures.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ static zend_object_value zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
291291
}
292292
/* }}} */
293293

294-
295294
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) /* {{{ */
296295
{
297296
zend_closure *closure;

Zend/zend_closures.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
BEGIN_EXTERN_C()
2626

27-
#define ZEND_INVOKE_FUNC_NAME "__invoke"
28-
2927
void zend_register_closure_ce(TSRMLS_D);
3028

3129
extern ZEND_API zend_class_entry *zend_ce_closure;

Zend/zend_compile.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
16211621
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
16221622
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
16231623
}
1624+
} else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
1625+
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
1626+
zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
1627+
}
16241628
}
16251629
} else {
16261630
char *class_lcname;
@@ -1677,6 +1681,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
16771681
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
16781682
}
16791683
CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
1684+
} else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
1685+
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
1686+
zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
1687+
}
16801688
} else if (!(fn_flags & ZEND_ACC_STATIC)) {
16811689
CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
16821690
}

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ END_EXTERN_C()
856856
#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic"
857857
#define ZEND_TOSTRING_FUNC_NAME "__tostring"
858858
#define ZEND_AUTOLOAD_FUNC_NAME "__autoload"
859+
#define ZEND_INVOKE_FUNC_NAME "__invoke"
859860

860861
/* The following constants may be combined in CG(compiler_options)
861862
* to change the default compiler behavior */

Zend/zend_interfaces.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint
452452
zval_ptr_dtor(&retval);
453453
}
454454

455-
if (result == FAILURE) {
455+
if (result == FAILURE && !EG(exception)) {
456456
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
457457
}
458458
return result;

ext/simplexml/simplexml.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_D
694694
}
695695
/* }}} */
696696

697-
static zval** sxe_property_get_adr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
697+
static zval** sxe_property_get_adr(zval *object, zval *member, int fetch_type, const zend_literal *key TSRMLS_DC) /* {{{ */
698698
{
699699
php_sxe_object *sxe;
700700
xmlNodePtr node;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail)
3+
--FILE--
4+
<?php
5+
spl_autoload_register(
6+
function($class) {
7+
throw new Exception("Failed");
8+
}
9+
);
10+
11+
try {
12+
var_dump(unserialize('O:1:"A":0:{}'));
13+
} catch (Exception $e) {
14+
var_dump($e->getMessage());
15+
}
16+
17+
try {
18+
var_dump(unserialize('a:2:{i:0;O:1:"A":0:{}i:1;O:1:"A":0:{}}'));
19+
} catch (Exception $e) {
20+
var_dump($e->getMessage());
21+
}
22+
?>
23+
--EXPECTF--
24+
string(6) "Failed"
25+
string(6) "Failed"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail)
3+
--FILE--
4+
<?php
5+
class A {
6+
public function __wakeup() {
7+
throw new Exception("Failed");
8+
}
9+
}
10+
11+
spl_autoload_register(
12+
function($class) {
13+
throw new Exception("Failed");
14+
}
15+
);
16+
17+
try {
18+
var_dump(unserialize('a:2:{i:0;O:1:"A":0:{}i:1;O:1:"B":0:{}}'));
19+
} catch (Exception $e) {
20+
var_dump($e->getMessage());
21+
}
22+
?>
23+
--EXPECTF--
24+
string(6) "Failed"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail)
3+
--FILE--
4+
<?php
5+
class A {
6+
public function __sleep() {
7+
throw new Exception("Failed");
8+
}
9+
}
10+
11+
class B implements Serializable {
12+
public function serialize() {
13+
return NULL;
14+
}
15+
16+
public function unserialize($data) {
17+
}
18+
}
19+
20+
$data = array(new A, new B);
21+
22+
try {
23+
serialize($data);
24+
} catch (Exception $e) {
25+
var_dump($e->getMessage());
26+
}
27+
?>
28+
--EXPECTF--
29+
string(6) "Failed"

ext/standard/var.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,10 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var
714714
ulong *var_already;
715715
HashTable *myht;
716716

717+
if (EG(exception)) {
718+
return;
719+
}
720+
717721
if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) {
718722
if (Z_ISREF_P(struc)) {
719723
smart_str_appendl(buf, "R:", 2);
@@ -800,8 +804,15 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var
800804
BG(serialize_lock)++;
801805
res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
802806
BG(serialize_lock)--;
807+
808+
if (EG(exception)) {
809+
if (retval_ptr) {
810+
zval_ptr_dtor(&retval_ptr);
811+
}
812+
return;
813+
}
803814

804-
if (res == SUCCESS && !EG(exception)) {
815+
if (res == SUCCESS) {
805816
if (retval_ptr) {
806817
if (HASH_OF(retval_ptr)) {
807818
php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC);
@@ -921,6 +932,11 @@ PHP_FUNCTION(serialize)
921932
php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
922933
PHP_VAR_SERIALIZE_DESTROY(var_hash);
923934

935+
if (EG(exception)) {
936+
smart_str_free(&buf);
937+
RETURN_FALSE;
938+
}
939+
924940
if (buf.c) {
925941
RETURN_STRINGL(buf.c, buf.len, 0);
926942
} else {
@@ -951,7 +967,9 @@ PHP_FUNCTION(unserialize)
951967
if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) {
952968
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
953969
zval_dtor(return_value);
954-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
970+
if (!EG(exception)) {
971+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
972+
}
955973
RETURN_FALSE;
956974
}
957975
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);

0 commit comments

Comments
 (0)