2525#include  <libxml/parserInternals.h> 
2626#include  "zend_strtod.h" 
2727#include  "zend_interfaces.h" 
28+ #include  "zend_enum.h" 
2829
2930/* zval type decode */ 
3031static  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)
830831	return  ret ;
831832}
832833
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+ 
833877static  xmlNodePtr  to_xml_string (encodeTypePtr  type , zval  * data , int  style , xmlNodePtr  parent )
834878{
835879	xmlNodePtr  ret , text ;
836- 	char  * str ;
837- 	int  new_len ;
838880
839881	ret  =  xmlNewNode (NULL , BAD_CAST ("BOGUS" ));
840882	xmlAddChild (parent , ret );
841883	FIND_ZVAL_NULL (data , ret , style );
842884
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 );
852888
853889	if  (SOAP_GLOBAL (encoding ) !=  NULL ) {
854890		xmlBufferPtr  in   =  xmlBufferCreateStatic (str , new_len );
855891		xmlBufferPtr  out  =  xmlBufferCreate ();
856892		int  n  =  xmlCharEncInFunc (SOAP_GLOBAL (encoding ), out , in );
857893
858894		if  (n  >= 0 ) {
859- 			efree (str );
895+ 			zend_string_release (serialization );
896+ 			serialization  =  NULL ;
860897			str  =  estrdup ((char * )xmlBufferContent (out ));
861898			new_len  =  n ;
862899		}
@@ -907,7 +944,11 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
907944
908945	text  =  xmlNewTextLen (BAD_CAST (str ), new_len );
909946	xmlAddChild (ret , text );
910- 	efree (str );
947+ 	if  (serialization ) {
948+ 		zend_string_release (serialization );
949+ 	} else  {
950+ 		efree (str );
951+ 	}
911952
912953	if  (style  ==  SOAP_ENCODED ) {
913954		set_ns_and_type (ret , type );
@@ -918,19 +959,14 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
918959static  xmlNodePtr  to_xml_base64 (encodeTypePtr  type , zval  * data , int  style , xmlNodePtr  parent )
919960{
920961	xmlNodePtr  ret , text ;
921- 	zend_string  * str ;
922962
923963	ret  =  xmlNewNode (NULL , BAD_CAST ("BOGUS" ));
924964	xmlAddChild (parent , ret );
925965	FIND_ZVAL_NULL (data , ret , style );
926966
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 );
934970
935971	text  =  xmlNewTextLen (BAD_CAST (ZSTR_VAL (str )), ZSTR_LEN (str ));
936972	xmlAddChild (ret , text );
@@ -955,7 +991,7 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo
955991	FIND_ZVAL_NULL (data , ret , style );
956992
957993	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 ));
959995		data  =  & tmp ;
960996	}
961997	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
10631099		snprintf (s , sizeof (s ), "%0.0F" ,floor (Z_DVAL_P (data )));
10641100		xmlNodeSetContent (ret , BAD_CAST (s ));
10651101	} 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 ));
10671103		xmlNodeSetContentLen (ret , BAD_CAST (ZSTR_VAL (str )), ZSTR_LEN (str ));
10681104		zend_string_release_ex (str , 0 );
10691105	}
@@ -3026,7 +3062,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
30263062		smart_str  list  =  {0 };
30273063
30283064		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 ));
30303066			data  =  & tmp ;
30313067		}
30323068		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
31353171		} ZEND_HASH_FOREACH_END ();
31363172		return  ret ;
31373173	}
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);
31453178
31463179	ret -> name  =  xmlStringTextNoenc ;
31473180	ret -> parent  =  parent ;
0 commit comments