Skip to content

Commit

Permalink
When packing/unpacking a zend_object don't call magic methods __set/_…
Browse files Browse the repository at this point in the history
…_get
  • Loading branch information
Sean-Der committed Dec 3, 2015
1 parent 034ddac commit e0f2819
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 9 deletions.
38 changes: 29 additions & 9 deletions msgpack_unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ typedef struct {
zval_ptr_dtor(_val); \
MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, _key, _val);

#define UNSET_MAGIC_METHODS(_ce) \
__get = _ce->__get; \
_ce->__get = NULL; \
__set = _ce->__set; \
_ce->__set = NULL; \

#define RESET_MAGIC_METHODS(_ce) \
ce->__set = __set; \
ce->__get = __get; \

#define MSGPACK_IS_STACK_VALUE(_v) (Z_TYPE_P((zval *)(_v)) < IS_ARRAY)

static zval *msgpack_var_push(msgpack_unserialize_data_t *var_hashx) /* {{{ */ {
Expand Down Expand Up @@ -236,14 +246,19 @@ static zend_class_entry* msgpack_unserialize_class(zval **container, zend_string
}
object_init_ex(container_val, ce);

if (Z_TYPE(container_tmp) != IS_UNDEF) {
ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(&container_tmp), str_key, val) {
const char *class_name, *prop_name;
size_t prop_len;
if (Z_TYPE(container_tmp) != IS_UNDEF) {
ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(&container_tmp), str_key, val) {
const char *class_name, *prop_name;
size_t prop_len;
zend_class_entry *ce = Z_OBJCE_P(container_val);
zend_function *__set, *__get;

UNSET_MAGIC_METHODS(ce);
zend_unmangle_property_name_ex(str_key, &class_name, &prop_name, &prop_len);
zend_update_property(ce, container_val, prop_name, prop_len, val);
RESET_MAGIC_METHODS(ce);

zend_unmangle_property_name_ex(str_key, &class_name, &prop_name, &prop_len);
zend_update_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, val);
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FOREACH_END();
zval_dtor(&container_tmp);
}

Expand Down Expand Up @@ -607,11 +622,16 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
case IS_STRING:
if (Z_OBJCE_P(container_val) != PHP_IC_ENTRY) {
const char *class_name, *prop_name;
zend_class_entry *ce = Z_OBJCE_P(container_val);
zval rv;
size_t prop_len;
zend_function *__get, *__set;

UNSET_MAGIC_METHODS(ce);
zend_unmangle_property_name_ex(Z_STR_P(key), &class_name, &prop_name, &prop_len);
zend_update_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, val);
nval = zend_read_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, 0, NULL);
zend_update_property(ce, container_val, prop_name, prop_len, val);
nval = zend_read_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, 1, &rv);
RESET_MAGIC_METHODS(ce);

zval_ptr_dtor(key);
zval_ptr_dtor(val);
Expand Down
42 changes: 42 additions & 0 deletions tests/bug013.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
Bug #13
--SKIPIF--
<?php
if (!extension_loaded("msgpack")) {
echo "skip";
}
--FILE--
<?php

class magicClass {
public function __set($name, $value) {
echo 'Called __set' . PHP_EOL;
$this->$name = $value;
}
public function __get($name) {
echo 'Called __get' . PHP_EOL;
return $this->$name;
}
}

$magicInstance = new \magicClass;
$magicInstance->val = 5;
var_dump($magicInstance);

$packed = msgpack_pack($magicInstance);
var_dump(bin2hex($packed));
$unpacked = msgpack_unpack($packed);
var_dump($unpacked);

?>
--EXPECTF--
Called __set
object(magicClass)#%d (1) {
["val"]=>
int(5)
}
string(36) "82c0aa6d61676963436c617373a376616c05"
object(magicClass)#%d (1) {
["val"]=>
int(5)
}

0 comments on commit e0f2819

Please sign in to comment.