From 7d233825adf9abfd98b6d653b70bc8fd38ee1924 Mon Sep 17 00:00:00 2001 From: Gabriel Belingueres Date: Sun, 31 Jan 2021 20:29:11 -0300 Subject: [PATCH] Fix MXParser fails to parse xml declaration properly (#138) - Fix bugs. - Added tests. - Improved error messages. --- .../plexus/util/xml/pull/MXParser.java | 25 ++++++++---- ...onformanceTestSuite_Production32_Test.java | 18 +++++---- .../plexus/util/xml/pull/MXParserTest.java | 40 +++++++++++++++++++ 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java index 4ce9bf0c..bc1c3608 100644 --- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java +++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java @@ -3296,6 +3296,8 @@ private void parseXmlDeclWithVersion( int versionStart, int versionEnd ) } xmlDeclVersion = newString( buf, versionStart, versionEnd - versionStart ); + String lastParsedAttr = "version"; + // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) char ch = more(); char prevCh = ch; @@ -3310,8 +3312,8 @@ private void parseXmlDeclWithVersion( int versionStart, int versionEnd ) { if ( !isS( prevCh ) ) { - throw new XmlPullParserException( "expected a space after version and not " + printable( ch ), this, - null ); + throw new XmlPullParserException( "expected a space after " + lastParsedAttr + " and not " + + printable( ch ), this, null ); } ch = more(); ch = requireInput( ch, NCODING ); @@ -3363,13 +3365,23 @@ else if ("UTF-16".equals( fileEncoding ) && inputEncoding.equalsIgnoreCase( "UTF throw new XmlPullParserException( "UTF-16 BOM plus xml decl of " + inputEncoding + " is incompatible", this, null ); } + + lastParsedAttr = "encoding"; + + ch = more(); + prevCh = ch; + ch = skipS( ch ); } - ch = more(); - ch = skipS( ch ); // [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) if ( ch == 's' ) { + if ( !isS( prevCh ) ) + { + throw new XmlPullParserException( "expected a space after " + lastParsedAttr + " and not " + + printable( ch ), this, null ); + } + ch = more(); ch = requireInput( ch, TANDALONE ); ch = skipS( ch ); @@ -3382,11 +3394,10 @@ else if ("UTF-16".equals( fileEncoding ) && inputEncoding.equalsIgnoreCase( "UTF ch = skipS( ch ); if ( ch != '\'' && ch != '"' ) { - throw new XmlPullParserException( "expected apostrophe (') or quotation mark (\") after encoding and not " + throw new XmlPullParserException( "expected apostrophe (') or quotation mark (\") after standalone and not " + printable( ch ), this, null ); } char quotChar = ch; - int standaloneStart = pos; ch = more(); if ( ch == 'y' ) { @@ -3411,9 +3422,9 @@ else if ( ch == 'n' ) + printable( ch ), this, null ); } ch = more(); + ch = skipS( ch ); } - ch = skipS( ch ); if ( ch != '?' ) { throw new XmlPullParserException( "expected ?> as last part of as last part of as last part of as last part of as last part of as last part of as last part of as last part of "; + + MXParser parser = new MXParser(); + parser.setInput( new StringReader( input ) ); + + try + { + assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() ); + assertEquals( XmlPullParser.START_TAG, parser.nextToken() ); + assertEquals( XmlPullParser.END_TAG, parser.nextToken() ); + } + catch ( Exception e ) + { + fail( "Should not throw Exception" ); + } + } + + @Test + public void testXMLDeclVersionEncodingStandaloneNoSpace() + throws Exception + { + String input = ""; + + MXParser parser = new MXParser(); + parser.setInput( new StringReader( input ) ); + + try + { + parser.nextToken(); + } + catch ( XmlPullParserException e ) + { + assertTrue( e.getMessage().contains( "expected a space after encoding and not s" )); + } + } + }