summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--std/wasi/snapshot_preview1.ts36
-rw-r--r--std/wasi/snapshot_preview1_test.ts14
m---------std/wasi/testdata0
3 files changed, 44 insertions, 6 deletions
diff --git a/std/wasi/snapshot_preview1.ts b/std/wasi/snapshot_preview1.ts
index dc2648efc..c8246b280 100644
--- a/std/wasi/snapshot_preview1.ts
+++ b/std/wasi/snapshot_preview1.ts
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { resolve } from "../path/mod.ts";
+import { relative, resolve } from "../path/mod.ts";
const CLOCKID_REALTIME = 0;
const CLOCKID_MONOTONIC = 1;
@@ -83,7 +83,7 @@ const _ERRNO_STALE = 72;
const ERRNO_TIMEDOUT = 73;
const _ERRNO_TXTBSY = 74;
const _ERRNO_XDEV = 75;
-const _ERRNO_NOTCAPABLE = 76;
+const ERRNO_NOTCAPABLE = 76;
const RIGHTS_FD_DATASYNC = 0x0000000000000001n;
const RIGHTS_FD_READ = 0x0000000000000002n;
@@ -1201,9 +1201,35 @@ export default class Context {
return ERRNO_INVAL;
}
- const text = new TextDecoder();
- const data = new Uint8Array(this.memory.buffer, pathOffset, pathLength);
- const path = resolve(entry.path!, text.decode(data));
+ const textDecoder = new TextDecoder();
+ const pathData = new Uint8Array(
+ this.memory.buffer,
+ pathOffset,
+ pathLength,
+ );
+ const resolvedPath = resolve(entry.path!, textDecoder.decode(pathData));
+
+ if (relative(entry.path, resolvedPath).startsWith("..")) {
+ return ERRNO_NOTCAPABLE;
+ }
+
+ let path;
+ if (
+ (dirflags & LOOKUPFLAGS_SYMLINK_FOLLOW) == LOOKUPFLAGS_SYMLINK_FOLLOW
+ ) {
+ try {
+ path = Deno.realPathSync(resolvedPath);
+
+ console.log("RESOLVED REAL PATH: %s", path);
+ if (relative(entry.path, path).startsWith("..")) {
+ return ERRNO_NOTCAPABLE;
+ }
+ } catch (_err) {
+ path = resolvedPath;
+ }
+ } else {
+ path = resolvedPath;
+ }
if ((oflags & OFLAGS_DIRECTORY) !== 0) {
// XXX (caspervonb) this isn't ideal as we can't get a rid for the
diff --git a/std/wasi/snapshot_preview1_test.ts b/std/wasi/snapshot_preview1_test.ts
index 99f9145c7..a159a634c 100644
--- a/std/wasi/snapshot_preview1_test.ts
+++ b/std/wasi/snapshot_preview1_test.ts
@@ -35,6 +35,7 @@ const tests = [
"testdata/wasi_fd_write_file.wasm",
"testdata/wasi_fd_write_stderr.wasm",
"testdata/wasi_fd_write_stdout.wasm",
+ "testdata/wasi_path_open.wasm",
"testdata/wasi_proc_exit.wasm",
"testdata/wasi_random_get.wasm",
"testdata/wasi_sched_yield.wasm",
@@ -46,9 +47,13 @@ const ignore = [
// TODO(caspervonb) investigate why these tests are failing on windows and fix
// them.
+// The failing tests all involve symlinks in some way, my best guess so far is
+// that there's something going wrong with copying the symlinks over to the
+// temporary working directory, but only in some cases.
if (Deno.build.os == "windows") {
ignore.push("testdata/std_fs_metadata.wasm");
ignore.push("testdata/std_fs_read_dir.wasm");
+ ignore.push("testdata/wasi_path_open.wasm");
}
const rootdir = path.dirname(path.fromFileUrl(import.meta.url));
@@ -64,7 +69,14 @@ for (const pathname of tests) {
);
const options = JSON.parse(prelude);
- const workdir = await Deno.makeTempDir();
+ // TODO(caspervonb) investigate more.
+ // On Windows creating a tempdir in the default directory breaks nearly
+ // all the tests, possibly due to symlinks pointing to the original file
+ // which crosses drive boundaries.
+ const workdir = await Deno.makeTempDir({
+ dir: testdir,
+ });
+
await copy(
path.join(testdir, "fixtures"),
path.join(workdir, "fixtures"),
diff --git a/std/wasi/testdata b/std/wasi/testdata
-Subproject ffbe85d2315ae0104534f38037903de38b6f2e6
+Subproject 324366afb925a3974c6135390c280aff9c4e0e9