Skip to content

Commit 116cc56

Browse files
committed
Before when unpacking a class if the container already had properties (keys came before classname in the payload) we would stomp on the keys. This would cause memory leaks and loss of data, now when initalizing the new class preserve those properties
1 parent 484102d commit 116cc56

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

msgpack_unpack.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,11 @@ static zend_class_entry* msgpack_unserialize_class(zval **container, zend_string
178178
zend_class_entry *ce;
179179
int func_call_status;
180180
zend_bool incomplete_class = 0;
181-
zval user_func, retval, args[1], *container_val;
181+
zval user_func, retval, args[1], *container_val, container_tmp, *val;
182+
zend_string *str_key;
182183

183184
container_val = Z_ISREF_P(*container) ? Z_REFVAL_P(*container) : *container;
185+
ZVAL_UNDEF(&container_tmp);
184186

185187
do {
186188
/* Try to find class directly */
@@ -229,7 +231,22 @@ static zend_class_entry* msgpack_unserialize_class(zval **container, zend_string
229231
}
230232

231233
if (init_class || incomplete_class) {
234+
if (Z_TYPE_P(container_val) == IS_ARRAY) {
235+
ZVAL_COPY_VALUE(&container_tmp, container_val);
236+
}
232237
object_init_ex(container_val, ce);
238+
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;
243+
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();
247+
zval_dtor(&container_tmp);
248+
}
249+
233250
}
234251

235252
/* store incomplete class name */

0 commit comments

Comments
 (0)