Skip to content

[BUG] A Unicode character across byte 4096 in an ordinary SVG crashes ink detection #126

Closed

Description

@DWAA1660

Environment

Windows, Rust 1.99.1, NoteCraft 0.0.9 at 33429876e885613f6ff8f29a762b15b2be736401 (current main when tested). Verified against the real workspace libraries / front end with synthetic files and an isolated profile. No product source changes or mocks.

Minimal reproducer

let mut svg = "<svg xmlns=\"http://www.w3.org/2000/svg\"><!--".to_string();
svg.push_str(&"a".repeat(4095 - svg.len()));
svg.push_str("é--><rect width=\"1\" height=\"1\"/></svg>");
assert!(!notecraft_ink::svg::is_ink(&svg)); // panics instead

This is a valid ordinary SVG with a long XML comment, not NoteCraft ink.

User-facing path also verified

Save that SVG as ordinary.svg beside a real page's index.html. Calling the real notecraft_store::page::ink_files(&page_dir) panics as well. The app calls this scan when opening pages to reconcile their drawings. SVG assets are also classified with the same function in the source-view file list.

Actual result

Direct call:

panicked at crates/ink/src/svg.rs:79:21:
end byte index 4096 is not a char boundary; it is inside 'é' (bytes 4095..4097 of string)

The real page scan also panics. Its bounded read replaces an incomplete trailing UTF-8 character with U+FFFD, and the same slice then splits that replacement character at bytes 4095..4098.

Expected result

Recognize the file as an ordinary SVG and continue opening the page. Ink detection should be safe on arbitrary valid text and on a bounded/lossy prefix.

Cause

svg.rs takes &text[..text.len().min(4096)] without establishing a character boundary. The cap needs a safe boundary or byte-based handling. Test both the direct helper and the real bounded-read callers.

This is a separate code path from #102's link panic; the current link fix in PR #118 does not touch it.

Duplicate check

Checked all open/closed issues and PRs, including the first audit's #102-#116 and new PRs #117-#120. No existing issue or PR covering this specific behavior was found.

Additional end-to-end front-end verification

The shipped ui_shot runner was also given a real notebook containing the synthetic ordinary SVG beside its page and asked to open that page. It exited 101 immediately with the same svg.rs:79:21 boundary panic, before reaching the requested page state. This confirms the automatic page-open path, beyond the direct helper/scan probes. The fixture remained an ordinary SVG with no NoteCraft ink namespace.

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

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions