Prevent NVDA freeze when brailling math with certain Unicode characters#20320
Draft
AAClause wants to merge 5 commits into
Draft
Prevent NVDA freeze when brailling math with certain Unicode characters#20320AAClause wants to merge 5 commits into
AAClause wants to merge 5 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Prevents NVDA from freezing when MathCAT (via PyO3) raises a Rust panic by translating those panics into regular Python exceptions, and documents the user-visible fix.
Changes:
- Added a MathCAT wrapper (
_callMathCAT) to convert PyO3 panic exceptions into aMathCATError. - Routed multiple
libmathcatcalls through_callMathCATso existingexcept Exceptionhandlers can catch failures. - Added a changelog entry describing the MathCAT panic/freeze fix.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| user_docs/en/changes.md | Documents the freeze fix for MathCAT panics in release notes. |
| source/mathPres/MathCAT/MathCAT.py | Adds panic-to-Exception translation and applies it across MathCAT/libmathcat calls. |
seanbudd
reviewed
Jun 12, 2026
Member
|
can this be updated to retarget to beta please? |
PyO3 exposes Rust panics as PanicException, which is not caught by except Exception. Route libmathcat calls through a wrapper that converts these panics into MathCATError so existing MathCAT error handling can run. Fixes nvaccess#20319
Simplify exception handling to a single BaseException handler and detect PyO3 panics via isinstance with a string-based fallback.
NVDA ships libmathcat_py only; pyo3_runtime is not importable. Detect PyO3 panics by exception type name and module instead.
Member
|
is this ready for re-review? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to issue number:
Fixes #20319
Summary of the issue:
NVDA can freeze when MathCAT panics while processing MathML that contains certain Unicode characters (commonly mathematical alphanumeric symbols such as 𝑎 U+1D44E and 𝑏 U+1D44F in , , etc.).
MathCAT's Nemeth braille post-processing can panic on invalid UTF-8 string slicing when real math characters collide with internal placeholder characters. PyO3 exposes this Rust panic as pyo3_runtime.PanicException, which does not inherit from Exception. NVDA's existing except Exception handlers in mathPres/MathCAT/MathCAT.py therefore do not catch it, leaving an unhandled exception on the main thread and triggering watchdog freeze recovery.
Description of user facing changes:
When MathCAT panics on problematic MathML, NVDA no longer becomes unresponsive. The failure is handled like other MathCAT errors: it is logged, the user is notified (e.g. "Error in brailling math."), and NVDA remains usable.
Speech/braille for the affected formula may still be missing or incorrect until MathCAT itself is fixed upstream; this PR only ensures NVDA fails gracefully.
Description of developer facing changes:
Description of development approach:
All direct libmathcat.* calls in MathCAT.py are routed through _callMathCAT(). The wrapper:
This approach was chosen because:
The underlying MathCAT panic (unsafe UTF-8 slicing / placeholder collision in Nemeth braille code) remains an upstream issue in MathCAT.
Testing strategy:
Performed manual testing using problematic math formulas.
Before: NVDA freezes; log shows unhandled pyo3_runtime.PanicException during libmathcat.GetBraille().
After: NVDA stays responsive; log shows handled MathCATError; user hears/sees the existing MathCAT error notification.
Known issues with pull request:
Code Review Checklist: