471388 - StringIndexOutOfBoundsException when using <c:url> with parameters

+ Cleaning up HttpURITest
+ Creating parameterized HttpURIParseTest from various separate test
  cases in former HttpURITest
  + Currently @Ignored
  + Test Parse from String
  + Test Parse from URI
  + Test Parse result differences with java.net.URI
+ Adding more testcases to demonstrate bug
This commit is contained in:
Joakim Erdfelt 2015-06-29 17:35:34 -07:00
parent f644926b2b
commit b522cf0bd8
2 changed files with 178 additions and 125 deletions

View File

@ -0,0 +1,177 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class HttpURIParseTest
{
public static int INPUT=0,SCHEME=1,HOST=2,PORT=3,PATH=4,PARAM=5,QUERY=6,FRAGMENT=7;
@Parameters(name="{0}")
public static List<String[]> data()
{
String[][] tests = {
{"/path/to/context",null,null,"-1","/path/to/context",null,null,null},
{"http://example.com/path/to/context;param?query=%22value%22#fragment","http","example.com","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]/path/to/context;param?query=%22value%22#fragment","http","[::1]","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://example.com:8080/path/to/context;param?query=%22value%22#fragment","http","example.com","8080","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]:8080/path/to/context;param?query=%22value%22#fragment","http","[::1]","8080","/path/to/context;param","param","query=%22value%22","fragment"},
{"/path/info",null,null,null,"/path/info",null,null,null},
{"/path/info#fragment",null,null,null,"/path/info",null,null,"fragment"},
{"/path/info?query",null,null,null,"/path/info",null,"query",null},
{"/path/info?query#fragment",null,null,null,"/path/info",null,"query","fragment"},
{"/path/info;param",null,null,null,"/path/info;param","param",null,null},
{"/path/info;param#fragment",null,null,null,"/path/info;param","param",null,"fragment"},
{"/path/info;param?query",null,null,null,"/path/info;param","param","query",null},
{"/path/info;param?query#fragment",null,null,null,"/path/info;param","param","query","fragment"},
{"//host/path/info",null,null,null,"//host/path/info",null,null,null},
{"//user@host/path/info",null,null,null,"//user@host/path/info",null,null,null},
{"//user@host:8080/path/info",null,null,null,"//user@host:8080/path/info",null,null,null},
{"//host:8080/path/info",null,null,null,"//host:8080/path/info",null,null,null},
{"http:/path/info","http",null,null,"/path/info",null,null,null},
{"http:/path/info#fragment","http",null,null,"/path/info",null,null,"fragment"},
{"http:/path/info?query","http",null,null,"/path/info",null,"query",null},
{"http:/path/info?query#fragment","http",null,null,"/path/info",null,"query","fragment"},
{"http:/path/info;param","http",null,null,"/path/info;param","param",null,null},
{"http:/path/info;param#fragment","http",null,null,"/path/info;param","param",null,"fragment"},
{"http:/path/info;param?query","http",null,null,"/path/info;param","param","query",null},
{"http:/path/info;param?query#fragment","http",null,null,"/path/info;param","param","query","fragment"},
{"http://user@host:8080/path/info;param?query#fragment","http","host","8080","/path/info;param","param","query","fragment"},
{"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","host","8080","/path/info;param","param","query","fragment"},
{"http:///;?#","http","",null,"/;","","",""},
{"/path/info?a=?query",null,null,null,"/path/info",null,"a=?query",null},
{"/path/info?a=;query",null,null,null,"/path/info",null,"a=;query",null},
{"//host:8080//",null,null,null,"//host:8080//",null,null,null},
{"file:///path/info","file","",null,"/path/info",null,null,null},
{"//",null,null,null,"//",null,null,null},
{"http://localhost/","http","localhost",null,"/",null,null,null},
{"http://localhost:8080/", "http", "localhost","8080","/", null, null,null},
{"http://localhost/?x=y", "http", "localhost",null,"/", null,"x=y",null},
{"/;param",null, null,null,"/;param", "param",null,null},
{"/?x=y",null, null,null,"/", null,"x=y",null},
{"/?abc=test",null, null,null,"/", null,"abc=test",null},
{"/#fragment",null, null,null,"/", null,null,"fragment"},
{"http://192.0.0.1:8080/","http","192.0.0.1","8080","/",null,null,null},
{"http://[2001:db8::1]:8080/","http","[2001:db8::1]","8080","/",null,null,null},
{"http://user@[2001:db8::1]:8080/","http","[2001:db8::1]","8080","/",null,null,null},
{"http://[2001:db8::1]/","http","[2001:db8::1]",null,"/",null,null,null},
{"//[2001:db8::1]:8080/",null,null,null,"//[2001:db8::1]:8080/",null,null,null},
{"http://user@[2001:db8::1]:8080/","http","[2001:db8::1]","8080","/",null,null,null},
{"*",null,null,null,"*",null, null,null},
{"http://host:8080/path/info?q1=v1&q2=v2","http","host","8080","/path/info",null,"q1=v1&q2=v2",null},
{"/path/info?q1=v1&q2=v2",null,null,null,"/path/info",null,"q1=v1&q2=v2",null},
{"/info?q1=v1&q2=v2",null,null,null,"/info",null,"q1=v1&q2=v2",null},
// FIXME (Bad Path/Query results) {"info?q1=v1&q2=v2",null,null,null,"info",null,"q1=v1&q2=v2",null},
// FIXME (StringIndexOutOfBoundsException) {"info;q1=v1?q2=v2",null,null,null,"info;q1=v1",null,"q2=v2",null},
{"?q1=v1&q2=v2",null,null,null,null,null,"q1=v1&q2=v2",null}
};
return Arrays.asList(tests);
}
@Parameter(0)
public String input;
@Parameter(1)
public String scheme;
@Parameter(2)
public String host;
@Parameter(3)
public String port;
@Parameter(4)
public String path;
@Parameter(5)
public String param;
@Parameter(6)
public String query;
@Parameter(7)
public String fragment;
@Test
public void testParseString() throws Exception
{
HttpURI httpUri = new HttpURI(input);
assertThat("["+input+"] .scheme", httpUri.getScheme(), is(scheme));
assertThat("["+input+"] .host", httpUri.getHost(), is(host));
assertThat("["+input+"] .port", httpUri.getPort(), is(port==null?-1:Integer.parseInt(port)));
assertThat("["+input+"] .path", httpUri.getPath(), is(path));
assertThat("["+input+"] .param", httpUri.getParam(), is(param));
assertThat("["+input+"] .query", httpUri.getQuery(), is(query));
assertThat("["+input+"] .fragment", httpUri.getFragment(), is(fragment));
assertThat("["+input+"] .toString", httpUri.toString(), is(input));
}
@Test
@Ignore("There are many examples of inconsistent results from .testParseString()")
public void testParseURI() throws Exception
{
URI javaUri = new URI(input);
HttpURI httpUri = new HttpURI(javaUri);
assertThat("["+input+"] .scheme", httpUri.getScheme(), is(scheme));
assertThat("["+input+"] .host", httpUri.getHost(), is(host));
assertThat("["+input+"] .port", httpUri.getPort(), is(port==null?-1:Integer.parseInt(port)));
assertThat("["+input+"] .path", httpUri.getPath(), is(path));
assertThat("["+input+"] .param", httpUri.getParam(), is(param));
assertThat("["+input+"] .query", httpUri.getQuery(), is(query));
assertThat("["+input+"] .fragment", httpUri.getFragment(), is(fragment));
assertThat("["+input+"] .toString", httpUri.toString(), is(input));
}
@Test
@Ignore("There are many examples of inconsistent results from .testParseString()")
public void testCompareToJavaNetURI() throws Exception
{
URI javaUri = new URI(input);
HttpURI httpUri = new HttpURI(javaUri);
assertThat("["+input+"] .scheme", httpUri.getScheme(), is(javaUri.getScheme()));
assertThat("["+input+"] .host", httpUri.getHost(), is(javaUri.getHost()));
assertThat("["+input+"] .port", httpUri.getPort(), is(javaUri.getPort()));
assertThat("["+input+"] .path", httpUri.getPath(), is(javaUri.getPath()));
// Not Relevant for java.net.URI assertThat("["+input+"] .param", httpUri.getParam(), is(param));
assertThat("["+input+"] .query", httpUri.getQuery(), is(javaUri.getRawQuery()));
assertThat("["+input+"] .fragment", httpUri.getFragment(), is(javaUri.getFragment()));
assertThat("["+input+"] .toString", httpUri.toString(), is(javaUri.toASCIIString()));
}
}

View File

@ -19,12 +19,9 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -34,128 +31,8 @@ import org.eclipse.jetty.util.Utf8Appendable;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
/* ------------------------------------------------------------ */
public class HttpURITest public class HttpURITest
{ {
String[][] tests=
{
{"/path/to/context",null,null,"-1","/path/to/context",null,null,null},
{"http://example.com/path/to/context;param?query=%22value%22#fragment","http","example.com","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]/path/to/context;param?query=%22value%22#fragment","http","[::1]","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://example.com:8080/path/to/context;param?query=%22value%22#fragment","http","example.com","8080","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]:8080/path/to/context;param?query=%22value%22#fragment","http","[::1]","8080","/path/to/context;param","param","query=%22value%22","fragment"},
};
public static int
INPUT=0,SCHEME=1,HOST=2,PORT=3,PATH=4,PARAM=5,QUERY=6,FRAGMENT=7;
/* ------------------------------------------------------------ */
@Test
public void testFromString() throws Exception
{
for (String[] test:tests)
{
HttpURI uri = new HttpURI(test[INPUT]);
assertEquals(test[SCHEME], uri.getScheme());
assertEquals(test[HOST], uri.getHost());
assertEquals(Integer.parseInt(test[PORT]), uri.getPort());
assertEquals(test[PATH], uri.getPath());
assertEquals(test[PARAM], uri.getParam());
assertEquals(test[QUERY], uri.getQuery());
assertEquals(test[FRAGMENT], uri.getFragment());
}
}
/* ------------------------------------------------------------ */
@Test
public void testFromURI() throws Exception
{
for (String[] test:tests)
{
URI u=new URI(test[INPUT]);
HttpURI uri = new HttpURI(u);
assertEquals(test[SCHEME], uri.getScheme());
assertEquals(test[HOST], uri.getHost());
assertEquals(Integer.parseInt(test[PORT]), uri.getPort());
assertEquals(test[PATH], uri.getPath());
assertEquals(test[PARAM], uri.getParam());
assertEquals(test[QUERY], uri.getQuery());
assertEquals(test[FRAGMENT], uri.getFragment());
assertEquals(u,uri.toURI());
}
}
private final String[][] path_tests=
{
/* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
/* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
/* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
/* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
/* 4*/ {"/path/info;param",null,null,null,null,"/path/info;param","param",null,null},
/* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info;param","param",null,"fragment"},
/* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info;param","param","query",null},
/* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info;param","param","query","fragment"},
/* 8*/ {"//host/path/info",null,null,null,null,"//host/path/info",null,null,null},
/* 9*/ {"//user@host/path/info",null,null,null,null,"//user@host/path/info",null,null,null},
/*10*/ {"//user@host:8080/path/info",null,null,null,null,"//user@host:8080/path/info",null,null,null},
/*11*/ {"//host:8080/path/info",null,null,null,null,"//host:8080/path/info",null,null,null},
/*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
/*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
/*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
/*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
/*16*/ {"http:/path/info;param","http",null,null,null,"/path/info;param","param",null,null},
/*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info;param","param",null,"fragment"},
/*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info;param","param","query",null},
/*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info;param","param","query","fragment"},
/*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info;param","param","query","fragment"},
/*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info;param","param","query","fragment"},
/*22*/ {"http:///;?#","http","//","",null,"/;","","",""},
/*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
/*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
/*25*/ {"//host:8080//",null,null,null,null,"//host:8080//",null,null,null},
/*26*/ {"file:///path/info","file","//","",null,"/path/info",null,null,null},
/*27*/ {"//",null,null,null,null,"//",null,null,null},
/*28*/ {"http://localhost/","http","//localhost","localhost",null,"/",null,null,null},
/*29*/ {"http://localhost:8080/", "http", "//localhost:8080", "localhost","8080","/", null, null,null},
/*30*/ {"http://localhost/?x=y", "http", "//localhost", "localhost",null,"/", null,"x=y",null},
/*31*/ {"/;param",null, null, null,null,"/;param", "param",null,null},
/*32*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*33*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null},
/*34*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
/*35*/ {"http://192.0.0.1:8080/","http","//192.0.0.1:8080","192.0.0.1","8080","/",null,null,null},
/*36*/ {"http://[2001:db8::1]:8080/","http","//[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*37*/ {"http://user@[2001:db8::1]:8080/","http","//user@[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*38*/ {"http://[2001:db8::1]/","http","//[2001:db8::1]","[2001:db8::1]",null,"/",null,null,null},
/*39*/ {"//[2001:db8::1]:8080/",null,null,null,null,"//[2001:db8::1]:8080/",null,null,null},
/*40*/ {"http://user@[2001:db8::1]:8080/","http","//user@[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*41*/ {"*",null,null,null,null,"*",null, null,null}
};
@Test
public void testPathURIs() throws Exception
{
HttpURI uri = new HttpURI();
for (int t=0;t<path_tests.length;t++)
{
uri.parse(path_tests[t][0]);
assertEquals(t+" "+path_tests[t][0],path_tests[t][1],uri.getScheme());
assertEquals(t+" "+path_tests[t][0],path_tests[t][3],uri.getHost());
assertEquals(t+" "+path_tests[t][0],path_tests[t][4]==null?-1:Integer.parseInt(path_tests[t][4]),uri.getPort());
assertEquals(t+" "+path_tests[t][0],path_tests[t][5],uri.getPath());
assertEquals(t+" "+path_tests[t][0],path_tests[t][6],uri.getParam());
assertEquals(t+" "+path_tests[t][0],path_tests[t][7],uri.getQuery());
assertEquals(t+" "+path_tests[t][0],path_tests[t][8],uri.getFragment());
assertEquals(path_tests[t][0], uri.toString());
}
}
@Test @Test
public void testInvalidAddress() throws Exception public void testInvalidAddress() throws Exception
{ {
@ -244,7 +121,6 @@ public class HttpURITest
assertEquals("/foo;abc=123/bar;jsessionid=12345",uri.getPath()); assertEquals("/foo;abc=123/bar;jsessionid=12345",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath()); assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals("jsessionid=12345",uri.getParam()); assertEquals("jsessionid=12345",uri.getParam());
} }
@Test @Test