diff --git a/lib/rb/lib/thrift/transport/memory_buffer_transport.rb b/lib/rb/lib/thrift/transport/memory_buffer_transport.rb index 2ca9d2461b..21fdaeb1ca 100644 --- a/lib/rb/lib/thrift/transport/memory_buffer_transport.rb +++ b/lib/rb/lib/thrift/transport/memory_buffer_transport.rb @@ -23,13 +23,9 @@ module Thrift class MemoryBufferTransport < BaseTransport GARBAGE_BUFFER_SIZE = 4*(2**10) # 4kB - # If you pass a string to this, you should #dup that string - # unless you want it to be modified by #read and #write - #-- - # this behavior is no longer required. If you wish to change it - # go ahead, just make sure the specs pass + # The transport copies the input buffer and keeps its own mutable storage. def initialize(buffer = nil) - @buf = buffer ? Bytes.force_binary_encoding(buffer) : Bytes.empty_byte_buffer + @buf = buffer ? Bytes.force_binary_encoding(buffer.dup) : Bytes.empty_byte_buffer @index = 0 end diff --git a/lib/rb/spec/base_transport_spec.rb b/lib/rb/spec/base_transport_spec.rb index e21a3ec383..854743aebb 100644 --- a/lib/rb/spec/base_transport_spec.rb +++ b/lib/rb/spec/base_transport_spec.rb @@ -305,12 +305,26 @@ expect(@buffer.to_s).to eq("memory") end - it "should accept a buffer on input and use it directly" do - s = +"this is a test" - @buffer = Thrift::MemoryBufferTransport.new(s) - expect(@buffer.read(4)).to eq("this") - s.slice!(-4..-1) - expect(@buffer.read(@buffer.available)).to eq(" is a ") + it "should privately own a buffer passed on input" do + source = +"this is a test" + @buffer = Thrift::MemoryBufferTransport.new(source) + + expect(source.encoding).to eq(Encoding::UTF_8) + source.replace("caller changed") + @buffer.write("!") + + expect(source).to eq("caller changed") + expect(@buffer.read(@buffer.available)).to eq("this is a test!".b) + end + + it "should allow writes and resets after receiving a frozen buffer" do + @buffer = Thrift::MemoryBufferTransport.new("abc".b.freeze) + + @buffer.write("d") + expect(@buffer.read(4)).to eq("abcd") + + @buffer.reset_buffer("xy") + expect(@buffer.read(2)).to eq("xy") end it "should always remain open" do