Throw on canonincalization of paths which do not exists
Per `canonicalize` documentation.
diff --git a/okio/src/jvmMain/kotlin/okio/ZipFileSystem.kt b/okio/src/jvmMain/kotlin/okio/ZipFileSystem.kt
index dcf46b1..f7f98d4 100644
--- a/okio/src/jvmMain/kotlin/okio/ZipFileSystem.kt
+++ b/okio/src/jvmMain/kotlin/okio/ZipFileSystem.kt
@@ -69,8 +69,11 @@
private val comment: String?
) : FileSystem() {
override fun canonicalize(path: Path): Path {
- // TODO(jwilson): throw FileNotFoundException if the canonical file doesn't exist.
- return canonicalizeInternal(path)
+ val canonical = canonicalizeInternal(path)
+ if (canonical !in entries) {
+ throw FileNotFoundException("$path")
+ }
+ return canonical
}
/** Don't throw [FileNotFoundException] if the path doesn't identify a file. */
diff --git a/okio/src/jvmTest/java/okio/ZipFileSystemTest.kt b/okio/src/jvmTest/java/okio/ZipFileSystemTest.kt
index c2ef186..c9f2d29 100644
--- a/okio/src/jvmTest/java/okio/ZipFileSystemTest.kt
+++ b/okio/src/jvmTest/java/okio/ZipFileSystemTest.kt
@@ -446,6 +446,38 @@
assertThat(zipFileSystem.list("/".toPath()))
.containsExactly("/hello.txt".toPath())
}
+
+ @Test
+ fun canonicalizationValid() {
+ val zipPath = ZipBuilder(base)
+ .addEntry("hello.txt", "Hello World")
+ .addEntry("directory/child.txt", "Another file!")
+ .build()
+ val zipFileSystem = fileSystem.openZip(zipPath)
+
+ assertThat(zipFileSystem.canonicalize("/".toPath())).isEqualTo("/".toPath())
+ assertThat(zipFileSystem.canonicalize(".".toPath())).isEqualTo("/".toPath())
+ assertThat(zipFileSystem.canonicalize("not/a/path/../../..".toPath())).isEqualTo("/".toPath())
+ assertThat(zipFileSystem.canonicalize("hello.txt".toPath())).isEqualTo("/hello.txt".toPath())
+ assertThat(zipFileSystem.canonicalize("stuff/../hello.txt".toPath())).isEqualTo("/hello.txt".toPath())
+ assertThat(zipFileSystem.canonicalize("directory".toPath())).isEqualTo("/directory".toPath())
+ assertThat(zipFileSystem.canonicalize("directory/whevs/..".toPath())).isEqualTo("/directory".toPath())
+ assertThat(zipFileSystem.canonicalize("directory/child.txt".toPath())).isEqualTo("/directory/child.txt".toPath())
+ assertThat(zipFileSystem.canonicalize("directory/whevs/../child.txt".toPath())).isEqualTo("/directory/child.txt".toPath())
+ }
+
+ @Test
+ fun canonicalizationInvalidThrows() {
+ val zipPath = ZipBuilder(base)
+ .addEntry("hello.txt", "Hello World")
+ .addEntry("directory/child.txt", "Another file!")
+ .build()
+ val zipFileSystem = fileSystem.openZip(zipPath)
+
+ assertFailsWith<FileNotFoundException> {
+ zipFileSystem.canonicalize("not/a/path".toPath())
+ }
+ }
}
private fun ByteString.replaceAll(a: ByteString, b: ByteString): ByteString {