25
25
#include <libxml/parserInternals.h>
26
26
#include "zend_strtod.h"
27
27
#include "zend_interfaces.h"
28
+ #include "zend_enum.h"
28
29
29
30
/* zval type decode */
30
31
static zval * to_zval_double (zval * ret , encodeTypePtr type , xmlNodePtr data );
@@ -830,33 +831,69 @@ static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data)
830
831
return ret ;
831
832
}
832
833
834
+ static zend_string * get_serialization_string_from_zval (zval * data )
835
+ {
836
+ switch (Z_TYPE_P (data )) {
837
+ case IS_OBJECT :
838
+ if (Z_OBJCE_P (data )-> ce_flags & ZEND_ACC_ENUM ) {
839
+ if (UNEXPECTED (Z_OBJCE_P (data )-> enum_backing_type == IS_UNDEF )) {
840
+ zend_value_error ("Non-backed enums have no default serialization" );
841
+ return zend_empty_string ;
842
+ } else {
843
+ zval * value = zend_enum_fetch_case_value (Z_OBJ_P (data ));
844
+ return zval_get_string_func (value );
845
+ }
846
+ }
847
+ ZEND_FALLTHROUGH ;
848
+ default :
849
+ return zval_get_string_func (data );
850
+ }
851
+ }
852
+
853
+ static zend_long get_serialization_long_from_zval (zval * data )
854
+ {
855
+ switch (Z_TYPE_P (data )) {
856
+ case IS_OBJECT :
857
+ if (Z_OBJCE_P (data )-> ce_flags & ZEND_ACC_ENUM ) {
858
+ if (UNEXPECTED (Z_OBJCE_P (data )-> enum_backing_type != IS_LONG )) {
859
+ if (Z_OBJCE_P (data )-> enum_backing_type == IS_UNDEF ) {
860
+ zend_value_error ("Non-backed enums have no default serialization" );
861
+ } else {
862
+ zend_value_error ("String-backed enum cannot be serialized as int" );
863
+ }
864
+ return 0 ;
865
+ } else {
866
+ zval * value = zend_enum_fetch_case_value (Z_OBJ_P (data ));
867
+ ZEND_ASSERT (Z_TYPE_P (value ) == IS_LONG );
868
+ return Z_LVAL_P (value );
869
+ }
870
+ }
871
+ ZEND_FALLTHROUGH ;
872
+ default :
873
+ return zval_get_long (data );
874
+ }
875
+ }
876
+
833
877
static xmlNodePtr to_xml_string (encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
834
878
{
835
879
xmlNodePtr ret , text ;
836
- char * str ;
837
- int new_len ;
838
880
839
881
ret = xmlNewNode (NULL , BAD_CAST ("BOGUS" ));
840
882
xmlAddChild (parent , ret );
841
883
FIND_ZVAL_NULL (data , ret , style );
842
884
843
- if (Z_TYPE_P (data ) == IS_STRING ) {
844
- str = estrndup (Z_STRVAL_P (data ), Z_STRLEN_P (data ));
845
- new_len = Z_STRLEN_P (data );
846
- } else {
847
- zend_string * tmp = zval_get_string_func (data );
848
- str = estrndup (ZSTR_VAL (tmp ), ZSTR_LEN (tmp ));
849
- new_len = ZSTR_LEN (tmp );
850
- zend_string_release_ex (tmp , 0 );
851
- }
885
+ zend_string * serialization = get_serialization_string_from_zval (data );
886
+ char * str = ZSTR_VAL (serialization );
887
+ size_t new_len = ZSTR_LEN (serialization );
852
888
853
889
if (SOAP_GLOBAL (encoding ) != NULL ) {
854
890
xmlBufferPtr in = xmlBufferCreateStatic (str , new_len );
855
891
xmlBufferPtr out = xmlBufferCreate ();
856
892
int n = xmlCharEncInFunc (SOAP_GLOBAL (encoding ), out , in );
857
893
858
894
if (n >= 0 ) {
859
- efree (str );
895
+ zend_string_release (serialization );
896
+ serialization = NULL ;
860
897
str = estrdup ((char * )xmlBufferContent (out ));
861
898
new_len = n ;
862
899
}
@@ -907,7 +944,11 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
907
944
908
945
text = xmlNewTextLen (BAD_CAST (str ), new_len );
909
946
xmlAddChild (ret , text );
910
- efree (str );
947
+ if (serialization ) {
948
+ zend_string_release (serialization );
949
+ } else {
950
+ efree (str );
951
+ }
911
952
912
953
if (style == SOAP_ENCODED ) {
913
954
set_ns_and_type (ret , type );
@@ -918,19 +959,14 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
918
959
static xmlNodePtr to_xml_base64 (encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
919
960
{
920
961
xmlNodePtr ret , text ;
921
- zend_string * str ;
922
962
923
963
ret = xmlNewNode (NULL , BAD_CAST ("BOGUS" ));
924
964
xmlAddChild (parent , ret );
925
965
FIND_ZVAL_NULL (data , ret , style );
926
966
927
- if (Z_TYPE_P (data ) == IS_STRING ) {
928
- str = php_base64_encode ((unsigned char * )Z_STRVAL_P (data ), Z_STRLEN_P (data ));
929
- } else {
930
- zend_string * tmp = zval_get_string_func (data );
931
- str = php_base64_encode ((unsigned char * ) ZSTR_VAL (tmp ), ZSTR_LEN (tmp ));
932
- zend_string_release_ex (tmp , 0 );
933
- }
967
+ zend_string * serialization = get_serialization_string_from_zval (data );
968
+ zend_string * str = php_base64_encode ((unsigned char * ) ZSTR_VAL (serialization ), ZSTR_LEN (serialization ));
969
+ zend_string_release (serialization );
934
970
935
971
text = xmlNewTextLen (BAD_CAST (ZSTR_VAL (str )), ZSTR_LEN (str ));
936
972
xmlAddChild (ret , text );
@@ -955,7 +991,7 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo
955
991
FIND_ZVAL_NULL (data , ret , style );
956
992
957
993
if (Z_TYPE_P (data ) != IS_STRING ) {
958
- ZVAL_STR (& tmp , zval_get_string_func (data ));
994
+ ZVAL_STR (& tmp , get_serialization_string_from_zval (data ));
959
995
data = & tmp ;
960
996
}
961
997
str = (unsigned char * ) safe_emalloc (Z_STRLEN_P (data ) * 2 , sizeof (char ), 1 );
@@ -1063,7 +1099,7 @@ static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNode
1063
1099
snprintf (s , sizeof (s ), "%0.0F" ,floor (Z_DVAL_P (data )));
1064
1100
xmlNodeSetContent (ret , BAD_CAST (s ));
1065
1101
} else {
1066
- zend_string * str = zend_long_to_str (zval_get_long (data ));
1102
+ zend_string * str = zend_long_to_str (get_serialization_long_from_zval (data ));
1067
1103
xmlNodeSetContentLen (ret , BAD_CAST (ZSTR_VAL (str )), ZSTR_LEN (str ));
1068
1104
zend_string_release_ex (str , 0 );
1069
1105
}
@@ -3026,7 +3062,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
3026
3062
smart_str list = {0 };
3027
3063
3028
3064
if (Z_TYPE_P (data ) != IS_STRING ) {
3029
- ZVAL_STR (& tmp , zval_get_string_func (data ));
3065
+ ZVAL_STR (& tmp , get_serialization_string_from_zval (data ));
3030
3066
data = & tmp ;
3031
3067
}
3032
3068
str = estrndup (Z_STRVAL_P (data ), Z_STRLEN_P (data ));
@@ -3135,13 +3171,10 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP
3135
3171
} ZEND_HASH_FOREACH_END ();
3136
3172
return ret ;
3137
3173
}
3138
- if (Z_TYPE_P (data ) == IS_STRING ) {
3139
- ret = xmlNewTextLen (BAD_CAST (Z_STRVAL_P (data )), Z_STRLEN_P (data ));
3140
- } else {
3141
- zend_string * tmp = zval_get_string_func (data );
3142
- ret = xmlNewTextLen (BAD_CAST (ZSTR_VAL (tmp )), ZSTR_LEN (tmp ));
3143
- zend_string_release_ex (tmp , 0 );
3144
- }
3174
+
3175
+ zend_string * serialization = get_serialization_string_from_zval (data );
3176
+ ret = xmlNewTextLen (BAD_CAST (ZSTR_VAL (serialization )), ZSTR_LEN (serialization ));
3177
+ zend_string_release_ex (serialization , false);
3145
3178
3146
3179
ret -> name = xmlStringTextNoenc ;
3147
3180
ret -> parent = parent ;
0 commit comments