Normalize spec when creating jar URL by removing /../ and /./
Previously when Handler was creating a URL from a context URL and a spec, any occurrances of /../ or /./ in the spec would be left as-is. This differed from the JDK's Handler implementation which normalizes the URL by modifying the path to remove any occurrences of /../ or /./ This commit updates our Handler implementation to align it with the JDK's. Tests have been added to assert that, given the same inputs, the two Handler classes produce the same output. Closes gh-9917
This commit is contained in:
parent
3b0cb1c4f2
commit
7a87c69dd0
|
@ -203,7 +203,34 @@ public class Handler extends URLStreamHandler {
|
|||
}
|
||||
|
||||
private void setFile(URL context, String file) {
|
||||
setURL(context, JAR_PROTOCOL, null, -1, null, null, file, null, null);
|
||||
setURL(context, JAR_PROTOCOL, null, -1, null, null, normalize(file), null, null);
|
||||
}
|
||||
|
||||
private String normalize(String file) {
|
||||
int afterLastSeparatorIndex = file.lastIndexOf(SEPARATOR) + SEPARATOR.length();
|
||||
String afterSeparator = file.substring(afterLastSeparatorIndex);
|
||||
afterSeparator = replaceParentDir(afterSeparator);
|
||||
afterSeparator = replaceCurrentDir(afterSeparator);
|
||||
return file.substring(0, afterLastSeparatorIndex) + afterSeparator;
|
||||
}
|
||||
|
||||
private String replaceParentDir(String file) {
|
||||
int parentDirIndex;
|
||||
while ((parentDirIndex = file.indexOf("/../")) >= 0) {
|
||||
int precedingSlashIndex = file.lastIndexOf('/', parentDirIndex - 1);
|
||||
if (precedingSlashIndex >= 0) {
|
||||
file = file.substring(0, precedingSlashIndex)
|
||||
+ file.substring(parentDirIndex + 3);
|
||||
}
|
||||
else {
|
||||
file = file.substring(parentDirIndex + 4);
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private String replaceCurrentDir(String file) {
|
||||
return file.replace("/./", "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -136,6 +136,36 @@ public class HandlerTests {
|
|||
new URL("jar:file:/test.jar!/BOOT-INF/classes/foo.txt")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void urlWithSpecReferencingParentDirectory() throws MalformedURLException {
|
||||
assertStandardAndCustomHandlerUrlsAreEqual(
|
||||
"file:/test.jar!/BOOT-INF/classes!/xsd/folderA/a.xsd",
|
||||
"../folderB/b.xsd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void urlWithSpecReferencingAncestorDirectoryOutsideJarStopsAtJarRoot()
|
||||
throws MalformedURLException {
|
||||
assertStandardAndCustomHandlerUrlsAreEqual(
|
||||
"file:/test.jar!/BOOT-INF/classes!/xsd/folderA/a.xsd",
|
||||
"../../../../../../folderB/b.xsd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void urlWithSpecReferencingCurrentDirectory() throws MalformedURLException {
|
||||
assertStandardAndCustomHandlerUrlsAreEqual(
|
||||
"file:/test.jar!/BOOT-INF/classes!/xsd/folderA/a.xsd",
|
||||
"./folderB/./b.xsd");
|
||||
}
|
||||
|
||||
private void assertStandardAndCustomHandlerUrlsAreEqual(String context, String spec)
|
||||
throws MalformedURLException {
|
||||
URL standardUrl = new URL(new URL("jar:" + context), spec);
|
||||
URL customHandlerUrl = new URL(new URL("jar", null, -1, context, this.handler),
|
||||
spec);
|
||||
assertThat(customHandlerUrl.toString()).isEqualTo(standardUrl.toString());
|
||||
}
|
||||
|
||||
private URL createUrl(String file) throws MalformedURLException {
|
||||
return new URL("jar", null, -1, file, this.handler);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue