@@ -197,6 +197,59 @@ static void msgpack_stack_pop(msgpack_unserialize_data_t *var_hashx, zval *v) /*
197197}
198198/* }}} */
199199
200+ static inline zval * update_property (const zend_class_entry * ce , HashTable * props , zend_string * mangled , zval * val ) {
201+ const char * class_name , * prop_name ;
202+ size_t prop_len ;
203+ zval * new_val ;
204+ zend_string * unmangled , * new_key ;
205+ zend_property_info * existing_propinfo ;
206+
207+ if (SUCCESS != zend_unmangle_property_name_ex (mangled , & class_name , & prop_name , & prop_len )) {
208+ return NULL ;
209+ }
210+
211+ unmangled = zend_string_init (prop_name , prop_len , 0 );
212+ existing_propinfo = zend_hash_find_ptr (& ce -> properties_info , unmangled );
213+
214+ if ((class_name == NULL || !strcmp (class_name , "*" ) || !strcasecmp (class_name , ZSTR_VAL (ce -> name )))
215+ && (existing_propinfo != NULL )
216+ && (existing_propinfo -> flags & ZEND_ACC_PPP_MASK )) {
217+ if (existing_propinfo -> flags & ZEND_ACC_PROTECTED ) {
218+ new_key = zend_mangle_property_name (
219+ "*" , 1 , ZSTR_VAL (unmangled ), ZSTR_LEN (unmangled ), 0 );
220+ } else if (existing_propinfo -> flags & ZEND_ACC_PRIVATE ) {
221+ if (class_name != NULL && strcmp (class_name , "*" ) != 0 ) {
222+ new_key = zend_mangle_property_name (
223+ class_name , strlen (class_name ),
224+ ZSTR_VAL (unmangled ), ZSTR_LEN (unmangled ),
225+ 0 );
226+ } else {
227+ new_key = zend_mangle_property_name (
228+ ZSTR_VAL (existing_propinfo -> ce -> name ), ZSTR_LEN (existing_propinfo -> ce -> name ),
229+ ZSTR_VAL (unmangled ), ZSTR_LEN (unmangled ),
230+ 0 );
231+ }
232+ } else {
233+ ZEND_ASSERT (existing_propinfo -> flags & ZEND_ACC_PUBLIC );
234+ new_key = unmangled ;
235+ }
236+ } else {
237+ new_key = mangled ;
238+ }
239+
240+ Z_TRY_ADDREF_P (val );
241+ new_val = zend_hash_update_ind (props , new_key , val );
242+
243+ if (new_key != unmangled ) {
244+ zend_string_release (unmangled );
245+ }
246+ if (new_key != mangled ) {
247+ zend_string_release (new_key );
248+ }
249+
250+ return new_val ;
251+ }
252+
200253static zend_class_entry * msgpack_unserialize_class (zval * * container , zend_string * class_name , zend_bool init_class ) /* {{{ */ {
201254 zend_class_entry * ce ;
202255 int func_call_status ;
@@ -260,22 +313,12 @@ static zend_class_entry* msgpack_unserialize_class(zval **container, zend_string
260313 object_init_ex (container_val , ce );
261314
262315 if (Z_TYPE (container_tmp ) != IS_UNDEF ) {
263- ZEND_HASH_FOREACH_STR_KEY_VAL (HASH_OF (& container_tmp ), str_key , val ) {
264- const char * class_name , * prop_name ;
265- size_t prop_len ;
266- zend_class_entry * ce ;
267- zend_function * __set , * __get ;
268-
269- if (!str_key ) {
270- continue ;
271- }
272- ce = Z_OBJCE_P (container_val );
273- UNSET_MAGIC_METHODS (ce );
274- zend_unmangle_property_name_ex (str_key , & class_name , & prop_name , & prop_len );
275- zend_update_property (ce , container_val , prop_name , prop_len , val );
276- RESET_MAGIC_METHODS (ce );
277-
278- } ZEND_HASH_FOREACH_END ();
316+ HashTable * props = Z_OBJPROP_P (container_val );
317+ ZEND_HASH_FOREACH_STR_KEY_VAL (HASH_OF (& container_tmp ), str_key , val )
318+ {
319+ update_property (ce , props , str_key , val );
320+ }
321+ ZEND_HASH_FOREACH_END ();
279322 zval_dtor (& container_tmp );
280323 }
281324
@@ -491,7 +534,7 @@ int msgpack_unserialize_array_item(msgpack_unserialize_data *unpack, zval **cont
491534 zval * nval ;
492535
493536 if (!* container || Z_TYPE_P (* container ) != IS_ARRAY ) {
494- return -1 ;
537+ return -1 ;
495538 }
496539
497540 nval = zend_hash_next_index_insert (Z_ARRVAL_P (* container ), obj );
@@ -649,18 +692,7 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
649692 break ;
650693 case IS_STRING :
651694 if (Z_OBJCE_P (container_val ) != PHP_IC_ENTRY ) {
652- const char * class_name , * prop_name ;
653- zend_class_entry * ce = Z_OBJCE_P (container_val );
654- zval rv ;
655- size_t prop_len ;
656- zend_function * __get , * __set ;
657-
658- UNSET_MAGIC_METHODS (ce );
659- zend_unmangle_property_name_ex (Z_STR_P (key ), & class_name , & prop_name , & prop_len );
660- zend_update_property (ce , container_val , prop_name , prop_len , val );
661- nval = zend_read_property (Z_OBJCE_P (container_val ), container_val , prop_name , prop_len , 1 , & rv );
662- RESET_MAGIC_METHODS (ce );
663-
695+ nval = update_property (Z_OBJCE_P (container_val ), Z_OBJPROP_P (container_val ), Z_STR_P (key ), val );
664696 zval_ptr_dtor (key );
665697 zval_ptr_dtor (val );
666698 } else {
0 commit comments