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)

Reply via email to