fix(deps): move zip off the yanked 2.4.2, to 9.0.4

Every zip 2.x release from 2.4.2 on is yanked; crates.io warned on each
0.3.2 publish. zip 9 returns entry names as a Result (it validates their
encoding): skip undecodable names, which can be neither the archive's TXT
payload nor an XLSX worksheet. zip 9 needs Rust 1.88, within our 1.89.

Closes #51.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
hermes 2026-10-16 10:46:00 +00:00
commit f5da3b745e
4 changed files with 45 additions and 37 deletions

View file

@ -172,7 +172,10 @@ fn extract_txt_from_zip(path: &Path) -> Result<String, IdxError> {
continue;
}
let name = file.name().to_ascii_lowercase();
// An undecodable entry name cannot be the TXT payload.
let Ok(name) = file.name().map(|name| name.to_ascii_lowercase()) else {
continue;
};
if !name.ends_with(".txt") {
continue;
}

View file

@ -87,11 +87,13 @@ fn read_zip_entry(
}
fn first_worksheet_name(zip: &mut zip::ZipArchive<Cursor<&[u8]>>) -> Result<String, IdxError> {
// Undecodable entry names cannot be worksheets; skip them.
let mut sheets: Vec<String> = zip
.file_names()
.filter_map(Result::ok)
.filter(|name| name.starts_with("xl/worksheets/") && name.ends_with(".xml"))
.filter(|name| !name["xl/worksheets/".len()..].contains('/'))
.map(str::to_string)
.map(|name| name.into_owned())
.collect();
// sheet1.xml, sheet2.xml, ... sort by their numeric suffix.
sheets.sort_by_key(|name| {