Dmytro Shteflyuk created THRIFT-6149:
----------------------------------------

             Summary: Ruby Binary and Compact protocols should avoid decoding 
skipped strings
                 Key: THRIFT-6149
                 URL: https://issues.apache.org/jira/browse/THRIFT-6149
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

When generated Ruby code encounters an unknown field with Thrift type 
{{STRING}}, {{BaseProtocol#skip}} reads it through {{read_string}}. For the 
Binary and Compact protocols, this first consumes the value as binary data and 
then constructs a UTF-8 string even though the value is immediately discarded.

Skipping should consume the wire value without performing representation work 
that cannot affect the result. JSON must retain its string-reading behavior 
because JSON strings and binary values have different wire representations.

h3. Client impact

Ruby clients and servers skip unknown fields when communicating across schema 
versions. Messages containing unknown string fields therefore create an 
unnecessary temporary string for every skipped value and spend additional time 
applying string encoding semantics.

The overhead scales with the number of skipped values. A focused benchmark 
using 100,000 128-byte strings observed one fewer allocation per skipped value 
and lower skip time for Binary and Compact protocols when consuming the raw 
bytes directly. The wire format and decoded values of known fields are 
unaffected.

h3. Reproduction

>From {{lib/rb}}, run:

{code:bash}
bundle exec ruby -Ilib -Iext <<'RUBY'
require "thrift"

class TrackingBinaryProtocol < Thrift::BinaryProtocol
  attr_reader :reads

  def initialize(transport)
    super
    @reads = []
  end

  def read_string
    @reads << :string
    super
  end

  def read_binary
    @reads << :binary
    super
  end
end

transport = Thrift::MemoryBufferTransport.new
protocol = TrackingBinaryProtocol.new(transport)
protocol.write_string("value")
protocol.skip(Thrift::Types::STRING)

puts protocol.reads.join(" -> ")
RUBY
{code}

Testing on master commit {{9b10484ca7687af6cc67567df9d457d0f031748e}} produces:

{code}
string -> binary
{code}

The skipped value enters the string-decoding path before its underlying binary 
bytes are consumed.

h3. Expected behavior

Binary and Compact protocols should consume skipped {{STRING}} values through 
their raw binary readers, avoiding unnecessary string conversion. JSON and 
custom protocols should retain the existing {{read_string}} contract unless 
they explicitly specialize skipped-string handling.

Header and decorated protocols should preserve the behavior of their selected 
or wrapped protocol. Skipping must consume exactly the same wire bytes as 
before and must not change handling of known fields.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to