Raise an error when nil is sent to binary protocol write operations
Currently, when accelerated binary protocol is used, and nil is passed to write operations like write_byte, write_i16, write_i32, write_i64, write_double, write_string, or write_binary, the code raises a StandardError with 'nil argument not allowed!' message. Ruby version (non-accelerated) instead raises random exceptions like NoMethodError or TypeError. This behavior is inconsistent with the expectation that a StandardError with the message 'nil argument not allowed!' should be raised.
1) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil byte
Failure/Error: expect { @prot.write_byte(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<NoMethodError: undefined method '<' for nil> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:85:in 'Thrift::BinaryProtocol#write_byte'
# ./spec/binary_protocol_spec_shared.rb:125:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:125:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:125:in 'block (2 levels) in <top (required)>'
2) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil i16
Failure/Error: expect { @prot.write_i16(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<TypeError: no implicit conversion of nil into Integer> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:90:in 'Thrift::BinaryProtocol#write_i16'
# ./spec/binary_protocol_spec_shared.rb:144:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:144:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:144:in 'block (2 levels) in <top (required)>'
3) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil i32
Failure/Error: expect { @prot.write_i32(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<NoMethodError: undefined method '<' for nil> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:94:in 'Thrift::BinaryProtocol#write_i32'
# ./spec/binary_protocol_spec_shared.rb:161:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:161:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:161:in 'block (2 levels) in <top (required)>'
4) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil i64
Failure/Error: expect { @prot.write_i64(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<NoMethodError: undefined method '<' for nil> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:99:in 'Thrift::BinaryProtocol#write_i64'
# ./spec/binary_protocol_spec_shared.rb:184:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:184:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:184:in 'block (2 levels) in <top (required)>'
5) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil double
Failure/Error: expect { @prot.write_double(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<TypeError: can't convert nil into Float> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:106:in 'Thrift::BinaryProtocol#write_double'
# ./spec/binary_protocol_spec_shared.rb:197:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:197:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:197:in 'block (2 levels) in <top (required)>'
6) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil string
Failure/Error: expect { @prot.write_string(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<NoMethodError: undefined method 'encoding' for nil> with backtrace:
# ./lib/thrift/bytes.rb:79:in 'Thrift::Bytes.convert_to_utf8_byte_buffer'
# ./lib/thrift/protocol/binary_protocol.rb:110:in 'Thrift::BinaryProtocol#write_string'
# ./spec/binary_protocol_spec_shared.rb:250:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:250:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:250:in 'block (2 levels) in <top (required)>'
7) BinaryProtocol it should behave like a binary protocol should error gracefully when trying to write a nil binary
Failure/Error: expect { @prot.write_binary(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
expected StandardError with "nil argument not allowed!", got #<NoMethodError: undefined method 'bytesize' for nil> with backtrace:
# ./lib/thrift/protocol/binary_protocol.rb:115:in 'Thrift::BinaryProtocol#write_binary'
# ./spec/binary_protocol_spec_shared.rb:254:in 'block (3 levels) in <top (required)>'
# ./spec/binary_protocol_spec_shared.rb:254:in 'block (2 levels) in <top (required)>'
Shared Example Group: "a binary protocol" called from ./spec/binary_protocol_spec.rb:25
# ./spec/binary_protocol_spec_shared.rb:254:in 'block (2 levels) in <top (required)>'
diff --git a/lib/rb/lib/thrift/protocol/binary_protocol.rb b/lib/rb/lib/thrift/protocol/binary_protocol.rb
index d8279db..ce5d0d7 100644
--- a/lib/rb/lib/thrift/protocol/binary_protocol.rb
+++ b/lib/rb/lib/thrift/protocol/binary_protocol.rb
@@ -82,20 +82,24 @@
end
def write_byte(byte)
+ raise 'nil argument not allowed!' if byte.nil?
raise RangeError if byte < -2**31 || byte >= 2**32
trans.write([byte].pack('c'))
end
def write_i16(i16)
+ raise 'nil argument not allowed!' if i16.nil?
trans.write([i16].pack('n'))
end
def write_i32(i32)
+ raise 'nil argument not allowed!' if i32.nil?
raise RangeError if i32 < -2**31 || i32 >= 2**31
trans.write([i32].pack('N'))
end
def write_i64(i64)
+ raise 'nil argument not allowed!' if i64.nil?
raise RangeError if i64 < -2**63 || i64 >= 2**64
hi = i64 >> 32
lo = i64 & 0xffffffff
@@ -103,15 +107,18 @@
end
def write_double(dub)
+ raise 'nil argument not allowed!' if dub.nil?
trans.write([dub].pack('G'))
end
def write_string(str)
+ raise 'nil argument not allowed!' if str.nil?
buf = Bytes.convert_to_utf8_byte_buffer(str)
write_binary(buf)
end
def write_binary(buf)
+ raise 'nil argument not allowed!' if buf.nil?
write_i32(buf.bytesize)
trans.write(buf)
end
diff --git a/lib/rb/spec/binary_protocol_spec_shared.rb b/lib/rb/spec/binary_protocol_spec_shared.rb
index 58d65f0..4baedd7 100644
--- a/lib/rb/spec/binary_protocol_spec_shared.rb
+++ b/lib/rb/spec/binary_protocol_spec_shared.rb
@@ -122,7 +122,7 @@
end
it "should error gracefully when trying to write a nil byte" do
- expect { @prot.write_byte(nil) }.to raise_error
+ expect { @prot.write_byte(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
it "should write an i16" do
@@ -141,7 +141,7 @@
end
it "should error gracefully when trying to write a nil i16" do
- expect { @prot.write_i16(nil) }.to raise_error
+ expect { @prot.write_i16(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
it "should write an i32" do
@@ -158,7 +158,7 @@
end
it "should error gracefully when trying to write a nil i32" do
- expect { @prot.write_i32(nil) }.to raise_error
+ expect { @prot.write_i32(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
it "should write an i64" do
@@ -181,7 +181,7 @@
end
it "should error gracefully when trying to write a nil i64" do
- expect { @prot.write_i64(nil) }.to raise_error
+ expect { @prot.write_i64(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
it "should write a double" do
@@ -194,7 +194,7 @@
end
it "should error gracefully when trying to write a nil double" do
- expect { @prot.write_double(nil) }.to raise_error
+ expect { @prot.write_double(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
if RUBY_VERSION >= '1.9'
@@ -247,9 +247,13 @@
end
it "should error gracefully when trying to write a nil string" do
- expect { @prot.write_string(nil) }.to raise_error
+ expect { @prot.write_string(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
end
-
+
+ it "should error gracefully when trying to write a nil binary" do
+ expect { @prot.write_binary(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
+ end
+
it "should write the message header without version when writes are not strict" do
@prot = protocol_class.new(@trans, true, false) # no strict write
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)