Skip to content

Commit e0f2819

Browse files
committed
When packing/unpacking a zend_object don't call magic methods __set/__get
1 parent 034ddac commit e0f2819

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

msgpack_unpack.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ typedef struct {
4949
zval_ptr_dtor(_val); \
5050
MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, _key, _val);
5151

52+
#define UNSET_MAGIC_METHODS(_ce) \
53+
__get = _ce->__get; \
54+
_ce->__get = NULL; \
55+
__set = _ce->__set; \
56+
_ce->__set = NULL; \
57+
58+
#define RESET_MAGIC_METHODS(_ce) \
59+
ce->__set = __set; \
60+
ce->__get = __get; \
61+
5262
#define MSGPACK_IS_STACK_VALUE(_v) (Z_TYPE_P((zval *)(_v)) < IS_ARRAY)
5363

5464
static zval *msgpack_var_push(msgpack_unserialize_data_t *var_hashx) /* {{{ */ {
@@ -236,14 +246,19 @@ static zend_class_entry* msgpack_unserialize_class(zval **container, zend_string
236246
}
237247
object_init_ex(container_val, ce);
238248

239-
if (Z_TYPE(container_tmp) != IS_UNDEF) {
240-
ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(&container_tmp), str_key, val) {
241-
const char *class_name, *prop_name;
242-
size_t prop_len;
249+
if (Z_TYPE(container_tmp) != IS_UNDEF) {
250+
ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(&container_tmp), str_key, val) {
251+
const char *class_name, *prop_name;
252+
size_t prop_len;
253+
zend_class_entry *ce = Z_OBJCE_P(container_val);
254+
zend_function *__set, *__get;
255+
256+
UNSET_MAGIC_METHODS(ce);
257+
zend_unmangle_property_name_ex(str_key, &class_name, &prop_name, &prop_len);
258+
zend_update_property(ce, container_val, prop_name, prop_len, val);
259+
RESET_MAGIC_METHODS(ce);
243260

244-
zend_unmangle_property_name_ex(str_key, &class_name, &prop_name, &prop_len);
245-
zend_update_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, val);
246-
} ZEND_HASH_FOREACH_END();
261+
} ZEND_HASH_FOREACH_END();
247262
zval_dtor(&container_tmp);
248263
}
249264

@@ -607,11 +622,16 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
607622
case IS_STRING:
608623
if (Z_OBJCE_P(container_val) != PHP_IC_ENTRY) {
609624
const char *class_name, *prop_name;
625+
zend_class_entry *ce = Z_OBJCE_P(container_val);
626+
zval rv;
610627
size_t prop_len;
628+
zend_function *__get, *__set;
611629

630+
UNSET_MAGIC_METHODS(ce);
612631
zend_unmangle_property_name_ex(Z_STR_P(key), &class_name, &prop_name, &prop_len);
613-
zend_update_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, val);
614-
nval = zend_read_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, 0, NULL);
632+
zend_update_property(ce, container_val, prop_name, prop_len, val);
633+
nval = zend_read_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, 1, &rv);
634+
RESET_MAGIC_METHODS(ce);
615635

616636
zval_ptr_dtor(key);
617637
zval_ptr_dtor(val);

tests/bug013.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Bug #13
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("msgpack")) {
6+
echo "skip";
7+
}
8+
--FILE--
9+
<?php
10+
11+
class magicClass {
12+
public function __set($name, $value) {
13+
echo 'Called __set' . PHP_EOL;
14+
$this->$name = $value;
15+
}
16+
public function __get($name) {
17+
echo 'Called __get' . PHP_EOL;
18+
return $this->$name;
19+
}
20+
}
21+
22+
$magicInstance = new \magicClass;
23+
$magicInstance->val = 5;
24+
var_dump($magicInstance);
25+
26+
$packed = msgpack_pack($magicInstance);
27+
var_dump(bin2hex($packed));
28+
$unpacked = msgpack_unpack($packed);
29+
var_dump($unpacked);
30+
31+
?>
32+
--EXPECTF--
33+
Called __set
34+
object(magicClass)#%d (1) {
35+
["val"]=>
36+
int(5)
37+
}
38+
string(36) "82c0aa6d61676963436c617373a376616c05"
39+
object(magicClass)#%d (1) {
40+
["val"]=>
41+
int(5)
42+
}

0 commit comments

Comments
 (0)