@@ -771,113 +771,80 @@ static int php_var_serialize_call_magic_serialize(zval *retval, zval *obj) /* {{
771771}
772772/* }}} */
773773
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 ) /* {{{ */
775776{
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+ }
778781
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 ;
785786 }
787+ }
786788
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 ;
797797}
798798/* }}} */
799799
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 ) /* {{{ */
801802{
802803 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 ;
806806
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 ;
809810
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+ }
827816
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 );
830820 continue ;
831821 }
832822
833823 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 );
848829 continue ;
849830 }
850- zend_string_free (priv_name );
831+ zend_string_release (priv_name );
851832
852833 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 );
867838 continue ;
868839 }
869- zend_string_free (prot_name );
840+ zend_string_release (prot_name );
870841
871- undef_prop :
872- php_var_serialize_string (buf , ZSTR_VAL (name ), ZSTR_LEN (name ));
873- php_var_serialize_intern (buf , & nval , var_hash );
874842 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 );
876846 } 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 );
881848}
882849/* }}} */
883850
@@ -930,6 +897,17 @@ static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable
930897}
931898/* }}} */
932899
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+
933911static void php_var_serialize_intern (smart_str * buf , zval * struc , php_serialize_data_t var_hash ) /* {{{ */
934912{
935913 zend_long var_already ;
0 commit comments