Skip to content

Drop a trailing period from a suggested file name [patch] - #205

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/196-trailing-period
Oct 9, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/196-trailing-period

Conversation

@matt-edmondson

@matt-edmondson matt-edmondson commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #196

What was wrong

Models often end their answer with a full stop, even when asked for just a file name. Scan.SanitizeFileName kept that period at every step. Path.GetExtension("sunset.") is empty, . is a legal character, and the final trim removed only - and space. So:

model answer before after
sunset-over-the-lake. sunset-over-the-lake..jpg sunset-over-the-lake.jpg
photo.jpg. (to .png) photo.jpg..png photo.png
... ....jpg unnamed.jpg

A suggestion is stored once per hash and never regenerated, so the bad name stayed in the database for good.

Change

  • Trim trailing periods and spaces right after the quote and backtick trim, before the extension check. This also lets photo.jpg. lose its image extension.
  • Add . to the final trim set. A name made only of dots now falls back to unnamed. So does a period left at the end once the final trim removes a trailing hyphen (sunset.- gives sunset.jpg).
  • Dots inside a name are unchanged: the st.-louis-arch-at-dusk and sunset-at-5.30pm tests still pass.

Tests

New ScanTests cases: SanitizeFileNameDropsTrailingPeriod (4 rows), SanitizeFileNameStripsImageExtensionFollowedByPeriod, SanitizeFileNameReturnsUnnamedForOnlyPeriods (3 rows), and SanitizeFileNameDropsPeriodLeftBeforeTrimmedHyphen.

  • With the fix reverted, all 9 new cases fail.
  • With it applied, the full suite passes: 117 passed and 1 skipped. The skip is ScanForImagesSkipsUnreadableSubdirectories, which is inconclusive when run as root.
  • CI is green on Ubuntu, macOS and Windows.

Not covered: names already stored with .. are not rewritten. The triage note suggests a one-off cleanup or a re-suggest path for those, which is a separate change. I've also left alone a Windows-only crash that already exists on main: an extension that Windows rejects, such as .?, throws inside IsImageExtension. It is described in the comment below.

🤖 Generated with Claude Code

https://claude.ai/code/session_01URmxVUpdaWCEUSPudDfLsq

claude added 2 commits October 9, 2026 08:24
Models often end the answer with a full stop. SanitizeFileName kept it, so
"sunset-over-the-lake." became "sunset-over-the-lake..jpg", "photo.jpg."
kept its extension, and "..." became "....jpg" instead of "unnamed.jpg".
Trim trailing periods before the extension check, and include the period
in the final trim so a name left as only dots falls back to "unnamed".

Fixes #196

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01URmxVUpdaWCEUSPudDfLsq
Path.GetExtension("sunset.?") is ".?" on Windows, which FileExtension
refuses, so the case threw before reaching the trim it was meant to test.
"sunset.-" exercises the same trailing-period trim on every platform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01URmxVUpdaWCEUSPudDfLsq

Copy link
Copy Markdown
Contributor Author

The first push failed Test on windows-latest in SanitizeFileNameDropsPeriodLeftBeforeReplacedCharacter, which threw ArgumentException: Cannot convert ".?" to FileExtension. On Windows, Path.GetExtension("sunset.?") returns .?. ImageScanner.IsImageExtension then converts that to a FileExtension, which refuses ?. de7f220 swaps the input for sunset.-, which exercises the same trailing-period trim on every platform. Against the code before this PR, the renamed case fails; with the fix, it passes.

Not fixed here, because it is outside this PR's scope: the same crash exists on main today. On Windows, any suggestion whose text after its last dot contains a character Windows rejects (for example what is this.? or a.b:c) makes SanitizeFileName throw before the replacement step runs. One possible fix is to run the extension check after the character replacement, or to have IsImageExtension return false for an extension that isn't valid. Either would fit with #171.


Generated by Claude Code

@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 4525b4a into main Oct 9, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix/196-trailing-period branch October 9, 2026 10:25
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.

A filename suggestion ending in a period ("sunset-over-the-lake.") is stored as "sunset-over-the-lake..jpg" with a doubled dot

2 participants