fix(bestool): reject a backslash in a snippet name, not a trailing percent (audit M19) - #442
Draft
passcod wants to merge 1 commit into
Draft
fix(bestool): reject a backslash in a snippet name, not a trailing percent (audit M19)#442passcod wants to merge 1 commit into
passcod wants to merge 1 commit into
Conversation
…rcent Backslash is LIKE's default escape character, so `name NOT LIKE '%\%'` reads as "does not end in a literal percent sign" — the opposite of the comment directly above it. Verified on Postgres 16: `'foo\bar' LIKE '%\%'` is false and `'top100%' LIKE '%\%'` is true, while the intended `'%\\%'` gives true and false. So the one clause guarding against backslashes accepted them, and a legitimate name like `top100%` was rejected with a raw constraint 500. Names become client-side filenames on Windows bestool, which is why backslash is on the list at all; a percent sign never was. There's no app-level validation, so this CHECK is the only guard. Added NOT VALID: the corrected clause applies to every insert and update from here on, but existing rows aren't scanned. A legacy backslash name — accepted for as long as this constraint has been wrong — would otherwise fail the migration and block the deploy. `VALIDATE CONSTRAINT` finishes the job once the fleet is known clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGfH1cdFKPnKpM7ytRThft
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.
Fixes M19 (medium) from the audit in #370.
The bug
Backslash is
LIKE's default escape character, soname NOT LIKE '%\%'reads as "does not end in a literal percent sign" — the opposite of the comment directly above it. Verified on Postgres 16:'foo\bar' LIKE '%\%'false— backslash names were accepted'top100%' LIKE '%\%'true— percent names were rejected'foo\bar' LIKE '%\\%'true'top100%' LIKE '%\\%'falseSo the one clause guarding against backslashes let them through, and a perfectly reasonable name like
top100%was rejected with a raw constraint 500. Names become client-side filenames on Windows bestool, which is why backslash is on the forbidden list at all; a percent sign never was. There's no app-level validation, so this CHECK is the only guard.The fix
A migration replacing the constraint with
'%\\%'.NOT VALID, deliberately. The corrected clause is enforced on every insert and update from here on, but existing rows aren't scanned. A legacy name containing a backslash — accepted for as long as this constraint has been wrong — would otherwise fail the migration and block the deploy. Once the fleet is known clean,ALTER TABLE bestool_snippets VALIDATE CONSTRAINT valid_snippet_name;completes it without taking a write lock. Happy to make it a plainADD CONSTRAINTinstead if you'd rather find out loudly.Tests
New
crates/database/tests/it/snippet_name_constraint.rs:a_backslash_in_a_name_is_rejecteda_percent_sign_in_a_name_is_allowedthe_other_forbidden_names_are_still_rejected— spaces,. / < > : " ' | ? *, and the Windows reserved names, plus an ordinary name that must be accepted.The first two are confirmed to fail against the old constraint, one in each direction.
Generated by Claude Code