You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/05/08 22:16:28 UTC
[maven-surefire] 02/02: [SUREFIRE-1617] Surefire fails with bad
message when path contains whitespaces and colon
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch SUREFIRE-1617
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit ed82d7f6cea63a6aa3aef057f5e784fc22854565
Author: tibordigana <ti...@apache.org>
AuthorDate: Sun Apr 7 23:06:45 2019 +0200
[SUREFIRE-1617] Surefire fails with bad message when path contains whitespaces and colon
---
.../booterclient/JarManifestForkConfiguration.java | 56 ++++++++++++--------
.../JarManifestForkConfigurationTest.java | 61 +++++++++++++++++++++-
2 files changed, 94 insertions(+), 23 deletions(-)
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
index 62fa4c1..1a3dd4f 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
@@ -31,8 +31,9 @@ import javax.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
@@ -43,8 +44,11 @@ import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.isDirectory;
import static org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
+import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri.absolute;
+import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri.relative;
import static org.apache.maven.surefire.util.internal.StringUtils.NL;
/**
@@ -168,14 +172,11 @@ public final class JarManifestForkConfiguration
@Nonnull Path classPathElement,
@Nonnull File dumpLogDirectory,
boolean dumpError )
- throws IOException
{
try
{
- String relativeUriPath = relativize( parent, classPathElement )
- .replace( '\\', '/' );
-
- return new ClasspathElementUri( new URI( null, relativeUriPath, null ) );
+ String relativePath = relativize( parent, classPathElement );
+ return relative( escapeUri( relativePath, UTF_8 ) );
}
catch ( IllegalArgumentException e )
{
@@ -190,15 +191,7 @@ public final class JarManifestForkConfiguration
.dumpStreamText( error, dumpLogDirectory );
}
- return new ClasspathElementUri( toAbsoluteUri( classPathElement ) );
- }
- catch ( URISyntaxException e )
- {
- // This is really unexpected, so fail
- throw new IOException( "Could not create a relative path "
- + classPathElement
- + " against "
- + parent, e );
+ return absolute( toAbsoluteUri( classPathElement ) );
}
}
@@ -207,16 +200,37 @@ public final class JarManifestForkConfiguration
final String uri;
final boolean absolute;
- ClasspathElementUri( String uri )
+ private ClasspathElementUri( String uri, boolean absolute )
{
this.uri = uri;
- absolute = true;
+ this.absolute = absolute;
}
- ClasspathElementUri( URI uri )
+ static ClasspathElementUri absolute( String uri )
+ {
+ return new ClasspathElementUri( uri, true );
+ }
+
+ static ClasspathElementUri relative( String uri )
+ {
+ return new ClasspathElementUri( uri, false );
+ }
+ }
+
+ static String escapeUri( String input, Charset encoding )
+ {
+ try
+ {
+ String uriFormEncoded = URLEncoder.encode( input, encoding.name() );
+
+ String uriPathEncoded = uriFormEncoded.replaceAll( "\\+", "%20" );
+ uriPathEncoded = uriPathEncoded.replaceAll( "%2F|%5C", "/" );
+
+ return uriPathEncoded;
+ }
+ catch ( UnsupportedEncodingException e )
{
- this.uri = uri.toASCIIString();
- absolute = false;
+ throw new IllegalStateException( "avoided by using Charset" );
}
}
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfigurationTest.java
index 5e71238..08b3030 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfigurationTest.java
@@ -22,14 +22,18 @@ package org.apache.maven.plugin.surefire.booterclient;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
import java.nio.file.Path;
import org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri;
import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.relativize;
import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.toAbsoluteUri;
import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.toClasspathElementUri;
+import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.escapeUri;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.AfterClass;
@@ -39,7 +43,9 @@ import org.junit.runner.RunWith;
import static org.fest.util.Files.delete;
import static org.fest.util.Files.newTemporaryFolder;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.same;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
@@ -88,6 +94,8 @@ public class JarManifestForkConfigurationTest
.thenReturn( "../../../.m2/repository/grp/art/1.0/art-1.0.jar" );
when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
.thenCallRealMethod();
+ when( escapeUri( anyString(), any( Charset.class ) ) )
+ .thenCallRealMethod();
assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
.isEqualTo( "../../../.m2/repository/grp/art/1.0/art-1.0.jar" );
}
@@ -105,6 +113,8 @@ public class JarManifestForkConfigurationTest
.thenReturn( "../../../../../the Maven repo/grp/art/1.0/art-1.0.jar" );
when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
.thenCallRealMethod();
+ when( escapeUri( anyString(), any( Charset.class ) ) )
+ .thenCallRealMethod();
assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
.isEqualTo( "../../../../../the%20Maven%20repo/grp/art/1.0/art-1.0.jar" );
}
@@ -122,6 +132,8 @@ public class JarManifestForkConfigurationTest
.thenReturn( "..\\..\\..\\Users\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
.thenCallRealMethod();
+ when( escapeUri( anyString(), any( Charset.class ) ) )
+ .thenCallRealMethod();
assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
.isEqualTo( "../../../Users/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
}
@@ -134,11 +146,14 @@ public class JarManifestForkConfigurationTest
Path parent = mock( Path.class );
when( parent.toString() ).thenReturn( "C:\\Windows\\Temp\\surefire" );
Path classPathElement = mock( Path.class );
- when( classPathElement.toString() ).thenReturn( "C:\\Test User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
+ when( classPathElement.toString() )
+ .thenReturn("C:\\Test User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar");
when( relativize( parent, classPathElement ) )
.thenReturn( "..\\..\\..\\Test User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
.thenCallRealMethod();
+ when( escapeUri( anyString(), any( Charset.class ) ) )
+ .thenCallRealMethod();
assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
.isEqualTo( "../../../Test%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
}
@@ -168,6 +183,8 @@ public class JarManifestForkConfigurationTest
.thenThrow( new IllegalArgumentException() );
when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
.thenCallRealMethod();
+ when( escapeUri( anyString(), any( Charset.class ) ) )
+ .thenCallRealMethod();
when( toAbsoluteUri( same( classPathElement ) ) )
.thenCallRealMethod();
assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
@@ -175,6 +192,46 @@ public class JarManifestForkConfigurationTest
}
@Test
+ public void shouldEscapeUri()
+ throws Exception
+ {
+ assertThat( escapeUri( "a", UTF_8 ) ).isEqualTo( "a" );
+ assertThat( escapeUri( " ", UTF_8 ) ).isEqualTo( "%20" );
+ assertThat( escapeUri( "%", UTF_8 ) ).isEqualTo( "%25" );
+ assertThat( escapeUri( "+", UTF_8 ) ).isEqualTo( "%2B" );
+ assertThat( escapeUri( ",", UTF_8 ) ).isEqualTo( "%2C" );
+ assertThat( escapeUri( "/", UTF_8 ) ).isEqualTo( "/" );
+ assertThat( escapeUri( "7", UTF_8 ) ).isEqualTo( "7" );
+ assertThat( escapeUri( ":", UTF_8 ) ).isEqualTo( "%3A" );
+ assertThat( escapeUri( "@", UTF_8 ) ).isEqualTo( "%40" );
+ assertThat( escapeUri( "A", UTF_8 ) ).isEqualTo( "A" );
+ assertThat( escapeUri( "[", UTF_8 ) ).isEqualTo( "%5B" );
+ assertThat( escapeUri( "\\", UTF_8 ) ).isEqualTo( "/" );
+ assertThat( escapeUri( "]", UTF_8 ) ).isEqualTo( "%5D" );
+ assertThat( escapeUri( "`", UTF_8 ) ).isEqualTo( "%60" );
+ assertThat( escapeUri( "a", UTF_8 ) ).isEqualTo( "a" );
+ assertThat( escapeUri( "{", UTF_8 ) ).isEqualTo( "%7B" );
+ assertThat( escapeUri( "" + (char) 0xFF, UTF_8 ) ).isEqualTo( "%C3%BF" );
+
+ assertThat( escapeUri( "..\\..\\..\\Test : User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar",
+ UTF_8 ) )
+ .isEqualTo( "../../../Test%20%3A%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
+
+ assertThat( escapeUri( "..\\..\\..\\Test : User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar",
+ Charset.defaultCharset() ) )
+ .isEqualTo( "../../../Test%20%3A%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
+
+ assertThat( escapeUri( "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire", UTF_8 ) )
+ .isEqualTo( "../../surefire-its/target/junit-pathWith%C3%9Cmlaut_1/target/surefire" );
+
+ String source = "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire";
+ String encoded = escapeUri( "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire", UTF_8 );
+ String decoded = URLDecoder.decode( encoded, UTF_8.name() );
+ assertThat( decoded )
+ .isEqualTo( source );
+ }
+
+ @Test
public void shouldRelativizeOnRealPlatform()
{
Path parentDir = new File( TMP, "test-parent-1" )
@@ -218,6 +275,6 @@ public class JarManifestForkConfigurationTest
ClasspathElementUri testDirUriPath = toClasspathElementUri( parentDir, testDir, dumpDirectory, true );
assertThat( testDirUriPath.uri )
- .isEqualTo( "../@3%20test%20with%20white%20spaces" );
+ .isEqualTo( "../%403%20test%20with%20white%20spaces" );
}
}