Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions java/org/apache/catalina/util/RequestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,40 @@ public static String stripPathParams(String input, Request request) {
}


/**
* Strip parameters for given path.
*
* @param input the input path
* @param request the request to add the parameters to
*
* @return the cleaned path
*/
public static String stripPathParams(String input) {
// Shortcut
if (input.indexOf(';') < 0) {
return input;
}

StringBuilder sb = new StringBuilder(input.length());
int pos = 0;
int limit = input.length();
while (pos < limit) {
int nextSemiColon = input.indexOf(';', pos);
if (nextSemiColon < 0) {
nextSemiColon = limit;
}
sb.append(input, pos, nextSemiColon);
int followingSlash = input.indexOf('/', nextSemiColon);
if (followingSlash < 0) {
pos = limit;
} else {
pos = followingSlash;
}
}

return sb.toString();
}

/**
* Tests whether the provided URL is for a resource contained within the same web application as the request.
*
Expand Down Expand Up @@ -148,14 +182,26 @@ public static boolean isSameWebApplication(HttpServletRequest request, URL url)
}

/*
* This isn't perfect but is the best that can be done without running the full mapping logic on the url to
* determine which web application that url will map to.
* May not perfect, but try best to determine whether the url belongs to current request or not.
*/
if (!url.getPath().startsWith(request.getServletContext().getContextPath())) {
String urlPath = url.getPath();
urlPath = stripPathParams(urlPath);
urlPath = org.apache.tomcat.util.http.RequestUtil.normalize(urlPath);
String requestContextPath = request.getServletContext().getContextPath();

if(urlPath==null) {
return false;
}

if(urlPath.equals(requestContextPath)) {
return true;
} else if(requestContextPath.endsWith("/") && urlPath.startsWith(requestContextPath)) {
return true;
} else if(urlPath.startsWith(requestContextPath+"/")) {
return true;
} else {
return false;
}

return true;
}


Expand Down
27 changes: 25 additions & 2 deletions test/org/apache/catalina/connector/TestResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,11 @@ public void testBug53062p() throws Exception {


private void doTestEncodeURL(String location, String expected) {
Request req = new TesterRequest(true);
doTestEncodeURL("", location, expected);
}

private void doTestEncodeURL(String currentContextPath, String location, String expected) {
Request req = new TesterRequest(true,"/level1/level2/foo.html", currentContextPath);
req.setRequestedSessionId("1234");
req.setRequestedSessionURL(true);
Response resp = new Response(null);
Expand All @@ -359,7 +363,6 @@ private void doTestEncodeURL(String location, String expected) {
Assert.assertEquals(expected, result);
}


@Test
public void testEncodeURL01() throws Exception {
doTestEncodeURL("./bar.html", "./bar.html;jsessionid=1234");
Expand Down Expand Up @@ -454,7 +457,27 @@ public void testEncodeURL16() throws Exception {
doTestEncodeURL("./..#/../..", "./..;jsessionid=1234#/../..");
}

@Test
public void testEncodeURLBug70208a() throws Exception {
doTestEncodeURL("/admin", "/admin/index", "/admin/index;jsessionid=1234");
}

@Test
public void testEncodeURLBug70208b() throws Exception {
doTestEncodeURL("/admin", "/admin/../public/index", "/admin/../public/index");
}

@Test
public void testEncodeURLBug70208c() throws Exception {
doTestEncodeURL("/admin", "/public/..;/admin/index;jsessionid=zzz",
"/public/..;/admin/index;jsessionid=zzz;jsessionid=1234");
}

@Test
public void testEncodeURLBug70208d() throws Exception {
doTestEncodeURL("/admin", "/administrator/index",
"/administrator/index");
}
private void doTestEncodeRedirectURL(String location, String expected) {
Request req = new TesterRequest(true);
req.setRequestedSessionId("1234");
Expand Down
9 changes: 6 additions & 3 deletions test/org/apache/tomcat/unittest/TesterRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,13 @@ public TesterRequest(String requestUri) {


public TesterRequest(boolean withSession, String requestUri) {
this(withSession, requestUri, "");
}

public TesterRequest(boolean withSession, String requestUri, String reqContextPath) {
super(null, null);
context = new TesterContext();
servletContext = new TesterServletContext();
servletContext = new TesterServletContext(reqContextPath);
context.setServletContext(servletContext);
if (withSession) {
Set<SessionTrackingMode> modes = new HashSet<>();
Expand All @@ -71,8 +75,7 @@ public TesterRequest(boolean withSession, String requestUri) {
}
this.requestUri = requestUri;
}



@Override
public String getScheme() {
return "http";
Expand Down
11 changes: 10 additions & 1 deletion test/org/apache/tomcat/unittest/TesterServletContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,23 @@

public class TesterServletContext implements ServletContext {

private String contextPath = "";

public TesterServletContext() {
this("");
}

public TesterServletContext(String contextPath) {
this.contextPath=contextPath;
}
/**
* {@inheritDoc}
* <p>
* This test implementation is hard coded to return an empty String.
*/
@Override
public String getContextPath() {
return "";
return contextPath;
}

/**
Expand Down