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