Skip to content

Commit

Permalink
#35 Solved infinite loop when parsing malformed Processing Instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
belingueres authored and hboutemy committed Mar 10, 2019
1 parent 1dafbae commit 7e54bff
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -3017,6 +3017,7 @@ protected boolean parsePI()

try
{
boolean seenPITarget = false;
boolean seenQ = false;
char ch = more();
if ( isS( ch ) )
Expand All @@ -3031,6 +3032,11 @@ protected boolean parsePI()

if ( ch == '?' )
{
if ( !seenPITarget )
{
throw new XmlPullParserException( "processing instruction PITarget name not found", this,
null );
}
seenQ = true;
}
else if ( ch == '>' )
Expand All @@ -3039,7 +3045,18 @@ else if ( ch == '>' )
{
break; // found end sequence!!!!
}
seenQ = false;

if ( !seenPITarget )
{
throw new XmlPullParserException( "processing instruction PITarget name not found", this,
null );
}
else
{
// seenPITarget && !seenQ
throw new XmlPullParserException( "processing instruction started on line " + curLine
+ " and column " + curColumn + " was not closed", this, null );
}
}
else
{
Expand Down Expand Up @@ -3078,6 +3095,7 @@ else if ( ch == '>' )
}
}
}

seenQ = false;
}
if ( normalizeIgnorableWS )
Expand Down Expand Up @@ -3127,6 +3145,7 @@ else if ( ch == '\n' )
normalizedCR = false;
}
}
seenPITarget = true;
ch = more();
}
}
Expand Down
132 changes: 132 additions & 0 deletions src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,136 @@ public void testSubsequentProcessingInstructionMoreThan8k()
assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
}

public void testMalformedProcessingInstructionAfterTag()
throws Exception
{
MXParser parser = new MXParser();

String input = "<project /><?>";

parser.setInput( new StringReader( input ) );

try
{
assertEquals( XmlPullParser.START_TAG, parser.next() );

assertEquals( XmlPullParser.END_TAG, parser.next() );

assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.next() );

fail( "Should fail since it has an invalid Processing Instruction" );
}
catch ( XmlPullParserException ex )
{
assertTrue( ex.getMessage().contains( "processing instruction PITarget name not found" ) );
}
}

public void testMalformedProcessingInstructionBeforeTag()
throws Exception
{
MXParser parser = new MXParser();

String input = "<?><project />";

parser.setInput( new StringReader( input ) );

try
{
assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.next() );

assertEquals( XmlPullParser.START_TAG, parser.next() );

assertEquals( XmlPullParser.END_TAG, parser.next() );

fail( "Should fail since it has invalid PI" );
}
catch ( XmlPullParserException ex )
{
assertTrue( ex.getMessage().contains( "processing instruction PITarget name not found" ) );
}
}

public void testMalformedProcessingInstructionSpaceBeforeName()
throws Exception
{
MXParser parser = new MXParser();

StringBuilder sb = new StringBuilder();
sb.append( "<? shouldhavenospace>" );
sb.append( "<project />" );

parser.setInput( new StringReader( sb.toString() ) );

try
{
assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.next() );

assertEquals( XmlPullParser.START_TAG, parser.next() );

assertEquals( XmlPullParser.END_TAG, parser.next() );

fail( "Should fail since it has invalid PI" );
}
catch ( XmlPullParserException ex )
{
assertTrue( ex.getMessage().contains( "processing instruction PITarget must be exactly after <? and not white space character" ) );
}
}

public void testMalformedProcessingInstructionNoClosingQuestionMark()
throws Exception
{
MXParser parser = new MXParser();

StringBuilder sb = new StringBuilder();
sb.append( "<?shouldhavenospace>" );
sb.append( "<project />" );

parser.setInput( new StringReader( sb.toString() ) );

try
{
assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.next() );

assertEquals( XmlPullParser.START_TAG, parser.next() );

assertEquals( XmlPullParser.END_TAG, parser.next() );

fail( "Should fail since it has invalid PI" );
}
catch ( XmlPullParserException ex )
{
assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 2 was not closed" ) );
}
}

public void testSubsequentMalformedProcessingInstructionNoClosingQuestionMark()
throws Exception
{
MXParser parser = new MXParser();

StringBuilder sb = new StringBuilder();
sb.append( "<project />" );
sb.append( "<?shouldhavenospace>" );

parser.setInput( new StringReader( sb.toString() ) );

try
{
assertEquals( XmlPullParser.START_TAG, parser.next() );

assertEquals( XmlPullParser.END_TAG, parser.next() );

assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.next() );

fail( "Should fail since it has invalid PI" );
}
catch ( XmlPullParserException ex )
{
assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 13 was not closed" ) );
}
}

}

0 comments on commit 7e54bff

Please sign in to comment.