Skip to content

THRIFT-6148: Enforce complete Ruby Header frame limits - #3712

Merged
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-header-frame-limit
Aug 13, 2026
Merged

THRIFT-6148: Enforce complete Ruby Header frame limits#3712
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-header-frame-limit

Conversation

@kpumuk

@kpumuk kpumuk commented Aug 13, 2026

Copy link
Copy Markdown
Member

Ruby HeaderTransport currently applies max_frame_size to the payload before constructing the Header frame. The reader applies the same limit to the complete size declared on the wire, which also includes the fixed Header envelope, transformed payload, metadata, and padding. A writer can therefore emit a frame that a reader configured with the identical limit rejects.

This change validates the completed declared Header frame after transforms and header construction, before writing any bytes. The four-byte length prefix remains excluded, matching the read-side contract; each Header field and payload byte is counted exactly once. Framed and unframed Binary/Compact compatibility modes keep their existing accounting. Pending one-shot headers also remain available when this local validation rejects a frame before delivery.

Benchmarks

The repository Header write benchmark ran 10,000 small-structure writes per scenario for six trials, with the first trial discarded as warm-up:

ruby /thrift/src/test/rb/benchmarks/protocol_benchmark.rb \
  --scenarios hdr-bin-write-small,hdr-cmp-write-small,hdr-zlib-write-small \
  --small-runs 10000 \
  --json

Pure-Ruby controls used the identical command with THRIFT_BENCHMARK_SKIP_NATIVE=1. Current master and the proposed change used the same Ruby container and rebuilt native extension. Times are median seconds, with the measured five-trial range in parentheses.

Mode Scenario Master Proposed Delta
Native Header Binary 0.153373 (0.150825–0.159381) 0.154013 (0.151142–0.155030) +0.42%
Native Header Compact 0.128464 (0.121187–0.132505) 0.128461 (0.125729–0.132922) 0.00%
Native Header ZLIB 0.206152 (0.204393–0.210734) 0.205150 (0.201781–0.207064) -0.49%
Pure Ruby Header Binary 0.200360 (0.197171–0.210889) 0.198534 (0.192370–0.205776) -0.91%
Pure Ruby Header Compact 0.204374 (0.202167–0.207060) 0.204823 (0.200498–0.211956) +0.22%
Pure Ruby Header ZLIB 0.251476 (0.248048–0.254244) 0.250412 (0.248805–0.261224) -0.42%

All before-and-after ranges overlap; the results show no meaningful performance change.

  • Did you create an Apache Jira ticket? THRIFT-6148
  • If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
  • Did you squash your changes to a single commit? (not required, but preferred)
  • Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"?
  • If your change does not involve any code, include [skip ci] anywhere in the commit message to free up build resources.

Client: rb

Co-Authored-By: OpenAI Codex (GPT-5.6) <codex@openai.com>
Copilot AI lite review requested due to automatic review settings August 13, 2026 13:55
@mergeable mergeable Bot added the ruby Pull requests that update Ruby code label Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a mismatch in Ruby HeaderTransport frame size enforcement by validating max_frame_size against the fully constructed Header frame (post-transforms, metadata, and padding), aligning write-side behavior with what the reader enforces on the declared on-wire frame size (excluding the 4-byte length prefix).

Changes:

  • Validate Header-format frame size after header construction/transforms and before writing bytes, so writers and readers with the same max_frame_size agree.
  • Centralize size checking via validate_frame_size! and apply it consistently to framed/unframed compatibility write paths.
  • Expand Ruby specs to cover complete-frame accounting, metadata/padding inclusion, transform effects, and header preservation across rejected flushes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
lib/rb/lib/thrift/transport/header_transport.rb Moves size validation to occur after Header frame construction; adds validate_frame_size! and uses it for legacy framed/unframed write paths.
lib/rb/spec/header_transport_spec.rb Adds targeted tests to ensure the limit applies to the complete Header frame (including transforms/metadata/padding) and verifies retry behavior after local validation failures.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@kpumuk
kpumuk merged commit 9b10484 into apache:master Aug 13, 2026
94 of 95 checks passed
@kpumuk
kpumuk deleted the rb-header-frame-limit branch August 13, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ruby Pull requests that update Ruby code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants