diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-05-08 14:39:06 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-08 14:39:06 -0600 |
commit | 9f7f681e26887a9b284a2f25e8252c3a5077f348 (patch) | |
tree | 19315e1b11ab3597b2055966b8b6dd93780af298 | |
parent | 547ce6c3b82c5e0c04dfb902f609cb229a2bde9a (diff) |
fix(runtime): allow nul device on windows (#23741)
Fixes [23721](https://github.com/denoland/deno/issues/23721)
-rw-r--r-- | ext/fs/std_fs.rs | 15 | ||||
-rw-r--r-- | runtime/permissions/lib.rs | 6 | ||||
-rw-r--r-- | tests/specs/permission/special/main.js | 2 |
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; } } } |