fix: escape non-Latin-1 characters in challenge auth-params - #813
Merged
brendanjryan merged 1 commit intoAug 20, 2026
Merged
Conversation
Challenge.serialize writes the charge description into the WWW-Authenticate header, whose values must be ByteStrings (code points <= 0xFF). A description containing an em dash, smart quote, or emoji made Response construction throw "Cannot convert argument to a ByteString" deep inside undici, with no hint of the cause. Real-world product titles hit this constantly. Serialize now escapes characters above Latin-1 as \uXXXX inside quoted strings, and the quoted-string parser decodes them. The escape is unambiguous: serializers always double raw backslashes, so a bare \u can only come from this encoding. Old parsers degrade to showing the literal escape in the display-only description rather than breaking.
Collaborator
|
LGTM! |
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.
Problem
Challenge.serializewrites the chargedescriptioninto theWWW-Authenticateheader raw. Header values must be ByteStrings (code points ≤ 0xFF), so any description containing an em dash, smart quote, or emoji makesResponseconstruction throw in fetch-compliant runtimes:Minimal repro:
We hit this in production: merchant product titles routinely contain em dashes, so any integrator passing a title through
charge({ description })gets an opaque crash on the challenge response. (Existing serialize/deserialize tests pass because they never place the serialized value into a realHeaders/Response.)Fix
authParamnow escapes characters above Latin-1 as\uXXXXinside quoted strings, and the quoted-string parser decodes them. The escape is unambiguous with the existing convention: serializers always double raw backslashes, so a bare\ucan only come from this encoding. Older parsers degrade to rendering the literal escape in the display-only description rather than failing.test.eachescape table (em dash, surrogate pairs + quotes).🤖 Generated with Claude Code