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

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

> Ruby Serializer should finalize buffered protocol transports
> ------------------------------------------------------------
>
>                 Key: THRIFT-6147
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6147
>             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
> {{Thrift::Serializer#serialize}} writes a value through its protocol and then 
> immediately reads the serializer's backing memory buffer. It does not flush 
> the transport selected by the protocol factory first.
> This works for protocols that write directly to {{MemoryBufferTransport}}, 
> whose {{flush}} is a no-op. It does not work when the protocol factory 
> introduces a buffering or framing transport. {{HeaderTransport}} and 
> {{FramedTransport}} retain the encoded bytes until they are flushed, so the 
> serializer returns an empty string instead of the completed wire 
> representation.
> h3. Client impact
> Ruby callers using {{HeaderProtocolFactory}} receive an empty serialized 
> payload without an exception. The same behavior affects custom protocol 
> factories that compose a protocol with {{FramedTransport}}. A caller can 
> therefore store or send an empty payload while believing serialization 
> succeeded.
> h3. Reproduction
> Save the following as {{reproduce_serializer.rb}}:
> {code:ruby}
> require "thrift"
> class FramedBinaryProtocolFactory
>   def get_protocol(transport)
>     Thrift::BinaryProtocol.new(Thrift::FramedTransport.new(transport))
>   end
> end
> value = Thrift::ApplicationException.new(
>   Thrift::ApplicationException::UNKNOWN,
>   "example"
> )
> header = Thrift::Serializer.new(
>   Thrift::HeaderProtocolFactory.new
> ).serialize(value)
> framed = Thrift::Serializer.new(
>   FramedBinaryProtocolFactory.new
> ).serialize(value)
> puts "header_bytes=#{header.bytesize}"
> puts "framed_bytes=#{framed.bytesize}"
> {code}
> Run it from {{lib/rb}}:
> {code:bash}
> bundle exec ruby -Ilib reproduce_serializer.rb
> {code}
> Testing on master commit {{c2def39207a73394420088da9b4b105571dd9036}} 
> produces:
> {code}
> header_bytes=0
> framed_bytes=0
> {code}
> h3. Expected behavior
> {{Serializer}} should flush the transport exposed by the selected protocol 
> before reading its backing memory buffer. This finalizes Header, Framed, and 
> other conforming buffered transport output, while preserving existing 
> behavior for direct memory protocols because {{MemoryBufferTransport#flush}} 
> is a no-op.
> The returned payload should contain the complete wire representation and be 
> readable by the corresponding protocol stack.



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

Reply via email to