diff --git a/crates/socket-patch-core/src/crawlers/gradle_cache.rs b/crates/socket-patch-core/src/crawlers/gradle_cache.rs index 5f8dfcace..8774a0f6e 100644 --- a/crates/socket-patch-core/src/crawlers/gradle_cache.rs +++ b/crates/socket-patch-core/src/crawlers/gradle_cache.rs @@ -702,7 +702,7 @@ const WRAPPER_PROPERTIES: &str = "gradle/wrapper/gradle-wrapper.properties"; /// `\r`, `\f`, `\uXXXX` and `\` escapes are resolved. A later key /// wins. fn parse_properties(bytes: &[u8]) -> HashMap { - let bytes = bytes.strip_prefix(b"\xEF\xBB\xBF").unwrap_or(bytes); + let bytes = crate::formats::text::strip_bom_bytes(bytes); let text: String = bytes.iter().map(|&b| b as char).collect(); let text = text.replace("\r\n", "\n"); let is_ws = |c: char| matches!(c, ' ' | '\t' | '\x0c'); @@ -1010,3 +1010,23 @@ pub fn locked_gavs(cwd: &Path) -> BTreeSet { } out } + +#[cfg(test)] +mod tests { + use super::*; + + /// `Properties.load` drops one leading UTF-8 BOM (#905); the bytes of a + /// second one are ISO-8859-1 content of the first key. + #[test] + fn parse_properties_drops_one_leading_bom_only() { + let one = parse_properties(b"\xef\xbb\xbfdistributionUrl=x\n"); + assert_eq!(one.get("distributionUrl").map(String::as_str), Some("x")); + let two = parse_properties(b"\xef\xbb\xbf\xef\xbb\xbfdistributionUrl=x\n"); + assert_eq!(two.get("distributionUrl"), None); + assert_eq!( + two.get("\u{ef}\u{bb}\u{bf}distributionUrl") + .map(String::as_str), + Some("x") + ); + } +} diff --git a/crates/socket-patch-core/src/crawlers/ivy_cache.rs b/crates/socket-patch-core/src/crawlers/ivy_cache.rs index 3df844893..5ae6fbcca 100644 --- a/crates/socket-patch-core/src/crawlers/ivy_cache.rs +++ b/crates/socket-patch-core/src/crawlers/ivy_cache.rs @@ -295,7 +295,7 @@ fn attribute<'a>(tag: &'a str, name: &str) -> Option<&'a str> { /// Whether `text`'s root element is ` bool { - let mut rest = text.trim_start_matches('\u{feff}'); + let mut rest = crate::formats::text::strip_bom(text); loop { rest = rest.trim_start(); let skip_to = if rest.starts_with("\n\n\n" )); assert!(!is_pom_root("")); + // Exactly one leading BOM is encoding (#905); a second is content. + assert!(is_pom_root("\u{feff}")); + assert!(!is_pom_root("\u{feff}\u{feff}")); assert!(!is_pom_root("")); assert!(!is_pom_root("