Skip to content

Commit

Permalink
Also handle canonicalizing relative paths
Browse files Browse the repository at this point in the history
  • Loading branch information
squarejesse committed Aug 2, 2023
1 parent b900105 commit 3871b9b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ abstract class AbstractFileSystemTest(
@Test
fun canonicalizeDotReturnsCurrentWorkingDirectory() {
if (fileSystem.isFakeFileSystem || fileSystem is ForwardingFileSystem) return
if (isWasiFileSystem) return // Canonicalize is limited on WASI.
val cwd = fileSystem.canonicalize(".".toPath())
val cwdString = cwd.toString()
val slash = Path.DIRECTORY_SEPARATOR
assertTrue(cwdString) {
if (isWrappingJimFileSystem) {
cwdString.endsWith("work")
} else if (isWasiFileSystem) {
cwdString.endsWith("/tmp")
} else {
cwdString.endsWith("okio${slash}okio") ||
cwdString.endsWith("${slash}okio-parent-okio-nodefilesystem-test") ||
Expand Down Expand Up @@ -233,7 +234,6 @@ abstract class AbstractFileSystemTest(
@Test
fun canonicalizeReturnsShallowerPath() {
if (!supportsSymlink()) return
if (isWasiFileSystem) return // Canonicalize is limited on WASI.
val base = fileSystem.canonicalize(base)

val expected = base / "a.txt"
Expand Down Expand Up @@ -269,12 +269,10 @@ abstract class AbstractFileSystemTest(
fileSystem.write("a.txt".toPath()) {
writeUtf8("hello, world!")
}
} else if (isWrappingJimFileSystem) {
} else if (isWrappingJimFileSystem || isWasiFileSystem) {
fileSystem.write("a.txt".toPath()) {
writeUtf8("hello, world!")
}
} else if (isWasiFileSystem) {
return // TODO: implement this behavior.
}

val entries = fileSystem.list(".".toPath())
Expand All @@ -284,7 +282,6 @@ abstract class AbstractFileSystemTest(
@Test
fun listOnRelativePathWhichIsNotDotReturnsRelativePaths() {
if (isNodeJsFileSystem) return
if (isWasiFileSystem) return // TODO: implement this behavior.

// Make sure there's always at least one file so our assertion is useful. We copy the first 2
// entries of the real working directory of the JVM to validate the results on all environment.
Expand All @@ -300,7 +297,7 @@ abstract class AbstractFileSystemTest(
fileSystem.write(apiDir / "okio.api".toPath()) {
writeUtf8("hello, world!")
}
} else if (isWrappingJimFileSystem) {
} else if (isWrappingJimFileSystem || isWasiFileSystem) {
val apiDir = "api".toPath()
fileSystem.createDirectory(apiDir)
fileSystem.write(apiDir / "okio.api".toPath()) {
Expand Down Expand Up @@ -336,7 +333,6 @@ abstract class AbstractFileSystemTest(
@Test
fun listOrNullOnRelativePathWhichIsNotDotReturnsRelativePaths() {
if (isNodeJsFileSystem) return
if (isWasiFileSystem) return // TODO: implement this behavior.

// Make sure there's always at least one file so our assertion is useful. We copy the first 2
// entries of the real working directory of the JVM to validate the results on all environment.
Expand Down
20 changes: 13 additions & 7 deletions okio-wasifilesystem/src/wasmMain/kotlin/okio/WasiFileSystem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ object WasiFileSystem : FileSystem() {
if (dirNameErrno != 0) throw ErrnoException(dirNameErrno.toShort())
val dirName = bufPointer.readString(size)
val dirNamePath = dirName.toPath()
add(Preopen(dirNamePath.segmentsBytes, fd))
add(Preopen(dirNamePath, dirNamePath.segmentsBytes, fd))
}
}
}
Expand All @@ -94,15 +94,20 @@ object WasiFileSystem : FileSystem() {
?: throw IllegalStateException("no preopens")

override fun canonicalize(path: Path): Path {
val absolutePath = when {
path.isAbsolute -> path
else -> relativePathPreopen.path.resolve(path, normalize = true)
}

// There's no APIs in preview1 to canonicalize a path. We give it a best effort by resolving
// all symlinks, but this could result in a relative path.
val candidate = resolveSymlinks(path, 0)
val result = resolveSymlinks(absolutePath, 0).normalized()

if (!candidate.isAbsolute) {
throw IOException("WASI preview1 cannot canonicalize relative paths")
check(result.isAbsolute) {
"Canonicalize $path returned non-absolute path: $result"
}

return candidate
return result
}

private fun resolveSymlinks(
Expand All @@ -118,7 +123,7 @@ object WasiFileSystem : FileSystem() {
else -> null
}
val pathWithResolvedParent = when {
resolvedParent != null -> resolvedParent / path.name
resolvedParent != null -> resolvedParent.resolve(path.name)
else -> path
}

Expand All @@ -127,7 +132,7 @@ object WasiFileSystem : FileSystem() {

val resolvedSymlinkTarget = when {
symlinkTarget.isAbsolute -> symlinkTarget
resolvedParent != null -> resolvedParent / symlinkTarget
resolvedParent != null -> resolvedParent.resolve(symlinkTarget)
else -> symlinkTarget
}

Expand Down Expand Up @@ -500,6 +505,7 @@ object WasiFileSystem : FileSystem() {
override fun toString() = "okio.WasiFileSystem"

private class Preopen(
val path: Path,
val segmentsBytes: List<ByteString>,
val fd: fd,
)
Expand Down

0 comments on commit 3871b9b

Please sign in to comment.