summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/fs/std_fs.rs15
-rw-r--r--runtime/permissions/lib.rs6
-rw-r--r--tests/specs/permission/special/main.js2
3 files changed, 19 insertions, 4 deletions
diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs
index 6bc15a72d..9e2acedcc 100644
--- a/ext/fs/std_fs.rs
+++ b/ext/fs/std_fs.rs
@@ -890,7 +890,15 @@ fn open_with_access_check(
access_check: Option<AccessCheckCb>,
) -> FsResult<std::fs::File> {
if let Some(access_check) = access_check {
- let path = if path.is_absolute() {
+ let path_bytes = path.as_os_str().as_encoded_bytes();
+ let is_windows_device_path = cfg!(windows)
+ && path_bytes.starts_with(br"\\.\")
+ && !path_bytes.contains(&b':');
+ let path = if is_windows_device_path {
+ // On Windows, normalize_path doesn't work with device-prefix-style
+ // paths. We pass these through.
+ path.to_owned()
+ } else if path.is_absolute() {
normalize_path(path)
} else {
let cwd = current_dir()?;
@@ -898,8 +906,8 @@ fn open_with_access_check(
};
(*access_check)(false, &path, &options)?;
// On Linux, /proc may contain magic links that we don't want to resolve
- let needs_canonicalization =
- !cfg!(target_os = "linux") || path.starts_with("/proc");
+ let needs_canonicalization = !is_windows_device_path
+ && (!cfg!(target_os = "linux") || path.starts_with("/proc"));
let path = if needs_canonicalization {
match path.canonicalize() {
Ok(path) => path,
@@ -916,7 +924,6 @@ fn open_with_access_check(
} else {
path
};
-
(*access_check)(true, &path, &options)?;
// For windows
diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs
index e66f16a7f..70d1abae7 100644
--- a/runtime/permissions/lib.rs
+++ b/runtime/permissions/lib.rs
@@ -1696,6 +1696,12 @@ impl PermissionsContainer {
self.check_was_allow_all_flag_passed().map_err(error_all)?;
}
} else if cfg!(target_os = "windows") {
+ // \\.\nul is allowed
+ let s = path.as_os_str().as_encoded_bytes();
+ if s.eq_ignore_ascii_case(br#"\\.\nul"#) {
+ return Ok(());
+ }
+
fn is_normalized_windows_drive_path(path: &Path) -> bool {
let s = path.as_os_str().as_encoded_bytes();
// \\?\X:\
diff --git a/tests/specs/permission/special/main.js b/tests/specs/permission/special/main.js
index 53a7adc9e..59ec4f7b5 100644
--- a/tests/specs/permission/special/main.js
+++ b/tests/specs/permission/special/main.js
@@ -5,6 +5,7 @@ const testCases = [
// Allowed, safe
[["darwin", "linux"], null, "/dev/null"],
[["darwin", "linux"], null, "/etc/passwd"],
+ [["windows"], null, "\\\\.\\nul"],
// Denied, requires `--allow-all`
[["darwin", "linux"], /PermissionDenied/, "/dev/ptmx"],
[["linux"], /PermissionDenied/, "/proc/self/environ"],
@@ -40,6 +41,7 @@ for (const [oses, error, file] of testCases) {
console.log(`Got an error (expected) for ${file}: ${e}`);
} else {
console.log(`*** Got an unexpected error for ${file}: ${e}`);
+ failed = true;
}
}
}