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