Skip to content

codegen: escape companion include! names, and reject a path in release builds too - #718

Merged
iainmcgin merged 3 commits into
anthropics:mainfrom
veljjanoski:codegen-companion-include-escape
Oct 20, 2026
Merged

iainmcgin merged 3 commits into
anthropics:mainfrom
veljjanoski:codegen-companion-include-escape

Conversation

@veljjanoski

@veljjanoski veljjanoski commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #708.

apply_companions wrote each companion name into the stitcher as include!("<name>") unescaped, and checked the name only with a debug_assert!, which a release build of a downstream generator skips. A name with a " then gave a stitcher that was not valid Rust or named a different file, and the error appeared in the consumer's crate.

The line is now include!({name:?});, the escaped literal generate_module_tree writes. The check is an assert! in every build: a name must not contain / or \, and must not be empty, . or ... A " or a newline in a name is escaped now, where the debug_assert! rejected it. Every name is checked before files is changed. The issue offered an assert! or a try_apply_companions that returns a CodeGenError; this is the assert!, so the signature is unchanged.

A generator that passed a name with a separator from a release build now panics; switch to a bare name such as <stem>.__myplugin.rs.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@veljjanoski

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Oct 15, 2026
veljjanoski and others added 2 commits October 15, 2026 10:10
…escaping test

An empty name, `.` and `..` contain no separator, so they passed the
check and produced an include! of a directory. apply_companions now
panics for them as well, before any output is changed.

apply_companions_escapes_name_in_include compared the parsed literal's
value with the name. A raw newline, tab or bidi control parses to the
same value as its escape, so only the quote pinned the escaping. The
test now also compares the appended text with the escaped literal, and
the name gains a carriage return, which does not lex unescaped.

@iainmcgin iainmcgin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude code] Pushed one maintainer commit on top of yours (11235ce); the escaping and the release-build check are as you wrote them.

  • An empty name, . and .. contain no separator, so they passed the check and produced an include! of a directory. apply_companions now panics for them too, before any output is changed; the rustdoc, # Panics and the fragment say so.
  • apply_companions_escapes_name_in_include compared the parsed literal with the name. A raw newline, tab or bidi control parses to the same value as its escape, so only the quote pinned the escaping. The test now also compares the text appended to the stitcher with the escaped literal, and the name gains a carriage return, which does not lex unescaped.
  • New test apply_companions_rejects_names_that_are_not_files: a good companion first, then each of the three names; it checks the panic message and that no output changed.

cargo test -p buffa-codegen passes on this head (938 passed), and the apply_companions tests pass with --release.

@iainmcgin
iainmcgin added this pull request to the merge queue Oct 20, 2026
Merged via the queue into anthropics:main with commit 247019d Oct 20, 2026
11 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

codegen: apply_companions writes the companion file name into include! unescaped, and checks it only with a debug_assert!

2 participants