[ 
https://issues.apache.org/jira/browse/THRIFT-6149?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmytro Shteflyuk resolved THRIFT-6149.
--------------------------------------
    Fix Version/s: 0.25.0
       Resolution: Fixed

> 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
>            Priority: Major
>             Fix For: 0.25.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> 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