mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-05 13:29:13 +00:00
Issue #3983 - JarFileResource directory listing is invalid
+ Correcting encoded path searching + Adding more unit tests to ensure no regression Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
f65e59cadf
commit
472ede48cd
@ -29,7 +29,6 @@ import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
@ -116,9 +115,11 @@ public class JarFileResource extends JarResource
|
||||
_jarFile = null;
|
||||
_list = null;
|
||||
|
||||
int sep = _urlString.lastIndexOf("!/");
|
||||
_jarUrl = _urlString.substring(0, sep + 2);
|
||||
_path = URIUtil.decodePath(_urlString.substring(sep + 2));
|
||||
// Work with encoded URL path
|
||||
String urlFilePath = _url.getPath();
|
||||
int sep = urlFilePath.lastIndexOf("!/");
|
||||
_jarUrl = urlFilePath.substring(0, sep + 2);
|
||||
_path = URIUtil.decodePath(urlFilePath.substring(sep + 2));
|
||||
if (_path.length() == 0)
|
||||
_path = null;
|
||||
_jarFile = _jarConnection.getJarFile();
|
||||
@ -316,11 +317,12 @@ public class JarFileResource extends JarResource
|
||||
}
|
||||
|
||||
Enumeration<JarEntry> e = jarFile.entries();
|
||||
String dir = _urlString.substring(_urlString.lastIndexOf("!/") + 2);
|
||||
String encodedDir = _urlString.substring(_urlString.lastIndexOf("!/") + 2);
|
||||
String dir = URIUtil.decodePath(encodedDir);
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
JarEntry entry = e.nextElement();
|
||||
String name = StringUtil.replace(entry.getName(), '\\', '/');
|
||||
String name = entry.getName();
|
||||
if (!name.startsWith(dir) || name.length() == dir.length())
|
||||
{
|
||||
continue;
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.eclipse.jetty.util.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -41,6 +42,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
@ -138,9 +140,9 @@ public class JarResourceTest
|
||||
@Test
|
||||
public void testJarFileCopyToDirectoryTraversal() throws Exception
|
||||
{
|
||||
Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/extract.zip");
|
||||
Path extractZip = MavenTestingUtils.getTestResourcePathFile("TestData/extract.zip");
|
||||
|
||||
String s = "jar:" + testZip.toUri().toASCIIString() + "!/";
|
||||
String s = "jar:" + extractZip.toUri().toASCIIString() + "!/";
|
||||
Resource r = Resource.newResource(s);
|
||||
|
||||
assertThat(r, instanceOf(JarResource.class));
|
||||
@ -188,6 +190,78 @@ public class JarResourceTest
|
||||
assertTrue(r.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJarFileResourceList() throws Exception
|
||||
{
|
||||
Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar");
|
||||
String uri = "jar:" + testJar.toUri().toASCIIString() + "!/";
|
||||
|
||||
Resource resource = new JarFileResource(URI.create(uri).toURL());
|
||||
Resource rez = resource.addPath("rez/");
|
||||
|
||||
assertThat("path /rez/ is a dir", rez.isDirectory(), is(true));
|
||||
|
||||
List<String> actual = Arrays.asList(rez.list());
|
||||
String[] expected = new String[]{
|
||||
"one",
|
||||
"aaa",
|
||||
"bbb",
|
||||
"oddities/",
|
||||
"another dir/",
|
||||
"ccc",
|
||||
"deep/",
|
||||
};
|
||||
assertThat("Dir contents", actual, containsInAnyOrder(expected));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a file listing of a Directory in a JAR
|
||||
* Where the JAR entries contain names that are URI encoded / escaped
|
||||
*/
|
||||
@Test
|
||||
public void testJarFileResourceList_PreEncodedEntries() throws Exception
|
||||
{
|
||||
Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar");
|
||||
String uri = "jar:" + testJar.toUri().toASCIIString() + "!/";
|
||||
|
||||
Resource resource = new JarFileResource(URI.create(uri).toURL());
|
||||
Resource rez = resource.addPath("rez/oddities/");
|
||||
|
||||
assertThat("path /rez/oddities/ is a dir", rez.isDirectory(), is(true));
|
||||
|
||||
List<String> actual = Arrays.asList(rez.list());
|
||||
String[] expected = new String[]{
|
||||
";",
|
||||
"#hashcode",
|
||||
"index.html#fragment",
|
||||
"other%2fkind%2Fof%2fslash", // pre-encoded / escaped
|
||||
"a file with a space",
|
||||
";\" onmousedown=\"alert(document.location)\"",
|
||||
"some\\slash\\you\\got\\there" // not encoded, stored as backslash native
|
||||
};
|
||||
assertThat("Dir contents", actual, containsInAnyOrder(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJarFileResourceList_DirWithSpace() throws Exception
|
||||
{
|
||||
Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar");
|
||||
String uri = "jar:" + testJar.toUri().toASCIIString() + "!/";
|
||||
|
||||
Resource resource = new JarFileResource(URI.create(uri).toURL());
|
||||
Resource anotherDir = resource.addPath("rez/another dir/");
|
||||
|
||||
assertThat("path /rez/another dir/ is a dir", anotherDir.isDirectory(), is(true));
|
||||
|
||||
List<String> actual = Arrays.asList(anotherDir.list());
|
||||
String[] expected = new String[]{
|
||||
"a file.txt",
|
||||
"another file.txt",
|
||||
"..\\a different file.txt",
|
||||
};
|
||||
assertThat("Dir contents", actual, containsInAnyOrder(expected));
|
||||
}
|
||||
|
||||
private List<Path> listFiles(Path dir) throws IOException
|
||||
{
|
||||
return Files.list(dir).collect(Collectors.toList());
|
||||
|
BIN
jetty-util/src/test/resources/jar-file-resource.jar
Normal file
BIN
jetty-util/src/test/resources/jar-file-resource.jar
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user