Dmytro Shteflyuk created THRIFT-6121:
----------------------------------------
Summary: Ruby HeaderProtocol emits unparseable errors for unknown
protocol IDs
Key: THRIFT-6121
URL: https://issues.apache.org/jira/browse/THRIFT-6121
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
When Ruby HeaderProtocol reads an otherwise valid Header frame containing an
unknown subprotocol ID, it raises a ProtocolException and attempts to return an
INVALID_PROTOCOL ApplicationException. The response Header frame still
advertises the unknown, peer-supplied subprotocol ID, however, so the receiver
cannot select a Binary or Compact decoder to read the error. The response also
replaces the incoming Header sequence ID with zero.
h3. Client impact
A client cannot decode the typed application error and instead fails again
while selecting a protocol for the response. Replacing the sequence ID also
prevents the response from being correlated with the request that caused it.
The useful "Unknown protocol ID" diagnostic is therefore trapped inside a
response that a normal HeaderProtocol reader cannot consume.
h3. Reproduction
Save the following as {{/tmp/header_unknown_protocol.rb}}:
{code:language=ruby}
require "thrift"
# Header frame with sequence ID 77 and unknown subprotocol ID 16.
frame = [14, 0x0fff, 0, 77, 1].pack("NnnNn")
frame << "\x10\x00\x00\x00".b
buffer = Thrift::MemoryBufferTransport.new(frame)
protocol = Thrift::HeaderProtocol.new(buffer)
begin
protocol.read_message_begin
rescue Thrift::ProtocolException
end
response = buffer.read(buffer.available)
puts "response_protocol_id=#{response.getbyte(14)} " \
"response_sequence_id=#{response.byteslice(8, 4).unpack1("N")} " \
"bytes=#{response.bytesize}"
reader = Thrift::HeaderProtocol.new(
Thrift::MemoryBufferTransport.new(response)
)
reader.read_message_begin
{code}
Run it from {{lib/rb}}:
{code:bash}
bundle exec ruby -Ilib /tmp/header_unknown_protocol.rb
{code}
The response retains protocol ID 16, loses sequence ID 77, and cannot be parsed:
{code}
response_protocol_id=16 response_sequence_id=0 bytes=50
Thrift::ProtocolException: Unknown protocol ID: 16
{code}
h3. Expected behavior
The error response should use the HeaderProtocol instance's configured,
supported default subprotocol and preserve the parsed Header sequence ID. A
fresh HeaderProtocol reader should be able to decode an EXCEPTION message
containing an INVALID_PROTOCOL ApplicationException with the original
diagnostic. If a malformed header cannot be parsed far enough to obtain safe
response metadata, handling it must not recursively emit another unparseable
response.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)