Dmytro Shteflyuk created THRIFT-6157:
----------------------------------------
Summary: Ruby CompactProtocol fixed-width reads differ between
native and pure modes
Key: THRIFT-6157
URL: https://issues.apache.org/jira/browse/THRIFT-6157
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
Ruby's pure {{CompactProtocol}} decoder can return arbitrary-precision values
when on-wire varints exceed the declared {{i16}} or {{i64}} width. The native
extension narrows the same bits to the declared Thrift width, so the value
returned by the library depends on whether {{thrift_native}} loaded.
h3. Client impact
The same Compact payload can produce different application values in native and
pure-Ruby deployments. This affects fixed-width integers read as fields,
container elements, map keys, and field identifiers. It also makes behavior
depend on an optional runtime optimization rather than the wire type.
h3. Reproduction
Run the following with {{thrift_native}} available, then with the extension
deliberately unavailable:
{code:language=ruby}
require "thrift"
i16 = Thrift::CompactProtocol.new(
Thrift::MemoryBufferTransport.new([0x80, 0x80, 0x04].pack("C*")),
)
i64 = Thrift::CompactProtocol.new(
Thrift::MemoryBufferTransport.new(
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f].pack("C*"),
),
)
puts "native=#{i16.native?}"
puts "i16=#{i16.read_i16}"
puts "i64=#{i64.read_i64}"
{code}
Testing on master commit {{04c87e89ae25e759123b942d2d73e4cc3415c948}} produces:
{code}
native=true
i16=-32768
i64=-9223372036854775808
{code}
With {{thrift_native}} deliberately unavailable, the same commit produces:
{code}
native=false
i16=32768
i64=-590295810358705651712
{code}
h3. Expected behavior
Native and pure-Ruby Compact readers should preserve the declared fixed-width
integer semantics and return the same values for the same payload. The pure
implementation should narrow these values to signed {{i16}} and {{i64}} widths,
matching the established native behavior, while leaving valid encodings and
existing unsigned-varint overflow validation unchanged.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)