diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
commit | 7e5d7eea9c580ef4b41a765bde624af431942b96 (patch) | |
tree | 2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/dunce | |
parent | Adding debian version 1.70.0+dfsg1-9. (diff) | |
download | rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/dunce')
-rw-r--r-- | vendor/dunce/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/dunce/Cargo.toml | 42 | ||||
-rw-r--r-- | vendor/dunce/LICENSE | 121 | ||||
-rw-r--r-- | vendor/dunce/README.md | 17 | ||||
-rw-r--r-- | vendor/dunce/src/lib.rs | 324 |
5 files changed, 505 insertions, 0 deletions
diff --git a/vendor/dunce/.cargo-checksum.json b/vendor/dunce/.cargo-checksum.json new file mode 100644 index 000000000..3bb53b2b9 --- /dev/null +++ b/vendor/dunce/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"97bcc4c25e6528ec52bf3df5202dc0e9eacdd3e7ff93c51f5d89c41b88e63b5f","LICENSE":"a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499","README.md":"890653901012199b8780375755a8a0b5b6eafcded2c3bccace87099bdfba9274","src/lib.rs":"ed0d70d8b377aed2d43d574acdcc54a4bc33a73241c4c7058838197543f48156"},"package":"0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c"}
\ No newline at end of file diff --git a/vendor/dunce/Cargo.toml b/vendor/dunce/Cargo.toml new file mode 100644 index 000000000..f414baec2 --- /dev/null +++ b/vendor/dunce/Cargo.toml @@ -0,0 +1,42 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "dunce" +version = "1.0.3" +authors = ["Kornel <kornel@geekhood.net>"] +description = "Normalize Windows paths to the most compatible format, avoiding UNC where possible" +homepage = "https://lib.rs/crates/dunce" +documentation = "https://docs.rs/dunce" +readme = "README.md" +keywords = [ + "realpath", + "unc", + "canonicalize", + "windows", + "deunc", +] +categories = ["filesystem"] +license = "CC0-1.0 OR MIT-0" +repository = "https://gitlab.com/kornelski/dunce" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[badges.appveyor] +repository = "pornel/dunce" + +[badges.gitlab] +repository = "kornelski/dunce" + +[badges.maintenance] +status = "passively-maintained" diff --git a/vendor/dunce/LICENSE b/vendor/dunce/LICENSE new file mode 100644 index 000000000..0e259d42c --- /dev/null +++ b/vendor/dunce/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/vendor/dunce/README.md b/vendor/dunce/README.md new file mode 100644 index 000000000..40a9c1032 --- /dev/null +++ b/vendor/dunce/README.md @@ -0,0 +1,17 @@ +# Dunce (de-UNC) + +In Windows the regular paths (`C:\foo`) are supported by all programs, +but have lots of bizarre restrictions for backwards compatibility with MS-DOS. +There are also Windows NT UNC paths (`\\?\C:\foo`), which are more robust and with fewer gotchas, +but are rarely supported by Windows programs. Even Microsoft's own! + +This crate converts Windows UNC paths to the MS-DOS-compatible format whenever possible, +but leaves UNC paths as-is when they can't be unambiguously expressed in a simpler way. +This allows legacy programs to access all paths they can possibly access, +and doesn't break any paths for UNC-aware programs. + +In Rust the worst UNC offender is the `fs::canonicalize()` function. This crate provides +a drop-in replacement for it that returns paths you'd expect. + +On non-Windows platforms these functions leave paths unmodified, so it's safe to use them +unconditionally for all platforms. diff --git a/vendor/dunce/src/lib.rs b/vendor/dunce/src/lib.rs new file mode 100644 index 000000000..8f11ec0e2 --- /dev/null +++ b/vendor/dunce/src/lib.rs @@ -0,0 +1,324 @@ +//! Filesystem paths in Windows are a total mess. This crate normalizes paths to the most +//! compatible (but still correct) format, so that you don't have to worry about the mess. +//! +//! In Windows the regular/legacy paths (`C:\foo`) are supported by all programs, but have +//! lots of bizarre restrictions for backwards compatibility with MS-DOS. +//! +//! And there are Windows NT UNC paths (`\\?\C:\foo`), which are more robust and with fewer +//! gotchas, but are rarely supported by Windows programs. Even Microsoft's own! +//! +//! This crate converts paths to legacy format whenever possible, but leaves UNC paths as-is +//! when they can't be unambiguously expressed in a simpler way. This allows legacy programs +//! to access all paths they can possibly access, and UNC-aware programs to access all paths. +//! +//! On non-Windows platforms these functions leave paths unmodified, so it's safe to use them +//! unconditionally for all platforms. +//! +//! Parsing is based on https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx +//! +//! [Project homepage](https://crates.rs/crates/dunce). +#![doc(html_logo_url = "https://assets.gitlab-static.net/uploads/-/system/project/avatar/4717715/dyc.png")] + +#[cfg(any(windows, test))] +use std::ffi::OsStr; +use std::fs; +use std::io; +#[cfg(windows)] +use std::os::windows::ffi::OsStrExt; +#[cfg(windows)] +use std::path::{Component, Prefix}; +use std::path::{Path, PathBuf}; + +/// Takes any path, and when possible, converts Windows UNC paths to regular paths. +/// +/// On non-Windows this is no-op. +/// +/// `\\?\C:\Windows` will be converted to `C:\Windows`, +/// but `\\?\C:\COM` will be left as-is (due to a reserved filename). +/// +/// Use this to pass arbitrary paths to programs that may not be UNC-aware. +/// It's generally safe to pass UNC paths to legacy programs, because +/// the paths contain a reserved character, so will gracefully fail +/// if used with wrong APIs. +/// +/// This function does not perform any I/O. +/// +/// Currently paths with unpaired surrogates aren't converted even if they +/// can be due to limitations of Rust's `OsStr` API. +#[inline] +pub fn simplified(path: &Path) -> &Path { + if is_safe_to_strip_unc(path) { + // unfortunately we can't safely strip prefix from a non-Unicode path + path.to_str().and_then(|s| s.get(4..)).map(Path::new).unwrap_or(path) + } else { + path + } +} + +/// Like `std::fs::canonicalize()`, but on Windows it outputs the most +/// compatible form of a path instead of UNC. +#[inline(always)] +pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> { + let path = path.as_ref(); + + #[cfg(not(windows))] + { + fs::canonicalize(path) + } + #[cfg(windows)] + { + canonicalize_win(path) + } +} + +#[cfg(windows)] +fn canonicalize_win(path: &Path) -> io::Result<PathBuf> { + let real_path = fs::canonicalize(path)?; + Ok(if is_safe_to_strip_unc(&real_path) { + real_path.to_str().and_then(|s| s.get(4..)).map(PathBuf::from).unwrap_or(real_path) + } else { + real_path + }) +} + +pub use self::canonicalize as realpath; + +#[cfg(any(windows,test))] +fn windows_char_len(s: &OsStr) -> usize { + #[cfg(not(windows))] + let len = s.to_string_lossy().chars().map(|c| if c as u32 <= 0xFFFF {1} else {2}).sum(); + #[cfg(windows)] + let len = s.encode_wide().count(); + len +} + +#[cfg(any(windows,test))] +fn is_valid_filename(file_name: &OsStr) -> bool { + let file_name = file_name.as_ref(); + if windows_char_len(file_name) > 255 { + return false; + } + + // Non-unicode is safe, but Rust can't reasonably losslessly operate on such strings + let file_name = if let Some(s) = file_name.to_str() { + s + } else { + return false; + }; + if file_name.is_empty() { + return false; + } + // Only ASCII subset is checked, and UTF-8 is safe for that + let byte_str = file_name.as_bytes(); + for &c in byte_str { + match c { + 0..=31 | + b'<' | b'>' | b':' | b'"' | + b'/' | b'\\' | b'|' | b'?' | b'*' => return false, + _ => {}, + } + } + + // Filename can't end with . or space (except before extension, but this checks the whole name) + let last_char = byte_str[byte_str.len()-1]; + if last_char == b' ' || last_char == b'.' { + return false; + } + true +} + +#[cfg(any(windows, test))] +const RESERVED_NAMES: [&'static str; 22] = [ + "AUX", "NUL", "PRN", "CON", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", + "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", +]; + +#[cfg(any(windows, test))] +fn is_reserved<P: AsRef<OsStr>>(file_name: P) -> bool { + // con.txt is reserved too + if let Some(stem) = Path::new(&file_name).file_stem() { + // all reserved DOS names have ASCII-compatible stem + if let Some(name) = stem.to_str() { + // "con.. .txt" is "CON" for DOS + let trimmed = right_trim(name); + if trimmed.len() <= 4 { + for name in &RESERVED_NAMES { + if name.eq_ignore_ascii_case(trimmed) { + return true; + } + } + } + } + } + false +} + +#[cfg(not(windows))] +#[inline] +fn is_safe_to_strip_unc(_path: &Path) -> bool { + false +} + +#[cfg(windows)] +fn is_safe_to_strip_unc(path: &Path) -> bool { + let mut components = path.components(); + match components.next() { + Some(Component::Prefix(p)) => match p.kind() { + Prefix::VerbatimDisk(..) => {}, + _ => return false, // Other kinds of UNC paths + }, + _ => return false, // relative or empty + } + + for component in components { + match component { + Component::RootDir => {}, + Component::Normal(file_name) => { + // it doesn't allocate in most cases, + // and checks are interested only in the ASCII subset, so lossy is fine + if !is_valid_filename(file_name) || is_reserved(file_name) { + return false; + } + } + _ => return false, // UNC paths take things like ".." literally + }; + } + + if windows_char_len(path.as_os_str()) > 260 { // However, if the path is going to be used as a directory it's 248 + return false; + } + true +} + +/// Trim '.' and ' ' +#[cfg(any(windows, test))] +fn right_trim(mut s: &str) -> &str { + while s.len() > 0 { + let last = s.len()-1; + unsafe { + if s.as_bytes()[last] == b'.' || s.as_bytes()[last] == b' ' { + s = s.get_unchecked(0..last) // trim of ASCII byte can't break UTF-8 + } else { + break; + } + } + } + s +} + +#[test] +fn trim_test() { + assert_eq!("a", right_trim("a.")); + assert_eq!("ą", right_trim("ą.")); + assert_eq!("a", right_trim("a ")); + assert_eq!("ąą", right_trim("ąą ")); + assert_eq!("a", right_trim("a. . . .... ")); + assert_eq!("a. . . ..ź", right_trim("a. . . ..ź.. ")); + assert_eq!(" b", right_trim(" b")); + assert_eq!(" べ", right_trim(" べ")); + assert_eq!("c. c", right_trim("c. c.")); + assert_eq!("。", right_trim("。")); + assert_eq!("", right_trim("")); +} + +#[test] +fn reserved() { + assert!(is_reserved("CON")); + assert!(is_reserved("con")); + assert!(is_reserved("con.con")); + assert!(is_reserved("COM4")); + assert!(is_reserved("COM4.txt")); + assert!(is_reserved("COM4 .txt")); + assert!(is_reserved("con.")); + assert!(is_reserved("con .")); + assert!(is_reserved("con ")); + assert!(is_reserved("con . ")); + assert!(is_reserved("con . .txt")); + assert!(is_reserved("con.....txt")); + assert!(is_reserved("PrN.....")); + + assert!(!is_reserved(" PrN.....")); + assert!(!is_reserved(" CON")); + assert!(!is_reserved("COM0")); + assert!(!is_reserved("COM77")); + assert!(!is_reserved(" CON ")); + assert!(!is_reserved(".CON")); + assert!(!is_reserved("@CON")); + assert!(!is_reserved("not.CON")); + assert!(!is_reserved("CON。")); +} + +#[test] +fn len() { + assert_eq!(1, windows_char_len(OsStr::new("a"))); + assert_eq!(1, windows_char_len(OsStr::new("€"))); + assert_eq!(1, windows_char_len(OsStr::new("本"))); + assert_eq!(2, windows_char_len(OsStr::new("🧐"))); + assert_eq!(2, windows_char_len(OsStr::new("®®"))); +} + +#[test] +fn valid() { + assert!(!is_valid_filename("..".as_ref())); + assert!(!is_valid_filename(".".as_ref())); + assert!(!is_valid_filename("aaaaaaaaaa:".as_ref())); + assert!(!is_valid_filename("ą:ą".as_ref())); + assert!(!is_valid_filename("".as_ref())); + assert!(!is_valid_filename("a ".as_ref())); + assert!(!is_valid_filename(" a. ".as_ref())); + assert!(!is_valid_filename("a/".as_ref())); + assert!(!is_valid_filename("/a".as_ref())); + assert!(!is_valid_filename("/".as_ref())); + assert!(!is_valid_filename("\\".as_ref())); + assert!(!is_valid_filename("\\a".as_ref())); + assert!(!is_valid_filename("<x>".as_ref())); + assert!(!is_valid_filename("a*".as_ref())); + assert!(!is_valid_filename("?x".as_ref())); + assert!(!is_valid_filename("a\0a".as_ref())); + assert!(!is_valid_filename("\x1f".as_ref())); + assert!(!is_valid_filename(::std::iter::repeat("a").take(257).collect::<String>().as_ref())); + + assert!(is_valid_filename(::std::iter::repeat("®").take(254).collect::<String>().as_ref())); + assert!(is_valid_filename("ファイル".as_ref())); + assert!(is_valid_filename("a".as_ref())); + assert!(is_valid_filename("a.aaaaaaaa".as_ref())); + assert!(is_valid_filename("a........a".as_ref())); + assert!(is_valid_filename(" b".as_ref())); +} + +#[test] +#[cfg(windows)] +fn realpath_test() { + assert_eq!(r"C:\WINDOWS", canonicalize(r"C:\Windows").unwrap().to_str().unwrap().to_uppercase()); + assert_ne!(r".", canonicalize(r".").unwrap().to_str().unwrap()); +} + +#[test] +#[cfg(windows)] +fn strip() { + assert_eq!(Path::new(r"C:\foo\😀"), simplified(Path::new(r"\\?\C:\foo\😀"))); + assert_eq!(Path::new(r"\\?\serv\"), simplified(Path::new(r"\\?\serv\"))); + assert_eq!(Path::new(r"\\.\C:\notdisk"), simplified(Path::new(r"\\.\C:\notdisk"))); + assert_eq!(Path::new(r"\\?\GLOBALROOT\Device\ImDisk0\path\to\file.txt"), simplified(Path::new(r"\\?\GLOBALROOT\Device\ImDisk0\path\to\file.txt"))); +} + +#[test] +#[cfg(windows)] +fn safe() { + assert!(is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\bar"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\Z:\foo\bar\"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\Z:\😀\🎃\"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\c:\foo"))); + + let long = ::std::iter::repeat("®").take(160).collect::<String>(); + assert!(is_safe_to_strip_unc(Path::new(&format!(r"\\?\c:\{}", long)))); + assert!(!is_safe_to_strip_unc(Path::new(&format!(r"\\?\c:\{}\{}", long, long)))); + + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\.\bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\..\bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c\foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c\foo/bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c:foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\cc:foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c:foo\bar"))); +} |