diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2023-08-05 17:34:07 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-05 17:34:07 -0400 |
commit | 6b0f75d1f50bf7afa47ba6ae369bca967754cf21 (patch) | |
tree | b009ff0af5eb9c08593766e09a5d42f9e097f0fe | |
parent | 8ae706293149fb6e3d40af3ac80a8661fa379111 (diff) |
fix(unstable): vendor cache override should handle forbidden windows directory names (#20069)
Meant to do this earlier.
-rw-r--r-- | cli/cache/http_cache/local.rs | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/cli/cache/http_cache/local.rs b/cli/cache/http_cache/local.rs index 833c6e935..8a7cd8850 100644 --- a/cli/cache/http_cache/local.rs +++ b/cli/cache/http_cache/local.rs @@ -332,6 +332,19 @@ fn url_to_local_sub_path( static FORBIDDEN_CHARS: Lazy<HashSet<char>> = Lazy::new(|| { HashSet::from(['?', '<', '>', ':', '*', '|', '\\', ':', '"', '\'', '/']) }); + // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file + static FORBIDDEN_WINDOWS_NAMES: Lazy<HashSet<&'static str>> = + Lazy::new(|| { + let set = HashSet::from([ + "con", "prn", "aux", "nul", "com0", "com1", "com2", "com3", "com4", + "com5", "com6", "com7", "com8", "com9", "lpt0", "lpt1", "lpt2", "lpt3", + "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", + ]); + // ensure everything is lowercase because we'll be comparing + // lowercase filenames against this + debug_assert!(set.iter().all(|s| s.to_lowercase() == *s)); + set + }); fn has_forbidden_chars(segment: &str) -> bool { segment.chars().any(|c| { @@ -405,7 +418,11 @@ fn url_to_local_sub_path( }; // the hash symbol at the start designates a hash for the url part - hash_context_specific || part.starts_with('#') || has_forbidden_chars(part) + hash_context_specific + || part.starts_with('#') + || has_forbidden_chars(part) + || last_ext.is_none() && FORBIDDEN_WINDOWS_NAMES.contains(part) + || part.ends_with('.') } // get the base url @@ -811,6 +828,19 @@ mod test { &[("content-type", "application/javascript")], "deno.land/x/#mod.ts_e8c36.js", ); + run_test( + // not allowed windows folder name + "https://deno.land/x/con/con.ts", + &[], + "deno.land/x/#con_1143d/con.ts", + ); + run_test( + // disallow ending a directory with a period + // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file + "https://deno.land/x/test./main.ts", + &[], + "deno.land/x/#test._4ee3d/main.ts", + ); #[track_caller] fn run_test(url: &str, headers: &[(&str, &str)], expected: &str) { |