From dfb97d8b229b2b3cb2e36a36afebc3f7f0605a5d Mon Sep 17 00:00:00 2001 From: jdkboy Date: Fri, 5 Feb 2021 13:57:54 +0800 Subject: [PATCH] add add-dunce-lib.patch to avoid accssing to Cargo --- add-dunce-lib.patch | 363 ++++++++++++++++++++++++++++++++++++++++++++ icedtea-web.spec | 6 +- 2 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 add-dunce-lib.patch diff --git a/add-dunce-lib.patch b/add-dunce-lib.patch new file mode 100644 index 0000000..4477b18 --- /dev/null +++ b/add-dunce-lib.patch @@ -0,0 +1,363 @@ +diff --git a/rust-launcher/Cargo.toml b/rust-launcher/Cargo.toml +index 61ee308..58bc763 100644 +--- a/rust-launcher/Cargo.toml ++++ b/rust-launcher/Cargo.toml +@@ -2,7 +2,3 @@ + name = "launcher" + version = "1.8.0" + authors = ["https://icedtea.classpath.org/wiki/IcedTea-Web"] +- +-[dependencies] +-[target.'cfg(windows)'.dependencies] +-dunce = "0.1.1" +diff --git a/rust-launcher/src/dirs_paths_helper.rs b/rust-launcher/src/dirs_paths_helper.rs +index a83011d..c0faa79 100644 +--- a/rust-launcher/src/dirs_paths_helper.rs ++++ b/rust-launcher/src/dirs_paths_helper.rs +@@ -1,12 +1,10 @@ + use os_access; ++use dunce; + + use std; + use std::io; + use std::env; + +-#[cfg(windows)] extern crate dunce; +- +- + pub static ICEDTEA_WEB: &'static str = "icedtea-web"; + pub static DEPLOYMENT_PROPERTIES: &'static str = "deployment.properties"; + +diff --git a/rust-launcher/src/dunce.rs b/rust-launcher/src/dunce.rs +new file mode 100644 +index 0000000..68b4249 +--- /dev/null ++++ b/rust-launcher/src/dunce.rs +@@ -0,0 +1,315 @@ ++//! 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. ++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. ++#[cfg(windows)] ++pub fn canonicalize>(path: P) -> io::Result { ++ 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 ++ }) ++} ++ ++/// Like `std::fs::canonicalize()`, but on Windows it outputs the most ++/// compatible form of a path instead of UNC. ++#[cfg(not(windows))] ++#[inline] ++pub fn canonicalize>(path: P) -> io::Result { ++ fs::canonicalize(path) ++} ++ ++pub use self::canonicalize as realpath; ++ ++#[cfg(any(windows,test))] ++fn windows_char_len(s: &OsStr) -> usize { ++ #[cfg(unix)] ++ 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: P) -> 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>(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))] ++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("..")); ++ assert!(!is_valid_filename(".")); ++ assert!(!is_valid_filename("aaaaaaaaaa:")); ++ assert!(!is_valid_filename("ą:ą")); ++ assert!(!is_valid_filename("")); ++ assert!(!is_valid_filename("a ")); ++ assert!(!is_valid_filename(" a. ")); ++ assert!(!is_valid_filename("a/")); ++ assert!(!is_valid_filename("/a")); ++ assert!(!is_valid_filename("/")); ++ assert!(!is_valid_filename("\\")); ++ assert!(!is_valid_filename("\\a")); ++ assert!(!is_valid_filename("")); ++ assert!(!is_valid_filename("a*")); ++ assert!(!is_valid_filename("?x")); ++ assert!(!is_valid_filename("a\0a")); ++ assert!(!is_valid_filename("\x1f")); ++ assert!(!is_valid_filename(::std::iter::repeat("a").take(257).collect::())); ++ ++ assert!(is_valid_filename(::std::iter::repeat("®").take(254).collect::())); ++ assert!(is_valid_filename("ファイル")); ++ assert!(is_valid_filename("a")); ++ assert!(is_valid_filename("a.aaaaaaaa")); ++ assert!(is_valid_filename("a........a")); ++ assert!(is_valid_filename(" b")); ++} ++ ++#[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"))); ++} ++ ++#[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::(); ++ 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"))); ++} +diff --git a/rust-launcher/src/main.rs b/rust-launcher/src/main.rs +index d13e1a6..0d9fb80 100644 +--- a/rust-launcher/src/main.rs ++++ b/rust-launcher/src/main.rs +@@ -9,6 +9,7 @@ mod utils; + mod property; + mod jars_helper; + mod log_helper; ++mod dunce; + + use std::string::String; + use std::fmt::Write; diff --git a/icedtea-web.spec b/icedtea-web.spec index f9b2364..0b0170c 100644 --- a/icedtea-web.spec +++ b/icedtea-web.spec @@ -10,13 +10,14 @@ %global debug_package %{nil} Name: icedtea-web Version: 1.8.4 -Release: 4 +Release: 5 Summary: Additional Java components for OpenJDK - Java Web Start implementation License: LGPLv2+ and GPLv2 with exceptions URL: http://icedtea.classpath.org/wiki/IcedTea-Web Source0: http://github.com/AdoptOpenJDK/IcedTea-Web/archive/%{name}-%{version}.tar.gz Patch0006: fix-for-cargo-test-sometimes-fails-when-make-runs-with-several-simultaneous-jobs.patch +Patch0007: add-dunce-lib.patch BuildRequires: javapackages-tools javapackages-local %{preffered_java}-devel BuildRequires: desktop-file-utils glib2-devel autoconf automake cargo junit hamcrest @@ -165,6 +166,9 @@ exit 0 %{_datadir}/man/man1/* %changelog +* Fri Feb 5 2021 jdkboy - 1.8.4-5 +- add add-dunce-lib.patch to avoid accssing to Cargo + * Mon Dec 21 2020 noah - 1.8.4-4 - add a license to this repo -- Gitee