diff --git a/crates/docx/src/read.rs b/crates/docx/src/read.rs index 95da45d0a..d50625285 100644 --- a/crates/docx/src/read.rs +++ b/crates/docx/src/read.rs @@ -204,7 +204,7 @@ fn read_opened_in(pkg: &Package, chunks: ChunkState) -> Result<(Document, usize, // those files when a producer omitted the document relationship; the bounded package // reader still applies the same entry and XML limits. An explicit usable relationship // always wins, including when it points outside the conventional `word/` paths. - if main != "word/document.xml" { + if !main.eq_ignore_ascii_case("word/document.xml") { return None; } let fallback = match t { diff --git a/crates/docx/tests/it/undefined_style.rs b/crates/docx/tests/it/undefined_style.rs index c50a9c8b7..e1a2611cb 100644 --- a/crates/docx/tests/it/undefined_style.rs +++ b/crates/docx/tests/it/undefined_style.rs @@ -81,15 +81,25 @@ fn conventional_styles_and_numbering_parts_without_relationships_are_read() { let numbering = format!( r#""# ); - let mut zw = zip::ZipWriter::new(std::io::Cursor::new(Vec::new())); - for (name, body) in [("word/document.xml", doc.as_str()), ("word/styles.xml", styles.as_str()), ("word/numbering.xml", numbering.as_str())] { - zw.start_file(name, zip::write::SimpleFileOptions::default()).unwrap(); - zw.write_all(body.as_bytes()).unwrap(); + for main_path in ["word/document.xml", "WORD/DOCUMENT.XML"] { + let root = format!( + r#""# + ); + let mut zw = zip::ZipWriter::new(std::io::Cursor::new(Vec::new())); + for (name, body) in [ + ("_rels/.rels", root.as_str()), + (main_path, doc.as_str()), + ("word/styles.xml", styles.as_str()), + ("word/numbering.xml", numbering.as_str()), + ] { + zw.start_file(name, zip::write::SimpleFileOptions::default()).unwrap(); + zw.write_all(body.as_bytes()).unwrap(); + } + let d = craft_docx::read(&zw.finish().unwrap().into_inner()).unwrap(); + assert!(d.styles.styles.iter().any(|style| style.id == "Body")); + let Some(Block::Para(p)) = d.body.first().map(|b| &**b) else { panic!("a body paragraph") }; + assert_eq!(p.props.style.as_deref(), Some("Body")); + assert_eq!(p.props.numbering.map(|n| (n.num, n.level)), Some((7, 0))); + assert!(d.numbering.level(7, 0).is_some()); } - let d = craft_docx::read(&zw.finish().unwrap().into_inner()).unwrap(); - assert!(d.styles.styles.iter().any(|style| style.id == "Body")); - let Some(Block::Para(p)) = d.body.first().map(|b| &**b) else { panic!("a body paragraph") }; - assert_eq!(p.props.style.as_deref(), Some("Body")); - assert_eq!(p.props.numbering.map(|n| (n.num, n.level)), Some((7, 0))); - assert!(d.numbering.level(7, 0).is_some()); }