@@ -105,7 +105,7 @@ static void spl_fixedarray_init_elems(spl_fixedarray *array, zend_long from, zen
105105static void spl_fixedarray_init_non_empty_struct (spl_fixedarray * array , zend_long size )
106106{
107107 array -> size = 0 ; /* reset size in case ecalloc() fails */
108- array -> elements = safe_emalloc (size , sizeof (zval ), 0 );
108+ array -> elements = size ? safe_emalloc (size , sizeof (zval ), 0 ) : NULL ;
109109 array -> size = size ;
110110 array -> should_rebuild_properties = true;
111111}
@@ -590,61 +590,64 @@ PHP_METHOD(SplFixedArray, __wakeup)
590590PHP_METHOD (SplFixedArray , __serialize )
591591{
592592 spl_fixedarray_object * intern = Z_SPLFIXEDARRAY_P (ZEND_THIS );
593- zval * current , tmp ;
593+ zval * current ;
594+ zend_string * key ;
594595
595596 if (zend_parse_parameters_none () == FAILURE ) {
596597 RETURN_THROWS ();
597598 }
598599
599- array_init (return_value );
600+ uint32_t property_num = zend_hash_num_elements (intern -> std .properties );
601+ array_init_size (return_value , intern -> array .size + property_num );
600602
601603 /* elements */
602- array_init_size (& tmp , intern -> array .size );
603-
604604 for (zend_long i = 0 ; i < intern -> array .size ; i ++ ) {
605605 current = & intern -> array .elements [i ];
606- zend_hash_next_index_insert (Z_ARRVAL ( tmp ), current );
606+ zend_hash_next_index_insert (Z_ARRVAL_P ( return_value ), current );
607607 Z_TRY_ADDREF_P (current );
608608 }
609609
610- zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & tmp );
611-
612610 /* members */
613- ZVAL_ARR (& tmp , zend_proptable_to_symtable (
614- zend_std_get_properties (& intern -> std ), /* always_duplicate */ 1 ));
615- zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & tmp );
611+ ZEND_HASH_FOREACH_STR_KEY_VAL (intern -> std .properties , key , current ) {
612+ zend_hash_str_add (Z_ARRVAL_P (return_value ), ZSTR_VAL (key ), ZSTR_LEN (key ), current );
613+ Z_TRY_ADDREF_P (current );
614+ } ZEND_HASH_FOREACH_END ();
616615}
617616
618617PHP_METHOD (SplFixedArray , __unserialize )
619618{
620619 spl_fixedarray_object * intern = Z_SPLFIXEDARRAY_P (ZEND_THIS );
621620 HashTable * data ;
622- zval * storage_zv , * members_zv , * elem ;
621+ zval members_zv , * elem ;
622+ zend_string * key ;
623+ zend_long idx , size , array_size ;
623624
624625 if (zend_parse_parameters (ZEND_NUM_ARGS (), "h" , & data ) == FAILURE ) {
625626 RETURN_THROWS ();
626627 }
627628
628629 if (intern -> array .size == 0 ) {
629- storage_zv = zend_hash_index_find (data , 0 );
630- members_zv = zend_hash_index_find (data , 1 );
631- if (!storage_zv || !members_zv ||
632- Z_TYPE_P (storage_zv ) != IS_ARRAY || Z_TYPE_P (members_zv ) != IS_ARRAY
633- ) {
634- zend_throw_exception (spl_ce_UnexpectedValueException ,
635- "Incomplete or ill-typed serialization data" , 0 );
636- RETURN_THROWS ();
637- }
638-
639- zend_long size = zend_hash_num_elements (Z_ARRVAL_P (storage_zv ));
630+ size = zend_hash_num_elements (data );
640631 spl_fixedarray_init_non_empty_struct (& intern -> array , size );
641-
642- zend_long i = 0 ;
643- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (storage_zv ), elem ) {
644- ZVAL_COPY (& intern -> array .elements [i ++ ], elem );
632+ array_init (& members_zv );
633+
634+ array_size = 0 ;
635+ ZEND_HASH_FOREACH_KEY_VAL (data , idx , key , elem ) {
636+ if (key == NULL ) {
637+ ZVAL_COPY (& intern -> array .elements [idx ], elem );
638+ array_size ++ ;
639+ } else {
640+ zval tmp ;
641+ ZVAL_COPY (& tmp , elem );
642+ zend_hash_add (Z_ARRVAL (members_zv ), key , & tmp );
643+ }
645644 } ZEND_HASH_FOREACH_END ();
646645
647- object_properties_load (& intern -> std , Z_ARRVAL_P (members_zv ));
646+ intern -> array .elements = erealloc (intern -> array .elements , sizeof (zval ) * array_size );
647+ intern -> array .size = array_size ;
648+
649+ object_properties_load (& intern -> std , Z_ARRVAL (members_zv ));
650+ zval_ptr_dtor (& members_zv );
648651 }
649652}
650653
0 commit comments