[ 
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)

Reply via email to