Repository navigation
fix(model): long attachment names keep their extension and stay removable (#130, #131) - #174
Merged
DWAA1660 merged 3 commits intoNov 12, 2026
Conversation
`safe_file_name` cut a cleaned name to 80 characters as a whole, so a long `report.pdf` lost its `.pdf` and was no longer known as a PDF or a picture (AlienTechSoftware#130). `unique_name` then added `-2` after that cut, making an 82-character name that `remove` refused as unsafe, so a second copy of a long attachment could not be taken out again (AlienTechSoftware#131). A name is now cut in its stem, before the extension, and the suffix of a copy goes in through the same rule, so every name the writer makes is one the remover accepts. Fixes AlienTechSoftware#130 Fixes AlienTechSoftware#131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Audit finding: the new truncation can turn a valid filename into a reserved Windows device name. Reproduced by compiling this PR's actual The second arrow is a second call on the result. Main preserves the original names. Please validate the final truncated/trimmed stem for reserved names (including any safety prefix within the length budget), and add these cases to the idempotence regression. Holding this PR out of the merge batch until fixed. |
# Conflicts: # crates/store/src/assets.rs
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.
What and why
Fixes #130 and #131. Both come from the same naming rule, so they're one PR: the fix for #131 has to build on the length rule #130 changes.
#130: long names lost their extension.
names::safe_file_namecut the whole cleaned name with.chars().take(80)."x"×90 + ".pdf"was saved as 80xcharacters with no extension, somedia_kindcalled a long.pngOtherand the code view stopped recognising PDFs and Office files.#131: a long name's second copy couldn't be removed.
assets::unique_nameadded-2after that cut. An 80-character….txtbecame an 82-character…-2.txt, andassets::remove(and sopage.detach) refused it, because re-sanitising it didn't give the same name back.Changes in
notecraft_model::names:MAX_FILE_NAME(80) names the limit.split_extension(name)splits off a real extension: up to 16 ASCII letters and digits after the last dot.fit_file_name(stem, extension, suffix)joins the parts within the limit by cutting the stem, never the extension or suffix.safe_file_namecleans as before (path parts, characters, reserved names), then fits throughfit_file_name. Applying it again changes nothing, which is whatremoverelies on.assets::unique_namenow buildsstem-N.extwithfit_file_name, so every copy, however many digits its suffix has, is a safe name thatremoveaccepts.How it was checked
names::tests::a_long_attachment_name_keeps_its_extension:.pdf,.png,.docxand.tar.gzkeep their extension at exactly 80 characters, and a name already at the limit is keptsafe_file_nameis idempotent on a set of tricky names, including multibyte onesnames::tests::a_suffixed_name_fits_and_stays_safe: suffixes-2,-10and-1234fit with.txtkept, and are safe namesassets::tests::long_names_keep_their_type_and_every_copy_can_be_removed: through the real store, long PDF/PNG/DOCX keep their type (a long PNG isMediaKind::Image). Twelve copies of the issue's 80-character.txtall get distinct names and all can be removed.cargo test -p notecraft-model -p notecraft-store -p notecraft-engine -p notecraft-import: passcargo test -p notecraft-ui-egui: all pass (302 unit, 200 UI)cargo fmt --all -- --check,cargo clippy -p notecraft-model -p notecraft-store --all-targets -- -D warnings: clean🤖 Generated with Claude Code