From e80a194c473e94f90b30919da29cbe9b4542e244 Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Tue, 20 Sep 2011 18:45:56 +0000 Subject: [PATCH] THRIFT-1331. rb: Ruby library deserializes an empty map to nil This patch properly detects when the metadata is omitted in Compact Protocol messages. Patch: Armaan Sarkar git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1173300 13f79535-47bb-0310-9956-ffa450edef68 --- lib/rb/ext/struct.c | 2 +- lib/rb/lib/thrift/struct_union.rb | 2 +- lib/rb/spec/compact_protocol_spec.rb | 11 +++++++++++ test/DebugProtoTest.thrift | 4 ++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c index dae338e6..590983f3 100644 --- a/lib/rb/ext/struct.c +++ b/lib/rb/ext/struct.c @@ -484,7 +484,7 @@ static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) { if (!NIL_P(key_info) && !NIL_P(value_info)) { int specified_key_type = FIX2INT(rb_hash_aref(key_info, type_sym)); int specified_value_type = FIX2INT(rb_hash_aref(value_info, type_sym)); - if (specified_key_type == key_ttype && specified_value_type == value_ttype) { + if (num_entries == 0 || (specified_key_type == key_ttype && specified_value_type == value_ttype)) { result = rb_hash_new(); for (i = 0; i < num_entries; ++i) { diff --git a/lib/rb/lib/thrift/struct_union.rb b/lib/rb/lib/thrift/struct_union.rb index 0ff175f6..4e0afcfe 100644 --- a/lib/rb/lib/thrift/struct_union.rb +++ b/lib/rb/lib/thrift/struct_union.rb @@ -56,7 +56,7 @@ module Thrift when Types::MAP key_type, val_type, size = iprot.read_map_begin # Skip the map contents if the declared key or value types don't match the expected ones. - if (key_type != field[:key][:type] || val_type != field[:value][:type]) + if (size != 0 && (key_type != field[:key][:type] || val_type != field[:value][:type])) size.times do iprot.skip(key_type) iprot.skip(val_type) diff --git a/lib/rb/spec/compact_protocol_spec.rb b/lib/rb/spec/compact_protocol_spec.rb index 1fa21822..a88a2ae6 100644 --- a/lib/rb/spec/compact_protocol_spec.rb +++ b/lib/rb/spec/compact_protocol_spec.rb @@ -115,6 +115,17 @@ describe Thrift::CompactProtocol do brcp2.should == brcp end + it "should deserialize an empty map to an empty hash" do + struct = SingleMapTestStruct.new(:i32_map => {}) + ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) + bytes = ser.serialize(struct) + + deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) + struct2 = SingleMapTestStruct.new + deser.deserialize(struct2, bytes) + struct.should == struct2 + end + class JankyHandler def Janky(i32arg) i32arg * 2 diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift index 23d5d973..b8b89b75 100644 --- a/test/DebugProtoTest.thrift +++ b/test/DebugProtoTest.thrift @@ -161,6 +161,10 @@ struct CompactProtoTestStruct { 49: map> byte_list_map; } +// To be used to test the serialization of an empty map +struct SingleMapTestStruct { + 1: required map i32_map; +} const CompactProtoTestStruct COMPACT_TEST = { 'a_byte' : 127, -- 2.17.1