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( "