Dmytro Shteflyuk created THRIFT-6158:
----------------------------------------
Summary: Ruby processor should classify malformed request
arguments as protocol errors
Key: THRIFT-6158
URL: https://issues.apache.org/jira/browse/THRIFT-6158
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
Generated Ruby processors deserialize request arguments inside method-specific
dispatch code. {{Thrift::Processor#process}} wraps that dispatch in a broad
rescue and converts every {{StandardError}} into
{{ApplicationException::INTERNAL_ERROR}}.
As a result, a {{ProtocolException}} raised while decoding malformed request
arguments loses its protocol-error classification and message. The response
instead reports a generic internal server failure.
h3. Client impact
A client that sends malformed argument data receives {{INTERNAL_ERROR}}, which
normally indicates an unexpected server or handler failure. It cannot
distinguish invalid wire data from an internal implementation problem, and the
useful decoder error is lost.
The method name and sequence ID are preserved, but the application-exception
type and message are misleading.
h3. Reproduction
Save the following as {{/tmp/repro.rb}} and run it from {{lib/rb}} with:
{code}
bundle exec ruby -Ilib -Ispec/gen-rb /tmp/repro.rb
{code}
{code:ruby}
require "thrift"
require "nonblocking_service"
input = Thrift::MemoryBufferTransport.new(
'[1,"sleep",1,7,{"1":{"dbl":x}}]'
)
output = Thrift::MemoryBufferTransport.new
processor = SpecNamespace::NonblockingService::Processor.new(Object.new)
processor.process(
Thrift::JsonProtocol.new(input),
Thrift::JsonProtocol.new(output)
)
response = Thrift::JsonProtocol.new(output)
name, message_type, seqid = response.read_message_begin
exception = Thrift::ApplicationException.new
exception.read(response)
response.read_message_end
puts "name=#{name}"
puts "message_type=#{message_type}"
puts "seqid=#{seqid}"
puts "exception_type=#{exception.type}"
puts "message=#{exception.message.inspect}"
{code}
The malformed {{dbl}} argument is identified by {{read_args}} as
{{Thrift::ProtocolException}} with type {{INVALID_DATA}} and message
{{"Expected numeric value; got \"\""}}.
Testing on master commit {{6320b0b1c762bac2a6514bb634d71df049b9723c}} produces:
{code}
name=sleep
message_type=3
seqid=7
exception_type=6
message="Internal error"
{code}
Here, message type {{3}} is {{EXCEPTION}} and exception type {{6}} is
{{INTERNAL_ERROR}}.
h3. Expected behavior
A {{ProtocolException}} raised while deserializing request arguments should be
returned as {{ApplicationException::PROTOCOL_ERROR}}, preserving the decoder
message, request method name, and sequence ID. The request handler must not be
invoked.
Unexpected handler or server failures should continue to use {{INTERNAL_ERROR}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)