Skip to content

THRIFT-6106: Decode fixed-width values without undefined shifts#3647

Merged
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-fixed-width
Jul 20, 2026
Merged

THRIFT-6106: Decode fixed-width values without undefined shifts#3647
kpumuk merged 1 commit into
apache:masterfrom
kpumuk:rb-fixed-width

Conversation

@kpumuk

@kpumuk kpumuk commented Jul 19, 2026

Copy link
Copy Markdown
Member

Native Ruby protocol readers previously assembled fixed-width values through shifts on promoted signed integers. On common builds, those reads can appear to return the expected values, but UBSan exposes the undefined operation for high-bit byte patterns.

Before this change, building and running the focused examples from lib/rb with:

make -C ext clean all CFLAGS='-fPIC -O1 -g -fsanitize=undefined -fno-sanitize-recover=undefined' DLDFLAGS='-fsanitize=undefined'
UBSAN_OPTIONS='halt_on_error=1:print_stacktrace=1' bundle exec rspec spec/binary_protocol_spec.rb spec/compact_protocol_spec.rb --example fixed-width

reports:

compact_protocol.c:618:42: runtime error: left shift of 128 by 24 places cannot be represented in type 'int'

This change builds the binary and compact protocol values with correctly sized unsigned intermediates, then converts to signed values only after assembly. It also preserves double bit patterns when the high bit is set.

  • Did you create an Apache Jira ticket? THRIFT-6106
  • 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.4) <codex@openai.com>
Copilot AI review requested due to automatic review settings July 19, 2026 19:44
@mergeable mergeable Bot added the ruby Pull requests that update Ruby code label Jul 19, 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 undefined behavior in the native Ruby protocol C accelerators when decoding fixed-width integers and doubles, by assembling values using correctly sized unsigned intermediates and converting to signed only after the full value is formed. It also adds regression specs to ensure edge byte patterns (including high-bit cases and negative zero) are preserved as expected.

Changes:

  • Rework fixed-width integer decoding in binary_protocol_accelerated.c to use unsigned assembly plus explicit unsigned→signed conversion helpers.
  • Rework compact protocol double decoding to assemble into a uint64_t to avoid undefined shifts and preserve bit patterns.
  • Add Ruby specs covering signed edge byte patterns and double edge byte patterns.

Reviewed changes

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

File Description
lib/rb/spec/compact_protocol_spec.rb Adds regression spec to ensure compact double decoding preserves edge-case byte patterns.
lib/rb/spec/binary_protocol_spec_shared.rb Adds regression spec for fixed-width signed integer edge byte patterns across i16/i32/i64.
lib/rb/ext/compact_protocol.c Avoids undefined shifts and signed conversions by assembling doubles via uint64_t byte-wise.
lib/rb/ext/binary_protocol_accelerated.c Avoids undefined shifts by assembling integers/doubles via unsigned intermediates and explicit conversions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kpumuk
kpumuk merged commit 35291f7 into apache:master Jul 20, 2026
95 checks passed
@kpumuk
kpumuk deleted the rb-fixed-width branch July 20, 2026 15:36
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