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