@@ -765,7 +765,7 @@ static int php_var_serialize_call_magic_serialize(zval *retval, zval *obj) /* {{
765
765
/* }}} */
766
766
767
767
static int php_var_serialize_try_add_sleep_prop (
768
- HashTable * ht , HashTable * props , zend_string * name , zend_string * error_name ) /* {{{ */
768
+ HashTable * ht , HashTable * props , zend_string * name , zend_string * error_name , zval * struc ) /* {{{ */
769
769
{
770
770
zval * val = zend_hash_find (props , name );
771
771
if (val == NULL ) {
@@ -775,6 +775,12 @@ static int php_var_serialize_try_add_sleep_prop(
775
775
if (Z_TYPE_P (val ) == IS_INDIRECT ) {
776
776
val = Z_INDIRECT_P (val );
777
777
if (Z_TYPE_P (val ) == IS_UNDEF ) {
778
+ zend_property_info * info = zend_get_typed_property_info_for_slot (Z_OBJ_P (struc ), val );
779
+ if (info ) {
780
+ zend_throw_error (NULL ,
781
+ "Typed property %s::$%s must not be accessed before initialization (in __sleep)" ,
782
+ ZSTR_VAL (Z_OBJCE_P (struc )-> name ), ZSTR_VAL (error_name ));
783
+ }
778
784
return FAILURE ;
779
785
}
780
786
}
@@ -790,14 +796,17 @@ static int php_var_serialize_try_add_sleep_prop(
790
796
}
791
797
/* }}} */
792
798
793
- static void php_var_serialize_get_sleep_props (
799
+ static int php_var_serialize_get_sleep_props (
794
800
HashTable * ht , zval * struc , HashTable * sleep_retval ) /* {{{ */
795
801
{
796
802
zend_class_entry * ce = Z_OBJCE_P (struc );
797
803
HashTable * props = zend_get_properties_for (struc , ZEND_PROP_PURPOSE_SERIALIZE );
798
804
zval * name_val ;
805
+ int retval = SUCCESS ;
799
806
800
807
zend_hash_init (ht , zend_hash_num_elements (sleep_retval ), NULL , ZVAL_PTR_DTOR , 0 );
808
+ /* TODO: Rewrite this by fetching the property info instead of trying out different
809
+ * name manglings? */
801
810
ZEND_HASH_FOREACH_VAL (sleep_retval , name_val ) {
802
811
zend_string * name , * tmp_name , * priv_name , * prot_name ;
803
812
@@ -808,36 +817,56 @@ static void php_var_serialize_get_sleep_props(
808
817
}
809
818
810
819
name = zval_get_tmp_string (name_val , & tmp_name );
811
- if (php_var_serialize_try_add_sleep_prop (ht , props , name , name ) == SUCCESS ) {
820
+ if (php_var_serialize_try_add_sleep_prop (ht , props , name , name , struc ) == SUCCESS ) {
812
821
zend_tmp_string_release (tmp_name );
813
822
continue ;
814
823
}
815
824
825
+ if (EG (exception )) {
826
+ zend_tmp_string_release (tmp_name );
827
+ retval = FAILURE ;
828
+ break ;
829
+ }
830
+
816
831
priv_name = zend_mangle_property_name (
817
832
ZSTR_VAL (ce -> name ), ZSTR_LEN (ce -> name ),
818
833
ZSTR_VAL (name ), ZSTR_LEN (name ), ce -> type & ZEND_INTERNAL_CLASS );
819
- if (php_var_serialize_try_add_sleep_prop (ht , props , priv_name , name ) == SUCCESS ) {
834
+ if (php_var_serialize_try_add_sleep_prop (ht , props , priv_name , name , struc ) == SUCCESS ) {
820
835
zend_tmp_string_release (tmp_name );
821
836
zend_string_release (priv_name );
822
837
continue ;
823
838
}
824
839
zend_string_release (priv_name );
825
840
841
+ if (EG (exception )) {
842
+ zend_tmp_string_release (tmp_name );
843
+ retval = FAILURE ;
844
+ break ;
845
+ }
846
+
826
847
prot_name = zend_mangle_property_name (
827
848
"*" , 1 , ZSTR_VAL (name ), ZSTR_LEN (name ), ce -> type & ZEND_INTERNAL_CLASS );
828
- if (php_var_serialize_try_add_sleep_prop (ht , props , prot_name , name ) == SUCCESS ) {
849
+ if (php_var_serialize_try_add_sleep_prop (ht , props , prot_name , name , struc ) == SUCCESS ) {
829
850
zend_tmp_string_release (tmp_name );
830
851
zend_string_release (prot_name );
831
852
continue ;
832
853
}
833
854
zend_string_release (prot_name );
834
855
856
+ if (EG (exception )) {
857
+ zend_tmp_string_release (tmp_name );
858
+ retval = FAILURE ;
859
+ break ;
860
+ }
861
+
835
862
php_error_docref (NULL , E_NOTICE ,
836
863
"\"%s\" returned as member variable from __sleep() but does not exist" , ZSTR_VAL (name ));
837
864
zend_hash_add (ht , name , & EG (uninitialized_zval ));
838
865
zend_tmp_string_release (tmp_name );
839
866
} ZEND_HASH_FOREACH_END ();
867
+
840
868
zend_release_properties (props );
869
+ return retval ;
841
870
}
842
871
/* }}} */
843
872
@@ -893,10 +922,11 @@ static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable
893
922
static void php_var_serialize_class (smart_str * buf , zval * struc , zval * retval_ptr , php_serialize_data_t var_hash ) /* {{{ */
894
923
{
895
924
HashTable props ;
896
- php_var_serialize_get_sleep_props (& props , struc , HASH_OF (retval_ptr ));
897
- php_var_serialize_class_name (buf , struc );
898
- php_var_serialize_nested_data (
899
- buf , struc , & props , zend_hash_num_elements (& props ), /* incomplete_class */ 0 , var_hash );
925
+ if (php_var_serialize_get_sleep_props (& props , struc , HASH_OF (retval_ptr )) == SUCCESS ) {
926
+ php_var_serialize_class_name (buf , struc );
927
+ php_var_serialize_nested_data (
928
+ buf , struc , & props , zend_hash_num_elements (& props ), /* incomplete_class */ 0 , var_hash );
929
+ }
900
930
zend_hash_destroy (& props );
901
931
}
902
932
/* }}} */
0 commit comments