Substitute the layout %{content} token literally, not through String#% - #67
Open
pcbeingused333 wants to merge 1 commit into
Open
pcbeingused333 wants to merge 1 commit into
pcbeingused333 wants to merge 1 commit into
Conversation
`Options#wrap` inserted the body with `layout % {content: ...}`. `String#%`
reads every `%` in the layout as a format directive, so any HTML layout that
carries a bare `%` — `width: 100%`, a percent-encoded URL, an inline `<style>`
rule — raised `ArgumentError: malformed format string` and the email never
went out.
Replace it with `layout.gsub("%{content}") { wrapped }`. The block form also
keeps the wrapped body verbatim when it contains `\1`, `\\` or `\&`, which the
string form of `gsub` would consume.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Options#wrapinserted the email body into a layout withlayout % {content: wrapped}.String#%treats every%in the layout string as a format directive, so a layout with a bare%blows up before the email is sent:width: 100%, a percent-encoded URL, aline-height: 150%in an inline<style>— all of these are ordinary in an HTML email layout, and any one of them takes delivery down.Fix
%{content}is the only token the layout ever interpolated, so a literal substitution covers it. The block form ofgsub(rather thangsub("%{content}", wrapped)) is deliberate: it passes the wrapped body through untouched when it contains\1,\\or\&, which the string-replacement form would eat.Behaviour change
A layout that wrote
%%to get a literal%throughString#%now keeps both characters. That escape was never documented (the README only shows%{content}), and it was the same feature that made bare%crash.Tests
Optionshad no test file — the layout-wrapping path (Options#wrap) was only exercised indirectly. Newtest/courrier/email/options_test.rbcovers the wrap, the literal%, and the backslash-sequence passthrough. Withlib/courrier/email/options.rbreverted the%case errors exactly as above.bundle exec rake teston Ruby 3.4: 162 runs, 306 assertions, 0 failures.rake standardclean.🤖 Generated with Claude Code