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