[MNG-7360] Fix xml transformation to ensure proper context (#744)

This commit is contained in:
Guillaume Nodet 2022-06-28 08:43:10 +02:00 committed by GitHub
parent 7dbbcc23a9
commit 90c084dcf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 132 additions and 37 deletions

View File

@ -53,7 +53,9 @@ public BuildToRawPomXMLFilterFactory( boolean consume )
public final XmlPullParser get( XmlPullParser orgParser, Path projectFile )
{
XmlPullParser parser = orgParser;
// Ensure that xs:any elements aren't touched by next filters
XmlPullParser parser = orgParser instanceof FastForwardFilter
? orgParser : new FastForwardFilter( orgParser );
if ( getDependencyKeyToVersionMapper() != null )
{

View File

@ -28,8 +28,9 @@
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* This filter will skip all following filters and write directly to the output.
* Should be used in case of a DOM that should not be effected by other filters, even though the elements match.
* This filter will bypass all following filters and write directly to the output.
* Should be used in case of a DOM that should not be effected by other filters,
* even though the elements match.
*
* @author Robert Scholte
* @author Guillaume Nodet
@ -59,7 +60,22 @@ class FastForwardFilter extends BufferingParser
}
@Override
protected boolean accept() throws XmlPullParserException, IOException
public int next() throws XmlPullParserException, IOException
{
int event = super.next();
filter();
return event;
}
@Override
public int nextToken() throws XmlPullParserException, IOException
{
int event = super.nextToken();
filter();
return event;
}
protected void filter() throws XmlPullParserException, IOException
{
if ( xmlPullParser.getEventType() == START_TAG )
{
@ -70,7 +86,7 @@ protected boolean accept() throws XmlPullParserException, IOException
}
else
{
final String key = state.peek() + '/' + localName;
final String key = state.peekLast() + '/' + localName;
switch ( key )
{
case "execution/configuration":
@ -79,8 +95,11 @@ protected boolean accept() throws XmlPullParserException, IOException
case "profile/reports":
case "project/reports":
case "reportSet/configuration":
if ( domDepth == 0 )
{
bypass( true );
}
domDepth++;
disable();
break;
default:
break;
@ -90,14 +109,20 @@ protected boolean accept() throws XmlPullParserException, IOException
}
else if ( xmlPullParser.getEventType() == END_TAG )
{
domDepth--;
if ( domDepth == 0 )
if ( domDepth > 0 )
{
enable();
if ( --domDepth == 0 )
{
bypass( false );
}
}
state.pop();
state.removeLast();
}
return true;
}
@Override
public void bypass( boolean bypass )
{
this.bypass = bypass;
}
}

View File

@ -39,13 +39,12 @@ public RawToConsumerPomXMLFilterFactory( BuildToRawPomXMLFilterFactory buildPomX
public final XmlPullParser get( XmlPullParser orgParser, Path projectPath )
{
XmlPullParser parser = orgParser;
// Ensure that xs:any elements aren't touched by next filters
XmlPullParser parser = orgParser instanceof FastForwardFilter
? orgParser : new FastForwardFilter( orgParser );
parser = buildPomXMLFilterFactory.get( parser, projectPath );
// Ensure that xs:any elements aren't touched by next filters
parser = new FastForwardFilter( parser );
// Strip modules
parser = new ModulesXMLFilter( parser );
// Adjust relativePath

View File

@ -41,7 +41,7 @@ public class BufferingParser implements XmlPullParser
protected XmlPullParser xmlPullParser;
protected Deque<Event> events;
protected Event current;
protected boolean disabled;
protected boolean bypass;
@SuppressWarnings( "checkstyle:VisibilityModifier" )
public static class Event
@ -404,7 +404,7 @@ public int next() throws XmlPullParserException, IOException
throw new XmlPullParserException( "already reached end of XML input", this, null );
}
int currentEvent = xmlPullParser.next();
if ( disabled || accept() )
if ( bypass() || accept() )
{
return currentEvent;
}
@ -430,7 +430,7 @@ public int nextToken() throws XmlPullParserException, IOException
throw new XmlPullParserException( "already reached end of XML input", this, null );
}
int currentEvent = xmlPullParser.nextToken();
if ( accept() )
if ( bypass() || accept() )
{
return currentEvent;
}
@ -531,22 +531,20 @@ protected boolean accept() throws XmlPullParserException, IOException
return true;
}
protected void enable()
public void bypass( boolean bypass )
{
disabled = false;
}
protected void disable()
{
if ( events != null && !events.isEmpty() )
if ( bypass && events != null && !events.isEmpty() )
{
throw new IllegalStateException( "Can not disable filter while processing" );
}
disabled = true;
if ( xmlPullParser instanceof BufferingParser )
{
( ( BufferingParser ) xmlPullParser ).disable();
}
this.bypass = bypass;
}
public boolean bypass()
{
return bypass
|| ( xmlPullParser instanceof BufferingParser
&& ( (BufferingParser) xmlPullParser ).bypass() );
}
protected static String nullSafeAppend( String originalValue, String charSegment )

View File

@ -33,7 +33,7 @@
public class ParentXMLFilterTest
extends AbstractXMLFilterTests
{
private Function<XmlPullParser, ParentXMLFilter> filterCreator;
private Function<XmlPullParser, XmlPullParser> filterCreator;
@BeforeEach
void reset() {
@ -41,22 +41,93 @@ void reset() {
}
@Override
protected ParentXMLFilter getFilter( XmlPullParser parser )
protected XmlPullParser getFilter( XmlPullParser parser )
{
Function<XmlPullParser, ParentXMLFilter> filterCreator =
Function<XmlPullParser, XmlPullParser> filterCreator =
(this.filterCreator != null ? this.filterCreator : this::createFilter);
return filterCreator.apply(parser);
}
protected ParentXMLFilter createFilter( XmlPullParser parser ) {
protected XmlPullParser createFilter( XmlPullParser parser ) {
return createFilter( parser,
x -> Optional.of(new RelativeProject("GROUPID", "ARTIFACTID", "1.0.0")),
Paths.get( "pom.xml").toAbsolutePath() );
}
protected ParentXMLFilter createFilter( XmlPullParser parser, Function<Path, Optional<RelativeProject>> pathMapper, Path projectPath ) {
ParentXMLFilter filter = new ParentXMLFilter( parser, pathMapper, projectPath );
return filter;
protected XmlPullParser createFilter( XmlPullParser parser, Function<Path, Optional<RelativeProject>> pathMapper, Path projectPath ) {
return new ParentXMLFilter( new FastForwardFilter( parser ), pathMapper, projectPath );
}
@Test
public void testWithFastForward()
throws Exception
{
String input = "<project>"
+ "<build>"
+ "<plugins>"
+ "<plugin>"
+ "<configuration>"
+ "<parent>"
+ "<groupId>GROUPID</groupId>"
+ "<artifactId>ARTIFACTID</artifactId>"
+ "</parent>"
+ "</configuration>"
+ "</plugin>"
+ "</plugins>"
+ "</build>"
+ "</project>";
String expected = input;
String actual = transform( input );
assertEquals( expected, actual );
}
@Test
public void testWithFastForwardAfterByPass()
throws Exception
{
String input = "<project>"
+ "<build>"
+ "<plugins>"
+ "<plugin>"
+ "<configuration>"
+ "<parent>"
+ "<groupId>GROUPID</groupId>"
+ "<artifactId>ARTIFACTID</artifactId>"
+ "</parent>"
+ "</configuration>"
+ "</plugin>"
+ "</plugins>"
+ "</build>"
+ "<parent>"
+ "<groupId>GROUPID</groupId>"
+ "<artifactId>ARTIFACTID</artifactId>"
+ "</parent>"
+ "</project>";
String expected = "<project>"
+ "<build>"
+ "<plugins>"
+ "<plugin>"
+ "<configuration>"
+ "<parent>"
+ "<groupId>GROUPID</groupId>"
+ "<artifactId>ARTIFACTID</artifactId>"
+ "</parent>"
+ "</configuration>"
+ "</plugin>"
+ "</plugins>"
+ "</build>"
+ "<parent>"
+ "<groupId>GROUPID</groupId>"
+ "<artifactId>ARTIFACTID</artifactId>"
+ "<version>1.0.0</version>"
+ "</parent>"
+ "</project>";
String actual = transform( input );
assertEquals( expected, actual );
}
@Test