Skip to content

Read files with dangling references instead of panicking - #377

Open
keithadler wants to merge 1 commit into
MathNya:masterfrom
keithadler:fix-dangling-reference-panics
Open

keithadler wants to merge 1 commit into
MathNya:masterfrom
keithadler:fix-dangling-reference-panics

Conversation

@keithadler

Copy link
Copy Markdown
Contributor

Problem

reader::xlsx::read panics on four kinds of reference that point at nothing:

Reference Panic
defined name with localSheetId past the last sheet sheet_mut(..).unwrap() in reader/xlsx/workbook.rs
hyperlink whose r:id names no relationship relationship_by_rid: "Not found relationship with ID"
conditional format whose dxfId is past the <dxfs> DifferentialFormats::style: get(id).unwrap()
comment whose authorId is missing or past the <authors> Comment::set_attributes: authors.get(..).unwrap()

A panic in a reader takes down whatever called it, for example a server handling an uploaded file, where a Result could have been handled.

Change

Excel opens all four and repairs them by dropping the dangling reference, so this does the same:

  • the name is skipped
  • the hyperlink is kept without a URL
  • the rule is kept without a style
  • the comment is kept without an author

RawRelationships::find_relationship_by_rid and DifferentialFormats::find_style are new non-panicking lookups. The existing panicking ones are unchanged for their other callers.

Tests

tests/dangling_references.rs builds each file from a workbook written by umya-spreadsheet itself, with one reference patched to dangle, and checks the read succeeds and what was kept. All four panic without the change. cargo +nightly fmt --all --check, cargo clippy -- -D warnings and cargo test pass.

Related: #310 lists other unwrap() panics on real files; #374 is the hyperlink-over-a-range panic, a different cause not addressed here. Found by the adversarial corpus of xlsx-lean, which writes one file per broken rule.

🤖 Generated with Claude Code

https://claude.ai/code/session_019hXzkiuCwk5QQRsyU9wT9h

Four references that point at nothing made the reader panic:

- a defined name whose localSheetId is past the last sheet
  (`sheet_mut(..).unwrap()` in reader/xlsx/workbook.rs)
- a hyperlink whose r:id names no relationship
  (`relationship_by_rid` panics when the id is not found)
- a conditional format whose dxfId is past the differential formats
  (`DifferentialFormats::style` unwraps `get(id)`)
- a comment whose authorId is missing or past the author list
  (`Comment::set_attributes` unwraps both the parse and `get`)

Excel opens each of these and repairs it by dropping the dangling
reference, so do the same: skip the name, keep the hyperlink without a
URL, keep the rule without a style, and keep the comment without an
author. `find_relationship_by_rid` and `DifferentialFormats::find_style`
are the non-panicking lookups; the existing panicking ones are
unchanged for their other callers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hXzkiuCwk5QQRsyU9wT9h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants