Dmytro Shteflyuk created THRIFT-6145:
----------------------------------------

             Summary: Validate Ruby Compact decoder varint and binary size 
bounds
                 Key: THRIFT-6145
                 URL: https://issues.apache.org/jira/browse/THRIFT-6145
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

The Ruby CompactProtocol decoder accepts fifth-byte payload bits that do not 
fit in a 32-bit varint. The pure-Ruby and native implementations then produce 
different values for the same bytes. Compact binary length prefixes are decoded 
as unsigned 32-bit values and passed to the transport even when they exceed the 
signed int32 size domain used by Thrift binary values.

h3. Client impact

Malformed Compact input can be interpreted inconsistently by the pure-Ruby and 
native decoders. Oversized declared binary lengths are delegated to 
{{read_all}} instead of being rejected by CompactProtocol, so callers receive a 
transport or EOF failure rather than a protocol size exception.

h3. Reproduction

{code:ruby}
require "thrift"

overflow = [0x80, 0x80, 0x80, 0x80, 0x10].pack("C*")
protocol = Thrift::CompactProtocol.new(
  Thrift::MemoryBufferTransport.new(overflow)
)
p protocol.read_i32

oversized = [0x80, 0x80, 0x80, 0x80, 0x08].pack("C*")
protocol = Thrift::CompactProtocol.new(
  Thrift::MemoryBufferTransport.new(oversized)
)
protocol.read_binary
{code}

Testing on master commit {{c2def39207a73394420088da9b4b105571dd9036}} produces:

* {{read_i32}} returns {{2147483648}} in pure Ruby and {{0}} with the native 
extension for {{80 80 80 80 10}}.
* Binary length prefixes for {{2147483648}} and {{4294967295}} reach 
{{read_all}} with those values and then raise {{EOFError}}.
* A valid fifth-byte varint, signed {{i32}} minimum, binary length 
{{2147483647}}, and a one-byte binary value remain accepted.

h3. Expected behavior

CompactProtocol should reject fifth-byte payload bits outside the uint32 domain 
with {{ProtocolException::INVALID_DATA}}. Binary lengths above {{2147483647}} 
should raise {{ProtocolException::SIZE_LIMIT}} before the protocol calls 
{{read_all}}. Valid uint32 varints, signed {{i32}} values, binary sizes through 
{{INT32_MAX}}, and ordinary Compact messages should remain supported.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to