You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@thrift.apache.org by "Dmytro Shteflyuk (Jira)" <ji...@apache.org> on 2026/07/26 18:40:00 UTC

[jira] [Resolved] (THRIFT-6121) Ruby HeaderProtocol emits unparseable errors for unknown protocol IDs

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