Skip to content

fix(ui-egui): keep an ink file that cannot all be read before writing over it (#157) - #178

Open
DWAA1660 wants to merge 2 commits into
AlienTechSoftware:mainfrom
DWAA1660:fix/ink-keep-unreadable-original
Open

DWAA1660 wants to merge 2 commits into
AlienTechSoftware:mainfrom
DWAA1660:fix/ink-keep-unreadable-original

Conversation

@DWAA1660

Copy link
Copy Markdown
Collaborator

What and why

Fixes #157. inkpad::Pad::of_page turned a read or parse failure of ink.svg into an empty layer (.ok()…unwrap_or_else(empty)). It counted paths without NoteCraft pen readings in flat, but dropped them from the drawing. The next Pad::save wrote only the drawing over the same file, or deleted it when the drawing was empty. The issue's red path, or an unreadable file, was silently destroyed as soon as the user drew one stroke.

This takes the issue's "recovery/backup path" option, so nothing in the file is ever lost:

  • Pad gains incomplete, set when ink.svg exists but couldn't be read or parsed, or when it holds flat > 0 uneditable paths.
  • Before the first write or removal of such a file, Pad::save copies it byte-for-byte to ink.svg.bak, or the first free ink-N.svg.bak, opened with create_new so nothing is overwritten. It records the path in kept_original, and later saves don't make more copies. The .bak extension keeps the copy out of ink detection and picture handling.
  • The app reports it after each of its three ink-save paths (drawing, taking a stroke back, absorbing old sheets) with a new message: "This page's drawing file held lines NoteCraft cannot edit. The file as it was is kept as {path}." It's in all 15 catalogs, including the pseudo-locales, and is also logged as a warning.

Files NoteCraft wrote itself and read back whole are saved exactly as before, with no copy.

Preserving uneditable paths inside the edited drawing would be a larger change to the ink model. The backup makes sure that, until then, nothing is lost.

How it was checked

  • New inkpad::tests::ink_that_cannot_all_be_read_is_kept_before_it_is_written_over:
    • for the issue's red-path SVG and for a file that isn't an SVG at all: the pad is incomplete, saving new ink keeps the original byte-for-byte at ink.svg.bak, and a second save makes no second copy
    • a NoteCraft-written ink file read back whole is saved with nothing kept
  • cargo test -p notecraft-ui-egui: all pass (303 unit, 200 UI)
  • cargo xtask i18n-audit, cargo xtask text: pass
  • cargo fmt --all -- --check, cargo clippy -p notecraft-ui-egui --all-targets -- -D warnings: clean

🤖 Generated with Claude Code

A page's ink.svg that could not be read, or that held lines with no pen
readings, loaded as an empty or partial drawing, and the next save wrote
that drawing over the file, losing everything else in it without a word
(AlienTechSoftware#157). The pad now marks such a file incomplete and, before it first
writes over it or takes it away, copies it as it was to ink.svg.bak (or
the next free name). The window says where the original was kept.

Fixes AlienTechSoftware#157

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DWAA1660

Copy link
Copy Markdown
Collaborator Author

Audit finding: the backup protection is not connected to the browser's virtual filesystem. The inkpad browser patch imports the virtual std shim, but these new Path methods still query native fs:

  • None => file.exists() in of_page
  • self.file.is_file() before keep_original

Using a file written through the actual virtual fs, a probe reports Path.exists=false, Path.is_file=false while virtual read_to_string succeeds. An unreadable original is therefore not marked incomplete, and even a flat SVG marked incomplete skips its backup and can be overwritten.

Also, keep_original uses OpenOptions::create_new, which is not implemented by the virtual shim. (The current patches DO provide virtual File::open; that part is supported.)

Please use virtual metadata for existence/type checks and add exclusive creation to the browser fs boundary, with a test that edits unreadable/flat ink in the virtual notebook and verifies the exact original bytes survive. Holding this PR out of the merge batch until the browser path is covered.

This branch has not been deployed

No deployments
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.

[BUG] Noneditable or unreadable ink.svg content is silently replaced when new ink is saved

1 participant