Dmytro Shteflyuk created THRIFT-6103:
----------------------------------------
Summary: Ruby MemoryBufferTransport should return unsigned byte
values
Key: THRIFT-6103
URL: https://issues.apache.org/jira/browse/THRIFT-6103
Project: Thrift
Issue Type: Bug
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
The native implementation of {{Thrift::MemoryBufferTransport#read_byte}} stores
the next byte in a plain C {{char}} before returning it to Ruby.
On platforms where {{char}} is signed, bytes with the high bit set are
sign-extended. For example, {{0x80}} is returned as {{-128}} and {{0xff}} as
{{-1}}. The pure-Ruby implementation returns the normal unsigned byte values,
{{128}} and {{255}}.
h3. Client impact
Ruby clients that call {{MemoryBufferTransport#read_byte}} directly can receive
different values depending on whether {{thrift_native}} is available and on the
platform's C {{char}} representation.
This affects custom protocol code and other transport consumers that interpret
bytes as values in the {{0..255}} range. Higher-level protocol readers often
normalize or mask their input, which is why ordinary serialization can continue
to work despite the inconsistent transport contract.
h3. Reproduction
{code:ruby}
require "thrift"
transport = Thrift::MemoryBufferTransport.new([0x80, 0xff].pack("C*"))
p [transport.read_byte, transport.read_byte]
{code}
With the native extension on a platform with signed C {{char}}, this prints:
{code}
[-128, -1]
{code}
Without the native extension, it prints:
{code}
[128, 255]
{code}
h3. Expected behavior
{{MemoryBufferTransport#read_byte}} should consistently return unsigned byte
values from {{0}} through {{255}}. In particular, {{0x00}}, {{0x7f}}, {{0x80}},
and {{0xff}} should return {{0}}, {{127}}, {{128}}, and {{255}} in both native
and pure-Ruby modes.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)