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)