[MNG-6703] DefaultUrlNormalizer doesn't normalize all relative URIs

* Switch behaviour on relative URIs to match Path#normalize()
* Adopt RFC 3986 behaviour for traversal past the root
* Add a test that this isn't applied to relative URI references

This closes #264
This commit is contained in:
Joseph Walton 2019-05-20 22:17:24 +10:00 committed by Michael Osipov
parent 7ba9700386
commit 4fa882c30f
2 changed files with 37 additions and 24 deletions

View File

@ -43,10 +43,15 @@ public class DefaultUrlNormalizer
while ( true )
{
int idx = result.indexOf( "/../" );
if ( idx <= 0 )
if ( idx < 0 )
{
break;
}
else if ( idx == 0 )
{
result = result.substring( 3 );
continue;
}
int parent = idx - 1;
while ( parent >= 0 && result.charAt( parent ) == '/' )
{
@ -55,9 +60,12 @@ public class DefaultUrlNormalizer
parent = result.lastIndexOf( '/', parent );
if ( parent < 0 )
{
break;
result = result.substring( idx + 4 );
}
else
{
result = result.substring( 0, parent ) + result.substring( idx + 3 );
}
result = result.substring( 0, parent ) + result.substring( idx + 3 );
}
}

View File

@ -19,45 +19,31 @@ package org.apache.maven.model.path;
* under the License.
*/
import junit.framework.TestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
/**
* @author Benjamin Bentmann
*/
public class DefaultUrlNormalizerTest
extends TestCase
{
private UrlNormalizer normalizer;
@Override
protected void setUp()
throws Exception
{
super.setUp();
normalizer = new DefaultUrlNormalizer();
}
@Override
protected void tearDown()
throws Exception
{
normalizer = null;
super.tearDown();
}
private UrlNormalizer normalizer = new DefaultUrlNormalizer();
private String normalize( String url )
{
return normalizer.normalize( url );
}
@Test
public void testNullSafe()
{
assertNull( normalize( null ) );
}
@Test
public void testTrailingSlash()
{
assertEquals( "", normalize( "" ) );
@ -65,6 +51,7 @@ public class DefaultUrlNormalizerTest
assertEquals( "http://server.org/dir/", normalize( "http://server.org/dir/" ) );
}
@Test
public void testRemovalOfParentRefs()
{
assertEquals( "http://server.org/child", normalize( "http://server.org/parent/../child" ) );
@ -74,6 +61,7 @@ public class DefaultUrlNormalizerTest
assertEquals( "http://server.org/child", normalize( "http://server.org/parent//../child" ) );
}
@Test
public void testPreservationOfDoubleSlashes()
{
assertEquals( "scm:hg:ssh://localhost//home/user", normalize( "scm:hg:ssh://localhost//home/user" ) );
@ -82,4 +70,21 @@ public class DefaultUrlNormalizerTest
normalize( "[fetch=]http://server.org/[push=]ssh://server.org/" ) );
}
@Test
public void absolutePathTraversalPastRootIsOmitted()
{
assertEquals( "/", normalize("/../" ) );
}
@Test
public void parentDirectoryRemovedFromRelativeUriReference()
{
assertEquals( "", normalize( "a/../" ) );
}
@Test
public void leadingParentDirectoryNotRemovedFromRelativeUriReference()
{
assertEquals( "../", normalize( "../" ) );
}
}