Skip to content

Fail only the file when EPUB or IMSCP XML names an unusable encoding - #874

Merged
rtibbles merged 1 commit into
learningequality:mainfrom
rtibblesbot:issue-855-ccd023
Oct 19, 2026
Merged

rtibbles merged 1 commit into
learningequality:mainfrom
rtibblesbot:issue-855-ccd023

Conversation

@rtibblesbot

@rtibblesbot rtibblesbot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

EPUB/IMSCP XML declaring an unknown (bogus) or multi-byte (Shift_JIS) encoding raised LookupError/ValueError and stopped the whole run.

  • Unknown encodings fail only that file with a one-line error.
  • Multi-byte encodings (Shift_JIS, ISO-2022-JP) are decoded with the declared codec and re-parsed.

References

Fixes #855. Same failure for SVGs: #813.

Reviewer guidance

Suggested review: Full code review.

  • Confirm parse_xml's decode-and-reparse (declared-encoding regex, expat error-code check) is the shared XML-parsing approach wanted, given SVGValidationHandler uses an lxml fallback instead.
  • Confirm a bogus-labelled IMSCP manifest should fail the package even when its bytes are valid UTF-8, while a mislabelled Shift_JIS one is recovered.
  • Confirm EPUBs declaring utf8 or ISO-2022-JP, which upstream rejects as not well-formed, should now process.

AI usage

Used Claude Code to implement the fix and its tests from the issue's reproductions. Verified with the full test suite, prek, and a script that runs process_file() on each acceptance-criteria fixture.

🤖 Generated with Claude Code

Deviations from the issue spec

Criterion Why not
IMSCP bogus manifest: process_file() returns None with a one-line .error No IMSCP File subclass exists; ContentNode(uri=...).process_files() raises a one-line InvalidNodeException instead. Adding a subclass is forbidden by AGENTS.md.

Written by rtibblesbot, an LLM-based coding agent.

@rtibblesbot

🔵 Post PR

Last updated: 2026-10-19 17:23 UTC

- Unknown encodings raise ET.ParseError instead of escaping as LookupError
- Multi-byte encodings such as Shift_JIS are decoded with the declared Python codec and parsed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rtibblesbot
rtibblesbot marked this pull request as ready for review October 18, 2026 20:54
@rtibblesbot
rtibblesbot requested review from a team and leq-bot October 18, 2026 20:54

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes make sense, and the test coverage shows what this is fixing.

)

XML_ENCODING_DECLARATION_REGEX = re.compile(
rb"""^(?:\xef\xbb\xbf)?\s*<\?xml\s[^>]*?\bencoding\s*=\s*["']([A-Za-z][\w.:-]*)["']"""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to complain about using regex to read XML data - but this is a smart usage of it to discover the declared encoding when we are otherwise unable to parse the file with the default UTF encoding.

@rtibbles
rtibbles merged commit 189f3ed into learningequality:main Oct 19, 2026
42 checks passed
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Quick check on rtibblesbot's work on this PR: react 👍 helpful · 😕 mixed · 👎 not helpful. Reply with anything specific.

@rtibblesbot
rtibblesbot deleted the issue-855-ccd023 branch October 19, 2026 17:24
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.

An EPUB or IMSCP package whose XML names an unknown encoding fails that file, not the run

2 participants