Skip to content

GetNavigationBraille panics in no-unsafe builds due to cross-document node insertion #827

Description

@venkatesh6114

Description

When MathCATForC is built with the no-unsafe feature, GetNavigationBraille can panic inside sxd-document-no-unsafe. GetSpokenText works correctly with the same MathML.

Originally observed with MathCAT and MathCATForC beta.8. The underlying issue was also reproduced with MathCAT 0.7.6-rc.4.

Reproduction

After normal MathCAT initialization:

SetMathML(R"(<math><mi id='focused'>x</mi><mo>+</mo><mi>y</mi></math>)");
GetNavigationBraille();

Build MathCATForC with:

cargo build --release --features no-unsafe

No explicit navigation operation was required in the original beta.8 reproduction.

A deterministic reproduction on MathCAT 0.7.6-rc.4 is:

set_mathml("<math><mi id='focused'>x</mi><mo>+</mo><mi>y</mi></math>")?;
set_navigation_node("focused", 0)?;
get_navigation_braille()?;

Actual Result

index out of bounds: the len is 1 but the index is 7

Relevant stack frames:

sxd_document_no_unsafe::raw::Connections::replace_element_child_parent
sxd_document_no_unsafe::raw::Connections::append_element_child
sxd_document_no_unsafe::dom::Element::append_child
libmathcat::interface::get_navigation_braille

Expected Result

GetNavigationBraille should return braille for the current navigation focus without panicking.

Root Cause

get_navigation_braille creates a temporary Package and <math> element, but copy_mathml(found) allocates the copied subtree in the original document and appends it to the temporary document.

The unsafe backend uses pointers and happens to tolerate this cross-document operation. The no-unsafe backend uses document-local indices, so it uses an original-document index against the temporary document storage and panics.

The invalid cross-document insertion occurs in MathCAT's interface.rs; sxd-document-no-unsafe exposes the ownership violation.

Proposed Fix

Allow recursive MathML copying to receive a destination Document and allocate the entire copied subtree there before appending it.

Add a regression test that focuses below the outer <math> element and calls get_navigation_braille with no-unsafe enabled.

Local Validation

The proposed fix passed:

  • Focused regression with --features no-unsafe
  • The same regression with default features
  • All interface::tests with no-unsafe
  • MathCATForC release DLL build with no-unsafe
  • Direct C ABI verification returning the expected navigation braille

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions