Skip to content

THRIFT-6045: Add Ruby recursion depth limit - #3691

Open
kpumuk wants to merge 1 commit into
apache:masterfrom
kpumuk:rb-recursion-depth
Open

THRIFT-6045: Add Ruby recursion depth limit#3691
kpumuk wants to merge 1 commit into
apache:masterfrom
kpumuk:rb-recursion-depth

Conversation

@kpumuk

@kpumuk kpumuk commented Jul 31, 2026

Copy link
Copy Markdown
Member

Ruby struct, union, and exception serialization previously had no recursion-depth limit, allowing deeply nested or cyclic values to recurse until the Ruby stack was exhausted.

This adds a call-local remaining-depth budget of 64 to the pure-Ruby and native read/write paths. Nested structs, unions, and exceptions consume the budget while containers pass it through unchanged; unknown and mismatched fields remain independently bounded by the existing protocol skip limit. The optional depth arguments and the migration required for custom exact-arity serialization overrides are documented for Ruby 0.25.0.

  • Did you create an Apache Jira ticket? (THRIFT-6045)
  • 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.

Copilot AI review requested due to automatic review settings July 31, 2026 22:22

This comment was marked as spam.

@mergeable mergeable Bot added the ruby Pull requests that update Ruby code label Jul 31, 2026
@kpumuk
kpumuk requested a review from Jens-G July 31, 2026 22:24
@kpumuk
kpumuk force-pushed the rb-recursion-depth branch from f6b4ee2 to 8af6280 Compare August 1, 2026 00:07
Copilot AI review requested due to automatic review settings August 1, 2026 00:07
Client: rb

Co-Authored-By: OpenAI Codex (GPT-5.6) <codex@openai.com>
@kpumuk
kpumuk force-pushed the rb-recursion-depth branch from 8af6280 to c5761b7 Compare August 1, 2026 00:12

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

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

Suppressed comments (2)

lib/rb/lib/thrift/exceptions.rb:21

  • Thrift::ApplicationException#read/#write references Types::..., but this file doesn’t require thrift/types. If a consumer requires thrift/exceptions directly (or gets it indirectly), calling these methods can raise NameError: uninitialized constant Thrift::Types unless thrift/types was loaded elsewhere. Adding the explicit require here makes the file self-contained.
module Thrift
  DEFAULT_RECURSION_DEPTH = 64

lib/rb/lib/thrift/protocol/base_protocol.rb:23

  • BaseProtocol uses Types::... extensively (e.g., in write_type / read_type), but this file doesn’t require thrift/types. Since it now requires thrift/exceptions, it’s more likely to be loaded directly; adding an explicit require 'thrift/types' avoids NameError when base_protocol is required standalone.
# this require is to make generated struct definitions happy
require 'set'
require 'thrift/exceptions'

Copilot AI review requested due to automatic review settings August 1, 2026 00:13

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

lib/rb/lib/thrift/protocol/base_protocol.rb:253

  • BaseProtocol#write_field always calls write_type with a third argument (remaining_depth), even when it is nil. That changes the call arity from 2→3 for the common case and will break custom protocol implementations that override write_type(field_info, value) with the previous 2-arg signature.

To preserve backward compatibility, only pass remaining_depth when it is non-nil (i.e., when the caller is explicitly propagating a depth budget).

      write_field_begin(field_info[:name], field_info[:type], fid)
      write_type(field_info, value, remaining_depth)
      write_field_end

Comment thread lib/rb/ext/struct.c
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