Skip to content

Commit 18dbdf2

Browse files
committed
Fixed memleaks
1 parent 7f9723b commit 18dbdf2

File tree

1 file changed

+55
-33
lines changed

1 file changed

+55
-33
lines changed

msgpack_unpack.c

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,28 @@ typedef struct {
2929
*obj = msgpack_var_push(_unpack->var_hash); \
3030
}
3131

32-
#define MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, op1, op2) \
33-
msgpack_stack_pop(_unpack->var_hash, op1, op2); \
32+
#define MSGPACK_UNSERIALIZE_DEC_DEP(_unpack) \
3433
_unpack->stack[_unpack->deps-1]--; \
3534
if (_unpack->stack[_unpack->deps-1] <= 0) { \
3635
_unpack->deps--; \
3736
}
3837

38+
#define MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, _v1, _v2) \
39+
if ((_v2) && MSGPACK_IS_STACK_VALUE((_v2))) { \
40+
msgpack_stack_pop(_unpack->var_hash, (_v2)); \
41+
} \
42+
if ((_v1) && MSGPACK_IS_STACK_VALUE((_v1))) { \
43+
msgpack_stack_pop(_unpack->var_hash, (_v1)); \
44+
} \
45+
MSGPACK_UNSERIALIZE_DEC_DEP(_unpack);
46+
3947
#define MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(_unpack, _key, _val) \
4048
zval_ptr_dtor(_key); \
4149
zval_ptr_dtor(_val); \
4250
MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, _key, _val);
4351

52+
#define MSGPACK_IS_STACK_VALUE(_v) (Z_TYPE_P((_v)) < IS_ARRAY)
53+
4454
static zval *msgpack_var_push(msgpack_unserialize_data_t *var_hashx) /* {{{ */ {
4555
var_entries *var_hash, *prev = NULL;
4656

@@ -71,6 +81,13 @@ static zval *msgpack_var_push(msgpack_unserialize_data_t *var_hashx) /* {{{ */ {
7181
}
7282
/* }}} */
7383

84+
static inline void msgpack_var_replace(zval *old, zval *new) /* {{{ */ {
85+
if (!MSGPACK_IS_STACK_VALUE(old)) {
86+
ZVAL_INDIRECT(old, new);
87+
}
88+
}
89+
/* }}} */
90+
7491
static zval *msgpack_var_access(msgpack_unserialize_data_t *var_hashx, long id) /* {{{ */ {
7592
var_entries *var_hash = var_hashx->first;
7693

@@ -84,7 +101,11 @@ static zval *msgpack_var_access(msgpack_unserialize_data_t *var_hashx, long id)
84101
}
85102

86103
if (id > 0 && id < var_hash->used_slots) {
87-
return &var_hash->data[id - 1];
104+
zval *zv = &var_hash->data[id - 1];
105+
if (UNEXPECTED(Z_TYPE_P(zv) == IS_INDIRECT)) {
106+
zv = Z_INDIRECT_P(zv);
107+
}
108+
return zv;
88109
}
89110

90111
return NULL;
@@ -121,8 +142,7 @@ static zval *msgpack_stack_push(msgpack_unserialize_data_t *var_hashx) /* {{{ */
121142
}
122143
/* }}} */
123144

124-
static void msgpack_stack_pop(msgpack_unserialize_data_t *var_hashx, zval *op1, zval *op2) /* {{{ */ {
125-
int32_t i;
145+
static void msgpack_stack_pop(msgpack_unserialize_data_t *var_hashx, zval *v) /* {{{ */ {
126146
var_entries *var_hash = var_hashx->first_dtor;
127147

128148
while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
@@ -133,20 +153,10 @@ static void msgpack_stack_pop(msgpack_unserialize_data_t *var_hashx, zval *op1,
133153
return;
134154
}
135155

136-
if (op2 && Z_TYPE_P(op2) < IS_ARRAY) {
137-
ZEND_ASSERT((&(var_hash->data[var_hash->used_slots -1]) == op2));
138-
if ((&(var_hash->data[var_hash->used_slots -1]) == op2)) {
139-
var_hash->used_slots--;
140-
ZVAL_UNDEF(op2);
141-
}
142-
}
143-
144-
if (op1 && Z_TYPE_P(op1) < IS_ARRAY) {
145-
ZEND_ASSERT((&(var_hash->data[var_hash->used_slots -1]) == op1));
146-
if (&(var_hash->data[var_hash->used_slots -1]) == op1) {
147-
var_hash->used_slots--;
148-
ZVAL_UNDEF(op1);
149-
}
156+
ZEND_ASSERT((&(var_hash->data[var_hash->used_slots -1]) == v));
157+
if ((&(var_hash->data[var_hash->used_slots -1]) == v)) {
158+
var_hash->used_slots--;
159+
ZVAL_UNDEF(v);
150160
}
151161

152162
/*
@@ -245,7 +255,7 @@ void msgpack_unserialize_var_destroy(msgpack_unserialize_data_t *var_hashx, zend
245255
while (var_hash) {
246256
if (err) {
247257
for (i = var_hash->used_slots; i > 0; i--) {
248-
/* TODO: memleaks ? zval_ptr_dtor(&var_hash->data[i - 1]); */
258+
zval_ptr_dtor(&var_hash->data[i - 1]);
249259
}
250260
}
251261
next = var_hash->next;
@@ -415,9 +425,14 @@ int msgpack_unserialize_array(msgpack_unserialize_data *unpack, unsigned int cou
415425
/* }}} */
416426

417427
int msgpack_unserialize_array_item(msgpack_unserialize_data *unpack, zval **container, zval *obj) /* {{{ */ {
418-
add_next_index_zval(*container, obj);
428+
zval *nval = zend_hash_next_index_insert(Z_ARRVAL_P(*container), obj);
419429

420-
MSGPACK_UNSERIALIZE_FINISH_ITEM(unpack, obj, NULL);
430+
if (MSGPACK_IS_STACK_VALUE(obj)) {
431+
MSGPACK_UNSERIALIZE_FINISH_ITEM(unpack, obj, NULL);
432+
} else {
433+
msgpack_var_replace(obj, nval);
434+
MSGPACK_UNSERIALIZE_DEC_DEP(unpack);
435+
}
421436

422437
return 0;
423438
}
@@ -448,6 +463,7 @@ int msgpack_unserialize_map(msgpack_unserialize_data *unpack, unsigned int count
448463

449464
int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **container, zval *key, zval *val) /* {{{ */ {
450465
long deps;
466+
zval *nval;
451467
zval *container_val;
452468

453469
if (MSGPACK_G(php_only)) {
@@ -554,7 +570,7 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
554570
if (Z_TYPE_P(container_val) == IS_OBJECT) {
555571
switch (Z_TYPE_P(key)) {
556572
case IS_LONG:
557-
if (zend_hash_index_update(Z_OBJPROP_P(container_val), Z_LVAL_P(key), val) == NULL) {
573+
if ((nval = zend_hash_index_update(Z_OBJPROP_P(container_val), Z_LVAL_P(key), val)) == NULL) {
558574
zval_ptr_dtor(val);
559575
MSGPACK_WARNING(
560576
"[msgpack] (%s) illegal offset type, skip this decoding",
@@ -568,11 +584,12 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
568584

569585
zend_unmangle_property_name_ex(Z_STR_P(key), &class_name, &prop_name, &prop_len);
570586
zend_update_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, val);
587+
nval = zend_read_property(Z_OBJCE_P(container_val), container_val, prop_name, prop_len, 0, NULL);
571588

572589
zval_ptr_dtor(key);
573590
zval_ptr_dtor(val);
574591
} else {
575-
if (zend_symtable_update(Z_OBJPROP_P(container_val), Z_STR_P(key), val) == NULL) {
592+
if ((nval = zend_symtable_update(Z_OBJPROP_P(container_val), Z_STR_P(key), val)) == NULL) {
576593
zval_ptr_dtor(val);
577594
MSGPACK_WARNING(
578595
"[msgpack] (%s) illegal offset type, skip this decoding",
@@ -585,15 +602,15 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
585602
MSGPACK_WARNING("[msgpack] (%s) illegal key type", __FUNCTION__);
586603

587604
if (MSGPACK_G(illegal_key_insert)) {
588-
if ((zend_hash_next_index_insert(Z_OBJPROP_P(container_val), key)) == NULL) {
605+
if ((nval = zend_hash_next_index_insert(Z_OBJPROP_P(container_val), key)) == NULL) {
589606
zval_ptr_dtor(key);
590607
}
591-
if ((zend_hash_next_index_insert(Z_OBJPROP_P(container_val), val)) == NULL) {
608+
if ((nval = zend_hash_next_index_insert(Z_OBJPROP_P(container_val), val)) == NULL) {
592609
zval_ptr_dtor(val);
593610
}
594611
} else {
595612
zend_string *skey = zval_get_string(key);
596-
if ((zend_symtable_update(Z_OBJPROP_P(container_val), skey, val)) == NULL) {
613+
if ((nval = zend_symtable_update(Z_OBJPROP_P(container_val), skey, val)) == NULL) {
597614
zval_ptr_dtor(val);
598615
}
599616
zend_string_release(skey);
@@ -606,15 +623,15 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
606623
}
607624
switch (Z_TYPE_P(key)) {
608625
case IS_LONG:
609-
if (zend_hash_index_update(Z_ARRVAL_P(container_val), Z_LVAL_P(key), val) == NULL) {
626+
if ((nval = zend_hash_index_update(Z_ARRVAL_P(container_val), Z_LVAL_P(key), val)) == NULL) {
610627
zval_ptr_dtor(val);
611628
MSGPACK_WARNING(
612629
"[msgpack] (%s) illegal offset type, skip this decoding",
613630
__FUNCTION__);
614631
}
615632
break;
616633
case IS_STRING:
617-
if (zend_symtable_update(Z_ARRVAL_P(container_val), Z_STR_P(key), val) == NULL) {
634+
if ((nval = zend_symtable_update(Z_ARRVAL_P(container_val), Z_STR_P(key), val)) == NULL) {
618635
zval_ptr_dtor(val);
619636
MSGPACK_WARNING(
620637
"[msgpack] (%s) illegal offset type, skip this decoding",
@@ -626,15 +643,15 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
626643
MSGPACK_WARNING("[msgpack] (%s) illegal key type", __FUNCTION__);
627644

628645
if (MSGPACK_G(illegal_key_insert)) {
629-
if (zend_hash_next_index_insert(Z_ARRVAL_P(container_val), key) == NULL) {
646+
if ((nval = zend_hash_next_index_insert(Z_ARRVAL_P(container_val), key)) == NULL) {
630647
zval_ptr_dtor(key);
631648
}
632-
if (zend_hash_next_index_insert(Z_ARRVAL_P(container_val), val) == NULL) {
649+
if ((nval = zend_hash_next_index_insert(Z_ARRVAL_P(container_val), val)) == NULL) {
633650
zval_ptr_dtor(val);
634651
}
635652
} else {
636653
zend_string *skey = zval_get_string(key);
637-
if ((zend_symtable_update(Z_ARRVAL_P(container_val), skey, val)) == NULL) {
654+
if ((nval = zend_symtable_update(Z_ARRVAL_P(container_val), skey, val)) == NULL) {
638655
zval_ptr_dtor(val);
639656
}
640657
zend_string_release(skey);
@@ -643,7 +660,12 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
643660
}
644661
}
645662

646-
msgpack_stack_pop(unpack->var_hash, key, val);
663+
if (MSGPACK_IS_STACK_VALUE(val)) {
664+
msgpack_stack_pop(unpack->var_hash, val);
665+
} else {
666+
msgpack_var_replace(val, nval);
667+
}
668+
msgpack_stack_pop(unpack->var_hash, key);
647669

648670
deps = unpack->deps - 1;
649671
unpack->stack[deps]--;

0 commit comments

Comments
 (0)