Dmytro Shteflyuk created THRIFT-6155:
----------------------------------------

             Summary: Ruby SimpleServer exits on zero-length framed messages
                 Key: THRIFT-6155
                 URL: https://issues.apache.org/jira/browse/THRIFT-6155
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

Ruby's {{FramedTransport}} accepts a frame header whose declared payload length 
is zero. Its optimized read paths then attempt to read a byte from an empty 
frame and return or operate on {{nil}} instead of raising a Thrift transport 
error.

When this reaches {{CompactProtocol}}, the native implementation raises a Ruby 
{{TypeError}} and the pure-Ruby implementation raises a {{NoMethodError}}. 
{{SimpleServer}} treats typed transport and protocol exceptions as 
connection-local failures, but these raw Ruby exceptions escape the serve loop 
and close the listener.

h3. Client impact

A client connection that sends a zero-length frame can cause a Ruby 
{{SimpleServer}} to stop accepting further connections. Other server 
implementations may contain the failure to a connection worker, but callers 
still receive implementation-dependent Ruby exceptions rather than a consistent 
Thrift transport error.

h3. Reproduction

The transport-level behavior can be reproduced with:

{code:language=ruby}
require "thrift"

frame = [0].pack("N")
transport = Thrift::FramedTransport.new(
  Thrift::MemoryBufferTransport.new(frame),
)

p transport.read_byte
{code}

Testing on master commit {{04c87e89ae25e759123b942d2d73e4cc3415c948}} produces:

{noformat}
nil
{noformat}

A deterministic loopback {{SimpleServer}} reproduction using framed Compact 
protocol produced:

{noformat}
native=true
server_error=TypeError: no implicit conversion from nil to integer
listener_closed=true
{noformat}

With {{thrift_native}} deliberately disabled, the same reproduction produced:

{noformat}
native=false
server_error=NoMethodError: undefined method '>' for nil
listener_closed=true
{noformat}

h3. Expected behavior

{{FramedTransport}} should reject a zero-length frame with a typed transport 
exception before any optimized reader accesses the empty payload. {{read}}, 
{{read_byte}}, and {{read_into_buffer}} should follow the same contract.

{{SimpleServer}} should close only the affected connection and continue 
accepting subsequent valid requests.




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

Reply via email to