@@ -430,16 +430,16 @@ mod syntax {
430430 mod pi {
431431 use super :: * ;
432432
433- err ! ( unclosed01( ".<?" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
434- err ! ( unclosed02( ".<??" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
435- err ! ( unclosed03( ".<?>" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
436- err ! ( unclosed04( ".<?<" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
437- err ! ( unclosed05( ".<?&" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
438- err ! ( unclosed06( ".<?p" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
439- err ! ( unclosed07( ".<? " ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
440- err ! ( unclosed08( ".<?\t " ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
441- err ! ( unclosed09( ".<?\r " ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
442- err ! ( unclosed10( ".<?\n " ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
433+ err ! ( unclosed01( ".<?" ) => SyntaxError :: UnclosedPI ) ;
434+ err ! ( unclosed02( ".<??" ) => SyntaxError :: UnclosedPI ) ;
435+ err ! ( unclosed03( ".<?>" ) => SyntaxError :: UnclosedPI ) ;
436+ err ! ( unclosed04( ".<?<" ) => SyntaxError :: UnclosedPI ) ;
437+ err ! ( unclosed05( ".<?&" ) => SyntaxError :: UnclosedPI ) ;
438+ err ! ( unclosed06( ".<?p" ) => SyntaxError :: UnclosedPI ) ;
439+ err ! ( unclosed07( ".<? " ) => SyntaxError :: UnclosedPI ) ;
440+ err ! ( unclosed08( ".<?\t " ) => SyntaxError :: UnclosedPI ) ;
441+ err ! ( unclosed09( ".<?\r " ) => SyntaxError :: UnclosedPI ) ;
442+ err ! ( unclosed10( ".<?\n " ) => SyntaxError :: UnclosedPI ) ;
443443
444444 // According to the grammar, processing instruction MUST contain a non-empty
445445 // target name, but we do not consider this as a _syntax_ error.
@@ -453,10 +453,16 @@ mod syntax {
453453 mod decl {
454454 use super :: * ;
455455
456- err ! ( unclosed1( ".<?x" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
457- err ! ( unclosed2( ".<?xm" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
458- err ! ( unclosed3( ".<?xml" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
459- err ! ( unclosed4( ".<?xml?" ) => SyntaxError :: UnclosedPIOrXmlDecl ) ;
456+ err ! ( unclosed1( ".<?x" ) => SyntaxError :: UnclosedPI ) ;
457+ err ! ( unclosed2( ".<?xm" ) => SyntaxError :: UnclosedPI ) ;
458+ err ! ( unclosed3( ".<?xml" ) => SyntaxError :: UnclosedXmlDecl ) ;
459+ err ! ( unclosed4( ".<?xml?" ) => SyntaxError :: UnclosedXmlDecl ) ;
460+ err ! ( unclosed5( ".<?xml " ) => SyntaxError :: UnclosedXmlDecl ) ;
461+ err ! ( unclosed6( ".<?xml\t " ) => SyntaxError :: UnclosedXmlDecl ) ;
462+ err ! ( unclosed7( ".<?xml\r " ) => SyntaxError :: UnclosedXmlDecl ) ;
463+ err ! ( unclosed8( ".<?xml\n " ) => SyntaxError :: UnclosedXmlDecl ) ;
464+ // "xmls" is a PI target, not an XML declaration
465+ err ! ( unclosed9( ".<?xmls" ) => SyntaxError :: UnclosedPI ) ;
460466
461467 // According to the grammar, XML declaration MUST contain at least one space
462468 // and `version` attribute, but we do not consider this as a _syntax_ error.
@@ -467,6 +473,67 @@ mod syntax {
467473 ok ! ( normal5( "<?xml\n ?>" ) => 8 : Event :: Decl ( BytesDecl :: from_start( BytesStart :: from_content( "xml\n " , 3 ) ) ) ) ;
468474 ok ! ( normal6( "<?xml\n ?>rest" ) => 8 : Event :: Decl ( BytesDecl :: from_start( BytesStart :: from_content( "xml\n " , 3 ) ) ) ) ;
469475 }
476+
477+ /// Tests for UTF-16 encoded XML declarations.
478+ /// FIXME: Add support for UTF-8/ASCII incompatible encodings (UTF-16)
479+ mod decl_utf16 {
480+ use super :: * ;
481+ use pretty_assertions:: assert_eq;
482+
483+ /// UTF-16 LE encoded `<?xml ` (with BOM)
484+ /// BOM (FF FE) + '<' (3C 00) + '?' (3F 00) + 'x' (78 00) + 'm' (6D 00) + 'l' (6C 00) + ' ' (20 00)
485+ const UTF16_LE_XML_DECL : & [ u8 ] = & [
486+ 0xFF , 0xFE , // BOM
487+ 0x3C , 0x00 , // <
488+ 0x3F , 0x00 , // ?
489+ 0x78 , 0x00 , // x
490+ 0x6D , 0x00 , // m
491+ 0x6C , 0x00 , // l
492+ 0x20 , 0x00 , // space
493+ ] ;
494+
495+ /// UTF-16 BE encoded `<?xml ` (with BOM)
496+ /// BOM (FE FF) + '<' (00 3C) + '?' (00 3F) + 'x' (00 78) + 'm' (00 6D) + 'l' (00 6C) + ' ' (00 20)
497+ const UTF16_BE_XML_DECL : & [ u8 ] = & [
498+ 0xFE , 0xFF , // BOM
499+ 0x00 , 0x3C , // <
500+ 0x00 , 0x3F , // ?
501+ 0x00 , 0x78 , // x
502+ 0x00 , 0x6D , // m
503+ 0x00 , 0x6C , // l
504+ 0x00 , 0x20 , // space
505+ ] ;
506+
507+ #[ test]
508+ #[ ignore = "UTF-16 support not yet implemented for XML declaration detection" ]
509+ fn utf16_le_unclosed_xml_decl ( ) {
510+ let mut reader = Reader :: from_reader ( UTF16_LE_XML_DECL ) ;
511+ match reader. read_event ( ) {
512+ Err ( Error :: Syntax ( cause) ) => {
513+ assert_eq ! ( cause, SyntaxError :: UnclosedXmlDecl ) ;
514+ }
515+ x => panic ! (
516+ "Expected `Err(Syntax(UnclosedXmlDecl))`, but got {:?}" ,
517+ x
518+ ) ,
519+ }
520+ }
521+
522+ #[ test]
523+ #[ ignore = "UTF-16 support not yet implemented for XML declaration detection" ]
524+ fn utf16_be_unclosed_xml_decl ( ) {
525+ let mut reader = Reader :: from_reader ( UTF16_BE_XML_DECL ) ;
526+ match reader. read_event ( ) {
527+ Err ( Error :: Syntax ( cause) ) => {
528+ assert_eq ! ( cause, SyntaxError :: UnclosedXmlDecl ) ;
529+ }
530+ x => panic ! (
531+ "Expected `Err(Syntax(UnclosedXmlDecl))`, but got {:?}" ,
532+ x
533+ ) ,
534+ }
535+ }
536+ }
470537}
471538
472539mod ill_formed {
0 commit comments