engine: a name up to 255 bytes is written, and a longer one is refused everywhere - #137
Conversation
…d everywhere Every file is written under a temporary name beside it and renamed once it is whole. That name was the file's name with eighteen bytes after it, so a name from 238 bytes up was never written on any system, while every file system stores it. A sibling name now keeps the plain join whenever it fits, and a longer name is cut to whole characters and tagged with a digest of the whole name, so two long names that begin alike still get two. The manifest and recipe fmt -w write their own siblings the same way. A name over 255 bytes was written on Windows and macOS, which count characters, and could not be on Linux, which counts bytes. It is now refused before anything is written, on every system, with its length and the limit. The rules a file name has to pass moved from engine.go into filename.go, which the length rule took past its ceiling. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (10)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review. 📜 Recent review details⏰ Context from checks skipped due to timeout. (15)
🧰 Additional context used📓 Path-based instructions (13)Applies to text shown to the user (labels, buttons, tooltips, placeholders, dialogs, errors, status messages, empty states, translations).⚙️ CodeRabbit configuration file Files:
Verify tests check real behavior and would fail if the implementation were broken.⚙️ CodeRabbit configuration file Files:
These are end-user desktop applications.⚙️ CodeRabbit configuration file Files:
Performance is a known weak spot of these projects.⚙️ CodeRabbit configuration file Files:
Applies only to code that builds or styles a GUI.⚙️ CodeRabbit configuration file Files:
User-facing changelog.⚙️ CodeRabbit configuration file Files:
Domain: test file generator (Go; `tfg` CLI and `tfg-gui` Fyne window over one engine).⚙️ CodeRabbit configuration file Files:
SECURITY, HIGH PRIORITY.⚙️ CodeRabbit configuration file Files:
These apps are QA/developer tools.⚙️ CodeRabbit configuration file Files:
Go code.⚙️ CodeRabbit configuration file Files:
Check that documentation matches the actual code in this PR: commands, flags, config keys, file paths, build steps and examples must exist.⚙️ CodeRabbit configuration file Files:
All code in this repository is written by an AI coding agent (Claude Code).⚙️ CodeRabbit configuration file Files:
Source excerpt: **Words a user reads are English, with a flat hyphen and no semicolons.**📄 CodeRabbit inference engine (CONTRIBUTING.md) Files:
🔇 Additional comments (9)
📝 WalkthroughWalkthroughThe change adds a cross-platform 255-byte filename limit, retains recipe filename validation in a separate file, and shortens temporary sibling names when needed. Generation, replacement, and manifest-writing paths use the bounded names. Tests cover long names, refusal of overlong names, and temporary-file handling. ChangesFilename handling
Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested labels: Merge Risk: ⚪ Minimal · up to No actionable issue remains; the change is ready to merge after normal checks. 🚥 Pre-merge checks | ✅ 14✅ Passed checks (14 passed)
Comment |
What changes
A file name from 238 to 255 bytes long is written. Every file is written under a temporary name beside it and renamed once it is whole. That name was the file's name with eighteen bytes after it, so a name from 238 bytes up was never written on any system, while every file system stores it. The same held for a manifest named that long and for
tfg recipe fmt -won a recipe file named that long.core.SiblingNamenow makes every such name. It keeps the plain join whenever it fits in 255 bytes, so nothing changes for any name the tool could write before. A longer one is cut to whole characters and tagged with sixteen hex digits of the SHA-256 of the whole name, so two long names that begin alike still get two temporary names. The marker stays last, so what an interrupted run leaves behind is still reported as a leftover.A file name longer than 255 bytes is refused before anything is written, on every system. Linux (ext4) stores at most 255 bytes in a name, while NTFS and APFS count UTF-16 units and characters. A name of 200 CJK characters (604 bytes) used to be written on Windows and macOS and fail on Linux with exit code 8 and no reason. It now ends with exit code 3 everywhere, and the refusal gives the length and the limit.
The rules a file name has to pass moved from
engine.gointoengine/filename.go, because the new rule tookengine.gopast its length ceiling. The ceiling went down to 407 rather than up.How it was checked
internal/guard/longnames_test.go, each asserting that it is in the state it asks about. Nine mutations, all caught. Ten existing mutation entries repointed atfilename.go, all caught.tfg verifypasses. The 604-byte name is refused with exit 3 on all three.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
tfg recipe fmt -w.Breaking Changes