Skip to content

Reject malformed Connect END_STREAM JSON#192

Merged
iainmcgin merged 2 commits into
anthropics:mainfrom
fallintoplace:fix-connect-end-stream-json
Jun 28, 2026
Merged

Reject malformed Connect END_STREAM JSON#192
iainmcgin merged 2 commits into
anthropics:mainfrom
fallintoplace:fix-connect-end-stream-json

Conversation

@fallintoplace

Copy link
Copy Markdown
Contributor

Summary

  • Reject malformed Connect END_STREAM JSON as an internal protocol error instead of treating it as an empty successful terminator.
  • Share END_STREAM parsing, trailer conversion, and error conversion between the server-stream and client-stream response paths.
  • Add regression coverage for malformed END_STREAM JSON in both paths.

Why

The client used serde_json::from_slice(...).unwrap_or_default() when parsing Connect END_STREAM payloads. Invalid JSON therefore became the default successful end-stream shape, so a malformed protocol terminator could be reported as a clean RPC completion.

Testing

  • cargo test -p connectrpc malformed_end_stream_json
  • cargo test -p connectrpc
  • cargo test --workspace
  • cargo check -p connectrpc --no-default-features
  • cargo clippy -p connectrpc --all-targets --all-features -- -D warnings
  • git diff --check

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

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

@fallintoplace

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 Jun 22, 2026
The metadata_to_trailers helper extracted in this branch contained the
pre-anthropics#169 uncapped HeaderMap::append loop, which panics once the map
reaches its 32k-entry hard ceiling — a server can hit that with a few
hundred KB of END_STREAM JSON. main replaced both call sites with
append_metadata_capped (try_append + stop at the cap) in anthropics#169; keep
that, drop the helper.

Also drops the now-dead Default derive on ClientEndStreamResponse
(existed only for the removed unwrap_or_default()) and adds the
CHANGELOG entry alongside its anthropics#163/anthropics#168 siblings.

@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] Thanks — the fix is correct and the regression tests are well-targeted. I pushed one maintainer commit (d55d2da) that merges main and resolves the conflict in client/mod.rs:

  • Dropped metadata_to_trailers and kept main's append_metadata_capped at both call sites. The extracted helper carried the pre-#169 uncapped HeaderMap::append loop, which panics at the map's ~32k-entry ceiling — a server can hit that with a few hundred KB of END_STREAM JSON. #169 replaced both sites with try_append-and-stop; the resolution preserves that guard while keeping your parse_connect_end_stream / end_stream_error_to_connect_error extractions.
  • Removed the Default derive on ClientEndStreamResponse — it existed only for the unwrap_or_default() this PR removes, and leaving it would let a future .unwrap_or_default() compile and silently reintroduce the bug.
  • Added a CHANGELOG.md entry under [Unreleased] / Fixed alongside its #163/#168 siblings, plus doc comments on the two new helpers.

One pre-existing asymmetry surfaced during review (not a regression here, so not addressed in this PR): the server-stream parse-error path at process_end_stream doesn't attach self.headers to the returned ConnectError, while the client-stream path does. Worth a follow-up to make them uniform.

LGTM with the above applied.

@iainmcgin iainmcgin enabled auto-merge June 28, 2026 17:51
@iainmcgin iainmcgin added this pull request to the merge queue Jun 28, 2026
Merged via the queue into anthropics:main with commit dcc7830 Jun 28, 2026
13 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 28, 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.

2 participants