1+ use quick_xml:: escape:: unescape;
12use quick_xml:: events:: { BytesStart , Event } ;
23use quick_xml:: name:: { QName , ResolveResult } ;
34use quick_xml:: { Decoder , Reader , Result } ;
@@ -403,21 +404,25 @@ fn namespace_name(n: ResolveResult, name: QName, decoder: Decoder) -> String {
403404 let name = decoder. decode ( name. as_ref ( ) ) . unwrap ( ) ;
404405 match n {
405406 // Produces string '{namespace}prefixed_name'
406- ResolveResult :: Bound ( n) => format ! ( "{{{}}}{}" , from_utf8 ( n. as_ref( ) ) . unwrap( ) , name) ,
407+ ResolveResult :: Bound ( n) => format ! ( "{{{}}}{}" , decoder . decode ( n. as_ref( ) ) . unwrap( ) , name) ,
407408 _ => name. to_string ( ) ,
408409 }
409410}
410411
411- fn make_attrs ( e : & BytesStart ) -> :: std:: result:: Result < String , String > {
412+ fn make_attrs ( e : & BytesStart , decoder : Decoder ) -> :: std:: result:: Result < String , String > {
412413 let mut atts = Vec :: new ( ) ;
413414 for a in e. attributes ( ) {
414415 match a {
415416 Ok ( a) => {
416417 if a. key . as_namespace_binding ( ) . is_none ( ) {
418+ let key = decoder. decode ( a. key . as_ref ( ) ) . unwrap ( ) ;
419+ let value = decoder. decode ( a. value . as_ref ( ) ) . unwrap ( ) ;
420+ let unescaped_value = unescape ( value. as_bytes ( ) ) . unwrap ( ) ;
417421 atts. push ( format ! (
418422 "{}=\" {}\" " ,
419- from_utf8( a. key. as_ref( ) ) . unwrap( ) ,
420- from_utf8( & * a. unescaped_value( ) . unwrap( ) ) . unwrap( )
423+ key,
424+ // unescape does not change validity of an UTF-8 string
425+ from_utf8( & * unescaped_value) . unwrap( )
421426 ) ) ;
422427 }
423428 }
@@ -430,43 +435,45 @@ fn make_attrs(e: &BytesStart) -> ::std::result::Result<String, String> {
430435fn xmlrs_display ( opt_event : Result < ( ResolveResult , Event ) > , decoder : Decoder ) -> String {
431436 match opt_event {
432437 Ok ( ( _, Event :: StartText ( _) ) ) => "StartText" . to_string ( ) ,
433- Ok ( ( n, Event :: Start ( ref e) ) ) => {
438+ Ok ( ( n, Event :: Start ( e) ) ) => {
434439 let name = namespace_name ( n, e. name ( ) , decoder) ;
435- match make_attrs ( e ) {
436- Ok ( ref attrs) if attrs. is_empty ( ) => format ! ( "StartElement({})" , & name) ,
437- Ok ( ref attrs) => format ! ( "StartElement({} [{}])" , & name, & attrs) ,
440+ match make_attrs ( & e , decoder ) {
441+ Ok ( attrs) if attrs. is_empty ( ) => format ! ( "StartElement({})" , & name) ,
442+ Ok ( attrs) => format ! ( "StartElement({} [{}])" , & name, & attrs) ,
438443 Err ( e) => format ! ( "StartElement({}, attr-error: {})" , & name, & e) ,
439444 }
440445 }
441- Ok ( ( n, Event :: Empty ( ref e) ) ) => {
446+ Ok ( ( n, Event :: Empty ( e) ) ) => {
442447 let name = namespace_name ( n, e. name ( ) , decoder) ;
443- match make_attrs ( e ) {
444- Ok ( ref attrs) if attrs. is_empty ( ) => format ! ( "EmptyElement({})" , & name) ,
445- Ok ( ref attrs) => format ! ( "EmptyElement({} [{}])" , & name, & attrs) ,
448+ match make_attrs ( & e , decoder ) {
449+ Ok ( attrs) if attrs. is_empty ( ) => format ! ( "EmptyElement({})" , & name) ,
450+ Ok ( attrs) => format ! ( "EmptyElement({} [{}])" , & name, & attrs) ,
446451 Err ( e) => format ! ( "EmptyElement({}, attr-error: {})" , & name, & e) ,
447452 }
448453 }
449- Ok ( ( n, Event :: End ( ref e) ) ) => {
454+ Ok ( ( n, Event :: End ( e) ) ) => {
450455 let name = namespace_name ( n, e. name ( ) , decoder) ;
451456 format ! ( "EndElement({})" , name)
452457 }
453- Ok ( ( _, Event :: Comment ( ref e) ) ) => format ! ( "Comment({})" , from_utf8 ( e) . unwrap( ) ) ,
454- Ok ( ( _, Event :: CData ( ref e) ) ) => format ! ( "CData({})" , from_utf8 ( e) . unwrap( ) ) ,
455- Ok ( ( _, Event :: Text ( ref e) ) ) => match e . unescaped ( ) {
456- Ok ( c) => format ! ( "Characters({})" , decoder . decode ( c. as_ref( ) ) . unwrap( ) ) ,
457- Err ( ref err) => format ! ( "FailedUnescape({:?}; {})" , e. escaped( ) , err) ,
458+ Ok ( ( _, Event :: Comment ( e) ) ) => format ! ( "Comment({})" , decoder . decode ( & e) . unwrap( ) ) ,
459+ Ok ( ( _, Event :: CData ( e) ) ) => format ! ( "CData({})" , decoder . decode ( & e) . unwrap( ) ) ,
460+ Ok ( ( _, Event :: Text ( e) ) ) => match unescape ( decoder . decode ( & e ) . unwrap ( ) . as_bytes ( ) ) {
461+ Ok ( c) => format ! ( "Characters({})" , from_utf8 ( c. as_ref( ) ) . unwrap( ) ) ,
462+ Err ( err) => format ! ( "FailedUnescape({:?}; {})" , e. escaped( ) , err) ,
458463 } ,
459- Ok ( ( _, Event :: Decl ( ref e) ) ) => {
464+ Ok ( ( _, Event :: Decl ( e) ) ) => {
460465 let version_cow = e. version ( ) . unwrap ( ) ;
461- let version = from_utf8 ( version_cow. as_ref ( ) ) . unwrap ( ) ;
466+ let version = decoder . decode ( version_cow. as_ref ( ) ) . unwrap ( ) ;
462467 let encoding_cow = e. encoding ( ) . unwrap ( ) . unwrap ( ) ;
463- let encoding = from_utf8 ( encoding_cow. as_ref ( ) ) . unwrap ( ) ;
468+ let encoding = decoder . decode ( encoding_cow. as_ref ( ) ) . unwrap ( ) ;
464469 format ! ( "StartDocument({}, {})" , version, encoding)
465470 }
466471 Ok ( ( _, Event :: Eof ) ) => format ! ( "EndDocument" ) ,
467- Ok ( ( _, Event :: PI ( ref e) ) ) => format ! ( "ProcessingInstruction(PI={})" , from_utf8( e) . unwrap( ) ) ,
468- Err ( ref e) => format ! ( "Error: {}" , e) ,
469- Ok ( ( _, Event :: DocType ( ref e) ) ) => format ! ( "DocType({})" , from_utf8( e) . unwrap( ) ) ,
472+ Ok ( ( _, Event :: PI ( e) ) ) => {
473+ format ! ( "ProcessingInstruction(PI={})" , decoder. decode( & e) . unwrap( ) )
474+ }
475+ Ok ( ( _, Event :: DocType ( e) ) ) => format ! ( "DocType({})" , decoder. decode( & e) . unwrap( ) ) ,
476+ Err ( e) => format ! ( "Error: {}" , e) ,
470477 }
471478}
472479
0 commit comments