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 e21b66cb..d44c9a7f 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 @@ -464,7 +464,7 @@ private void reset() // System.out.println("reset() called"); location = null; lineNumber = 1; - columnNumber = 0; + columnNumber = 1; seenRoot = false; reachedEnd = false; eventType = START_DOCUMENT; @@ -2988,7 +2988,7 @@ private void parseComment() posStart = pos; final int curLine = lineNumber; - final int curColumn = columnNumber; + final int curColumn = columnNumber - 4; try { final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; @@ -3109,7 +3109,7 @@ private boolean parsePI() if ( tokenize ) posStart = pos; final int curLine = lineNumber; - final int curColumn = columnNumber; + final int curColumn = columnNumber - 2; int piTargetStart = pos; int piTargetEnd = -1; final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; @@ -3158,6 +3158,10 @@ else if ( !seenInnerTag ) throw new XmlPullParserException( "processing instruction started on line " + curLine + " and column " + curColumn + " was not closed", this, null ); } + else + { + seenInnerTag = false; + } } else if ( ch == '<' ) { @@ -3960,7 +3964,7 @@ private char more() fillBuf(); // this return value should be ignored as it is used in epilog parsing ... if ( reachedEnd ) - return (char) -1; + throw new EOFException( "no more data available" + getPositionDescription() ); } final char ch = buf[pos++]; // line/columnNumber diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java index 27ba5f8c..e5e04708 100644 --- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java +++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java @@ -353,6 +353,35 @@ public void testValidCharacterReferenceDecimal() * * @throws java.lang.Exception if any. */ + @Test + public void testParserPosition() + throws Exception + { + String input = " \n \tnnn\n"; + + MXParser parser = new MXParser(); + parser.setInput( new StringReader( input ) ); + + assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() ); + assertPosition( 1, 39, parser ); + assertEquals( XmlPullParser.COMMENT, parser.nextToken() ); + assertPosition( 1, 49, parser ); + assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() ); + assertPosition( 2, 3, parser ); // end when next token starts + assertEquals( XmlPullParser.COMMENT, parser.nextToken() ); + assertPosition( 2, 12, parser ); + assertEquals( XmlPullParser.START_TAG, parser.nextToken() ); + assertPosition( 2, 18, parser ); + assertEquals( XmlPullParser.TEXT, parser.nextToken() ); + assertPosition( 2, 23, parser ); // end when next token starts + assertEquals( XmlPullParser.END_TAG, parser.nextToken() ); + assertPosition( 2, 29, parser ); + assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() ); + assertPosition( 3, 2, parser ); // end when next token starts + assertEquals( XmlPullParser.COMMENT, parser.nextToken() ); + assertPosition( 4, 6, parser ); + } + @Test public void testProcessingInstruction() throws Exception @@ -403,6 +432,37 @@ public void testProcessingInstructionsContainingXml() * * @throws java.lang.Exception if any. */ + @Test + public void testMalformedProcessingInstructionsContainingXmlNoClosingQuestionMark() + throws Exception + { + StringBuffer sb = new StringBuffer(); + sb.append( "\n" ); + sb.append( "\n" ); + sb.append( "\n" ); + sb.append( " >\n" ); + + MXParser parser = new MXParser(); + parser.setInput( new StringReader( sb.toString() ) ); + + try + { + assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() ); + assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() ); + assertEquals( XmlPullParser.START_TAG, parser.nextToken() ); + assertEquals( XmlPullParser.END_TAG, parser.nextToken() ); + assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() ); + assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() ); + + fail( "Should fail since it has invalid PI" ); + } + catch ( XmlPullParserException ex ) + { + assertTrue( ex.getMessage().contains( "processing instruction started on line 3 and column 1 was not closed" ) ); + } + } + @Test public void testSubsequentProcessingInstructionShort() throws Exception @@ -624,7 +684,7 @@ public void testMalformedProcessingInstructionNoClosingQuestionMark() } catch ( XmlPullParserException ex ) { - assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 2 was not closed" ) ); + assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 1 was not closed" ) ); } } @@ -657,7 +717,7 @@ public void testSubsequentMalformedProcessingInstructionNoClosingQuestionMark() } catch ( XmlPullParserException ex ) { - assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 13 was not closed" ) ); + assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 12 was not closed" ) ); } } @@ -666,6 +726,58 @@ public void testSubsequentMalformedProcessingInstructionNoClosingQuestionMark() * * @throws java.lang.Exception if any. */ + @Test + public void testSubsequentAbortedProcessingInstruction() + throws Exception + { + MXParser parser = new MXParser(); + StringBuilder sb = new StringBuilder(); + sb.append( "" ); + sb.append( "" ); + sb.append( "