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)

Reply via email to