11use crate :: avm2:: error:: {
2- make_error_1010, make_error_1085, make_error_1088, make_error_1118, make_unknown_ns_error ,
3- make_xml_error,
2+ XmlErrorCode , make_error_1010, make_error_1085, make_error_1088, make_error_1118,
3+ make_unknown_ns_error , make_xml_error,
44} ;
55use crate :: avm2:: function:: FunctionArgs ;
66use crate :: avm2:: object:: { E4XOrXml , FunctionObject , NamespaceObject } ;
@@ -15,8 +15,8 @@ use gc_arena::{
1515
1616use quick_xml:: {
1717 Error as XmlError , NsReader ,
18- errors:: IllFormedError ,
19- events:: { BytesStart , Event } ,
18+ errors:: { IllFormedError , SyntaxError as XmlSyntaxError } ,
19+ events:: { BytesStart , Event , attributes :: AttrError as XmlAttrError } ,
2020 name:: ResolveResult ,
2121} ;
2222use ruffle_common:: xml:: custom_unescape;
@@ -765,41 +765,71 @@ impl<'gc> E4XNode<'gc> {
765765 loop {
766766 let event = match parser. read_event ( ) {
767767 Ok ( event) => event,
768- Err ( XmlError :: IllFormed ( IllFormedError :: MismatchedEndTag { expected, found } ) ) => {
769- // We must accept </a/>, </a />, and </a b="c">
770- // TODO: Reject </a bc>, </a//>, <a //> etc.
771- if let Some ( rest) = found. strip_prefix ( & expected) {
772- if rest. starts_with ( [ ' ' , '\t' , '/' ] ) {
773- let node = open_tags. pop ( ) . unwrap ( ) ;
774- if open_tags. is_empty ( ) {
775- top_level. push ( node) ;
768+ Err ( err) => {
769+ let err = match err {
770+ XmlError :: IllFormed ( IllFormedError :: MismatchedEndTag {
771+ expected,
772+ found,
773+ } ) => {
774+ // We must accept </a/>, </a />, and </a b="c">
775+ // TODO: Reject </a bc>, </a//>, <a //> etc.
776+ if let Some ( rest) = found. strip_prefix ( & expected) {
777+ if rest. starts_with ( [ ' ' , '\t' , '/' ] ) {
778+ let node = open_tags. pop ( ) . unwrap ( ) ;
779+ if open_tags. is_empty ( ) {
780+ top_level. push ( node) ;
781+ }
782+ continue ;
783+ }
776784 }
777- continue ;
785+ make_error_1085 ( activation , & expected )
778786 }
779- }
780- return Err ( make_error_1085 ( activation, & expected) ) ;
781- }
782- Err ( XmlError :: IllFormed ( IllFormedError :: UnmatchedEndTag ( _) ) )
783- if open_tags. is_empty ( ) =>
784- {
785- return Err ( make_error_1088 ( activation) ) ;
787+ XmlError :: IllFormed ( IllFormedError :: UnmatchedEndTag ( _) )
788+ if open_tags. is_empty ( ) =>
789+ {
790+ make_error_1088 ( activation)
791+ }
792+ XmlError :: InvalidAttr ( XmlAttrError :: Duplicated ( _, _) ) => {
793+ make_xml_error ( activation, XmlErrorCode :: DuplicateAttribute )
794+ }
795+ XmlError :: Syntax ( syntax_error) => {
796+ let code = match syntax_error {
797+ XmlSyntaxError :: UnclosedPIOrXmlDecl => {
798+ XmlErrorCode :: UnterminatedProcessingInstruction
799+ }
800+ XmlSyntaxError :: UnclosedComment => {
801+ XmlErrorCode :: UnterminatedComment
802+ }
803+ XmlSyntaxError :: UnclosedDoctype => {
804+ XmlErrorCode :: UnterminatedDoctype
805+ }
806+ XmlSyntaxError :: UnclosedCData => XmlErrorCode :: UnterminatedCData ,
807+ XmlSyntaxError :: UnclosedTag => XmlErrorCode :: ElementMalformed ,
808+ // TODO: handle other errors properly
809+ _ => XmlErrorCode :: ElementMalformed ,
810+ } ;
811+
812+ make_xml_error ( activation, code)
813+ }
814+ // TODO: handle other errors properly
815+ _ => make_xml_error ( activation, XmlErrorCode :: ElementMalformed ) ,
816+ } ;
817+
818+ return Err ( err) ;
786819 }
787- Err ( err) => return Err ( make_xml_error ( activation, err) ) ,
788820 } ;
789821
790822 match & event {
791823 Event :: Start ( bs) => {
792- let child =
793- E4XNode :: from_start_event ( activation, & parser, bs, parser. decoder ( ) ) ?;
824+ let child = E4XNode :: from_start_event ( activation, & parser, bs) ?;
794825
795826 if let Some ( current_tag) = open_tags. last_mut ( ) {
796827 current_tag. append_child ( activation. gc ( ) , child) ;
797828 }
798829 open_tags. push ( child) ;
799830 }
800831 Event :: Empty ( bs) => {
801- let node =
802- E4XNode :: from_start_event ( activation, & parser, bs, parser. decoder ( ) ) ?;
832+ let node = E4XNode :: from_start_event ( activation, & parser, bs) ?;
803833 push_childless_node ( node, & mut open_tags, & mut top_level, activation) ;
804834 }
805835 Event :: End ( _) => {
@@ -810,8 +840,10 @@ impl<'gc> E4XNode<'gc> {
810840 }
811841 Event :: Text ( bt) => {
812842 handle_text_cdata (
813- custom_unescape ( bt, parser. decoder ( ) )
814- . map_err ( |e| make_xml_error ( activation, e) ) ?
843+ custom_unescape ( bt)
844+ . map_err ( |_| {
845+ make_xml_error ( activation, XmlErrorCode :: ElementMalformed )
846+ } ) ?
815847 . as_bytes ( ) ,
816848 ignore_white,
817849 & mut open_tags,
@@ -836,9 +868,11 @@ impl<'gc> E4XNode<'gc> {
836868 if ignore_comments {
837869 continue ;
838870 }
839- let text = custom_unescape ( bt, parser. decoder ( ) )
840- . map_err ( |e| make_xml_error ( activation, e) ) ?;
841- let text = AvmString :: new_utf8_bytes ( activation. gc ( ) , text. as_bytes ( ) ) ;
871+
872+ let text = custom_unescape ( bt)
873+ . map_err ( |_| make_xml_error ( activation, XmlErrorCode :: ElementMalformed ) ) ?;
874+ let text = AvmString :: new_utf8 ( activation. gc ( ) , text) ;
875+
842876 let node = E4XNode ( Gc :: new (
843877 activation. gc ( ) ,
844878 E4XNodeData {
@@ -856,8 +890,10 @@ impl<'gc> E4XNode<'gc> {
856890 if ignore_processing_instructions {
857891 continue ;
858892 }
859- let text = custom_unescape ( bt, parser. decoder ( ) )
860- . map_err ( |e| make_xml_error ( activation, e) ) ?;
893+
894+ let text = custom_unescape ( bt)
895+ . map_err ( |_| make_xml_error ( activation, XmlErrorCode :: ElementMalformed ) ) ?;
896+
861897 let ( name, value) = if let Some ( ( name, value) ) = text. split_once ( ' ' ) {
862898 (
863899 AvmString :: new_utf8_bytes ( activation. gc ( ) , name. as_bytes ( ) ) ,
@@ -910,18 +946,26 @@ impl<'gc> E4XNode<'gc> {
910946 activation : & mut Activation < ' _ , ' gc > ,
911947 parser : & NsReader < & [ u8 ] > ,
912948 bs : & BytesStart < ' _ > ,
913- decoder : quick_xml:: Decoder ,
914949 ) -> Result < Self , Error < ' gc > > {
915950 let mut attribute_nodes = Vec :: new ( ) ;
916951 let mut namespaces = Vec :: new ( ) ;
917952
918- let attributes: Result < Vec < _ > , _ > = bs. attributes ( ) . collect ( ) ;
919- for attribute in
920- attributes. map_err ( |e| make_xml_error ( activation, XmlError :: InvalidAttr ( e) ) ) ?
921- {
922- let value_str = custom_unescape ( & attribute. value , decoder)
923- . map_err ( |e| make_xml_error ( activation, e) ) ?;
924- let value = AvmString :: new_utf8_bytes ( activation. gc ( ) , value_str. as_bytes ( ) ) ;
953+ let attributes = bs
954+ . attributes ( )
955+ . collect :: < Result < Vec < _ > , XmlAttrError > > ( )
956+ . map_err ( |e| {
957+ let code = match e {
958+ XmlAttrError :: Duplicated ( _, _) => XmlErrorCode :: DuplicateAttribute ,
959+ _ => XmlErrorCode :: ElementMalformed ,
960+ } ;
961+
962+ make_xml_error ( activation, code)
963+ } ) ?;
964+
965+ for attribute in attributes {
966+ let value_str = custom_unescape ( & attribute. value )
967+ . map_err ( |_| make_xml_error ( activation, XmlErrorCode :: ElementMalformed ) ) ?;
968+ let value = AvmString :: new_utf8 ( activation. gc ( ) , value_str) ;
925969
926970 let ( ns, local_name) = parser. resolve_attribute ( attribute. key ) ;
927971
0 commit comments