From 939bd12832dfea062b58c3c320641df9439dd9a9 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 26 Oct 2026 03:56:04 +0000 Subject: [PATCH 1/2] Find zip entries stored with backslash separators in pptx packages Found while testing crates/pptx/src/opc.rs:77-82 (Package::open_within), lookup in Package::get via norm at :258 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/pptx/src/opc.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/pptx/src/opc.rs b/crates/pptx/src/opc.rs index c2acf9a2..adbcf448 100644 --- a/crates/pptx/src/opc.rs +++ b/crates/pptx/src/opc.rs @@ -93,7 +93,7 @@ impl Package { } } total = total.saturating_add(data.len() as u64); - parts.insert(name.to_ascii_lowercase(), (name, data)); + parts.insert(norm(&name), (name, data)); } Ok(Package { parts, ct_cache: std::sync::OnceLock::new() }) } @@ -499,6 +499,13 @@ mod tests { assert!(p.get("e").is_some()); } + #[test] + fn backslash_zip_entry_names_are_found() { + let z = zip_of(&[("PPT\\Slides\\Slide1.xml", 3)]); + let p = Package::open(&z).unwrap(); + assert!(p.get("ppt/slides/slide1.xml").is_some()); + } + #[test] fn xml_bytes_applies_the_xml_limit() { let z = zip_of(&[("small.xml", 10)]); From ba29b61f8cbc784fba511e84a60b1758f6d24f01 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Fri, 30 Oct 2026 15:54:46 -0400 Subject: [PATCH 2/2] Keep backslash zip entry names with forward slashes so later lookups split them Co-Authored-By: Claude Opus 5.5 --- crates/pptx/src/opc.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/pptx/src/opc.rs b/crates/pptx/src/opc.rs index adbcf448..20a53bcb 100644 --- a/crates/pptx/src/opc.rs +++ b/crates/pptx/src/opc.rs @@ -93,7 +93,8 @@ impl Package { } } total = total.saturating_add(data.len() as u64); - parts.insert(norm(&name), (name, data)); + // A name kept with `\` would reach code that splits paths on `/`. + parts.insert(norm(&name), (name.replace('\\', "/"), data)); } Ok(Package { parts, ct_cache: std::sync::OnceLock::new() }) } @@ -504,6 +505,7 @@ mod tests { let z = zip_of(&[("PPT\\Slides\\Slide1.xml", 3)]); let p = Package::open(&z).unwrap(); assert!(p.get("ppt/slides/slide1.xml").is_some()); + assert_eq!(p.original_name("ppt/slides/slide1.xml"), Some("PPT/Slides/Slide1.xml")); } #[test]