[
https://issues.apache.org/jira/browse/THRIFT-6155?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dmytro Shteflyuk resolved THRIFT-6155.
--------------------------------------
Fix Version/s: 0.25.0
Resolution: Fixed
> 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
> Priority: Major
> Fix For: 0.25.0
>
> Time Spent: 20m
> Remaining Estimate: 0h
>
> 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)