Skip to content

Split recipient strings without breaking a quoted display name - #63

Open
pcbeingused333 wants to merge 3 commits into
Rails-Designer:mainfrom
pcbeingused333:fix/split-addresses-on-quoted-display-name
Open

pcbeingused333 wants to merge 3 commits into
Rails-Designer:mainfrom
pcbeingused333:fix/split-addresses-on-quoted-display-name

Conversation

@pcbeingused333

@pcbeingused333 pcbeingused333 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The bug

Courrier::Email::Address.with_name quotes any display name that contains a special character, so with_name("jane@example.com", "Doe, Jane") returns:

"Doe, Jane" <jane@example.com>

Every provider then feeds to / cc / bcc / from / reply_to through Providers::Base#address_list, which does value.to_s.split(","). That tears the quoted name in two:

'"Doe, Jane" <jane@example.com>'.split(",").map(&:strip)
# => ["\"Doe", "Jane\" <jane@example.com>"]

So the recipient goes out as two malformed addresses. address_line (Mailgun, MailPace, Postmark, and SparkPost's CC header) rejoins the pieces with ", ", which hides the break for a single recipient but still rewrites any name whose comma isn't already followed by exactly one space ("Doe,Jane""Doe, Jane").

The address test suite already pins with_name producing "Doe, John" <...>, so the two halves of the library disagree.

The fix

split_addresses now splits only on commas that are outside a double-quoted display name ("(?:\\.|[^"\\])*"), so a quoted name survives intact and a plain a@x, b@y list still splits as before. Blank input (nil, "", " ", ",") still returns nil.

Three providers still hand-rolled their own recipient parsing and had the same class of bug; they now go through address_list like everyone else:

Tests

  • test/courrier/providers/base_test.rbaddress_list / address_line directly: quoted comma, quoted comma among several addresses, escaped quote, blank input.
  • New smtp2go_test.rb, lettermint_test.rb, ses_test.rb (none had a test file) — full body, quoted-name recipient, comma-string splitting, empty-field omission, registry wiring.
  • Added the quoted-name case to brevo_test (address_list path) and mailgun_test (address_line path).

11 of the new assertions fail on main and pass with the fix. bundle exec rake and bundle exec standardrb are green (181 runs, 0 failures).

🤖 Generated with Claude Code

pcbeingused333 and others added 3 commits September 8, 2026 13:16
address_list splits to/cc/bcc/from/reply_to on every comma, so a name
with a comma in it -- "Doe, Jane" <jane@example.com>, which is exactly
what Courrier::Email::Address.with_name produces -- is torn into two
malformed addresses. address_line then rejoins the pieces with ", ",
which hides the break for a single recipient but still rewrites any name
whose comma is not already followed by one space.

Splitting now skips commas inside a double-quoted display name. Smtp2go
and Lettermint, which still split by hand, go through the shared helper
too, which also drops their empty "" entries the way Rails-Designer#61 did elsewhere.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GtYgwYNfJ3wHrw9xrooVoB
SES built ToAddresses / CcAddresses / BccAddresses / ReplyToAddresses
with Array(@options.to), which wraps a comma-separated string in a
one-element list instead of splitting it -- so several recipients went
out as one malformed address (the same shape as Rails-Designer#59), and an empty cc
became [""]. It now uses address_list, like every other provider.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GtYgwYNfJ3wHrw9xrooVoB
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GtYgwYNfJ3wHrw9xrooVoB
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.

1 participant