@@ -771,113 +771,80 @@ static int php_var_serialize_call_magic_serialize(zval *retval, zval *obj) /* {{
771
771
}
772
772
/* }}} */
773
773
774
- static void php_var_serialize_collect_names (HashTable * ht , HashTable * src ) /* {{{ */
774
+ static int php_var_serialize_try_add_sleep_prop (
775
+ HashTable * ht , HashTable * props , zend_string * name , zend_string * error_name ) /* {{{ */
775
776
{
776
- zval * val ;
777
- zend_string * name , * tmp_name ;
777
+ zval * val = zend_hash_find (props , name );
778
+ if (val == NULL ) {
779
+ return FAILURE ;
780
+ }
778
781
779
- zend_hash_init (ht , zend_hash_num_elements (src ), NULL , NULL , 0 );
780
- ZEND_HASH_FOREACH_VAL (src , val ) {
781
- ZVAL_DEREF (val );
782
- if (Z_TYPE_P (val ) != IS_STRING ) {
783
- php_error_docref (NULL , E_NOTICE ,
784
- "__sleep should return an array only containing the names of instance-variables to serialize." );
782
+ if (Z_TYPE_P (val ) == IS_INDIRECT ) {
783
+ val = Z_INDIRECT_P (val );
784
+ if (Z_TYPE_P (val ) == IS_UNDEF ) {
785
+ return FAILURE ;
785
786
}
787
+ }
786
788
787
- name = zval_get_tmp_string (val , & tmp_name );
788
- if (zend_hash_exists (ht , name )) {
789
- php_error_docref (NULL , E_NOTICE ,
790
- "\"%s\" is returned from __sleep multiple times" , ZSTR_VAL (name ));
791
- zend_tmp_string_release (tmp_name );
792
- continue ;
793
- }
794
- zend_hash_add_empty_element (ht , name );
795
- zend_tmp_string_release (tmp_name );
796
- } ZEND_HASH_FOREACH_END ();
789
+ if (!zend_hash_add (ht , name , val )) {
790
+ php_error_docref (NULL , E_NOTICE ,
791
+ "\"%s\" is returned from __sleep multiple times" , ZSTR_VAL (error_name ));
792
+ return SUCCESS ;
793
+ }
794
+
795
+ Z_TRY_ADDREF_P (val );
796
+ return SUCCESS ;
797
797
}
798
798
/* }}} */
799
799
800
- static void php_var_serialize_class (smart_str * buf , zval * struc , zval * retval_ptr , php_serialize_data_t var_hash ) /* {{{ */
800
+ static void php_var_serialize_get_sleep_props (
801
+ HashTable * ht , zval * struc , HashTable * sleep_retval ) /* {{{ */
801
802
{
802
803
zend_class_entry * ce = Z_OBJCE_P (struc );
803
- HashTable names , * propers ;
804
- zval nval ;
805
- zend_string * name ;
804
+ HashTable * props = zend_get_properties_for (struc , ZEND_PROP_PURPOSE_SERIALIZE );
805
+ zval * name_val ;
806
806
807
- php_var_serialize_class_name (buf , struc );
808
- php_var_serialize_collect_names (& names , HASH_OF (retval_ptr ));
807
+ zend_hash_init (ht , zend_hash_num_elements (sleep_retval ), NULL , ZVAL_PTR_DTOR , 0 );
808
+ ZEND_HASH_FOREACH_VAL (sleep_retval , name_val ) {
809
+ zend_string * name , * tmp_name , * priv_name , * prot_name ;
809
810
810
- smart_str_append_unsigned (buf , zend_hash_num_elements (& names ));
811
- smart_str_appendl (buf , ":{" , 2 );
812
-
813
- ZVAL_NULL (& nval );
814
- propers = zend_get_properties_for (struc , ZEND_PROP_PURPOSE_SERIALIZE );
815
-
816
- ZEND_HASH_FOREACH_STR_KEY (& names , name ) {
817
- zend_string * prot_name , * priv_name ;
818
-
819
- zval * val = zend_hash_find_ex (propers , name , 1 );
820
- if (val != NULL ) {
821
- if (Z_TYPE_P (val ) == IS_INDIRECT ) {
822
- val = Z_INDIRECT_P (val );
823
- if (Z_TYPE_P (val ) == IS_UNDEF ) {
824
- goto undef_prop ;
825
- }
826
- }
811
+ ZVAL_DEREF (name_val );
812
+ if (Z_TYPE_P (name_val ) != IS_STRING ) {
813
+ php_error_docref (NULL , E_NOTICE ,
814
+ "__sleep should return an array only containing the names of instance-variables to serialize." );
815
+ }
827
816
828
- php_var_serialize_string (buf , ZSTR_VAL (name ), ZSTR_LEN (name ));
829
- php_var_serialize_intern (buf , val , var_hash );
817
+ name = zval_get_tmp_string (name_val , & tmp_name );
818
+ if (php_var_serialize_try_add_sleep_prop (ht , props , name , name ) == SUCCESS ) {
819
+ zend_tmp_string_release (tmp_name );
830
820
continue ;
831
821
}
832
822
833
823
priv_name = zend_mangle_property_name (
834
- ZSTR_VAL (ce -> name ), ZSTR_LEN (ce -> name ), ZSTR_VAL (name ), ZSTR_LEN (name ), 0 );
835
- val = zend_hash_find (propers , priv_name );
836
- if (val != NULL ) {
837
- if (Z_TYPE_P (val ) == IS_INDIRECT ) {
838
- val = Z_INDIRECT_P (val );
839
- if (Z_ISUNDEF_P (val )) {
840
- zend_string_free (priv_name );
841
- goto undef_prop ;
842
- }
843
- }
844
-
845
- php_var_serialize_string (buf , ZSTR_VAL (priv_name ), ZSTR_LEN (priv_name ));
846
- zend_string_free (priv_name );
847
- php_var_serialize_intern (buf , val , var_hash );
824
+ ZSTR_VAL (ce -> name ), ZSTR_LEN (ce -> name ),
825
+ ZSTR_VAL (name ), ZSTR_LEN (name ), ce -> type & ZEND_INTERNAL_CLASS );
826
+ if (php_var_serialize_try_add_sleep_prop (ht , props , priv_name , name ) == SUCCESS ) {
827
+ zend_tmp_string_release (tmp_name );
828
+ zend_string_release (priv_name );
848
829
continue ;
849
830
}
850
- zend_string_free (priv_name );
831
+ zend_string_release (priv_name );
851
832
852
833
prot_name = zend_mangle_property_name (
853
- "*" , 1 , ZSTR_VAL (name ), ZSTR_LEN (name ), 0 );
854
- val = zend_hash_find (propers , prot_name );
855
- if (val != NULL ) {
856
- if (Z_TYPE_P (val ) == IS_INDIRECT ) {
857
- val = Z_INDIRECT_P (val );
858
- if (Z_TYPE_P (val ) == IS_UNDEF ) {
859
- zend_string_free (prot_name );
860
- goto undef_prop ;
861
- }
862
- }
863
-
864
- php_var_serialize_string (buf , ZSTR_VAL (prot_name ), ZSTR_LEN (prot_name ));
865
- zend_string_free (prot_name );
866
- php_var_serialize_intern (buf , val , var_hash );
834
+ "*" , 1 , ZSTR_VAL (name ), ZSTR_LEN (name ), ce -> type & ZEND_INTERNAL_CLASS );
835
+ if (php_var_serialize_try_add_sleep_prop (ht , props , prot_name , name ) == SUCCESS ) {
836
+ zend_tmp_string_release (tmp_name );
837
+ zend_string_release (prot_name );
867
838
continue ;
868
839
}
869
- zend_string_free (prot_name );
840
+ zend_string_release (prot_name );
870
841
871
- undef_prop :
872
- php_var_serialize_string (buf , ZSTR_VAL (name ), ZSTR_LEN (name ));
873
- php_var_serialize_intern (buf , & nval , var_hash );
874
842
php_error_docref (NULL , E_NOTICE ,
875
- "\"%s\" returned as member variable from __sleep() but does not exist" , ZSTR_VAL (name ));
843
+ "\"%s\" returned as member variable from __sleep() but does not exist" , ZSTR_VAL (name ));
844
+ zend_hash_add (ht , name , & EG (uninitialized_zval ));
845
+ zend_tmp_string_release (tmp_name );
876
846
} ZEND_HASH_FOREACH_END ();
877
- smart_str_appendc (buf , '}' );
878
-
879
- zend_hash_destroy (& names );
880
- zend_release_properties (propers );
847
+ zend_release_properties (props );
881
848
}
882
849
/* }}} */
883
850
@@ -930,6 +897,17 @@ static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable
930
897
}
931
898
/* }}} */
932
899
900
+ static void php_var_serialize_class (smart_str * buf , zval * struc , zval * retval_ptr , php_serialize_data_t var_hash ) /* {{{ */
901
+ {
902
+ HashTable props ;
903
+ php_var_serialize_get_sleep_props (& props , struc , HASH_OF (retval_ptr ));
904
+ php_var_serialize_class_name (buf , struc );
905
+ php_var_serialize_nested_data (
906
+ buf , struc , & props , zend_hash_num_elements (& props ), /* incomplete_class */ 0 , var_hash );
907
+ zend_hash_destroy (& props );
908
+ }
909
+ /* }}} */
910
+
933
911
static void php_var_serialize_intern (smart_str * buf , zval * struc , php_serialize_data_t var_hash ) /* {{{ */
934
912
{
935
913
zend_long var_already ;
0 commit comments