From: David Reiss Date: Mon, 30 Mar 2009 20:46:47 +0000 (+0000) Subject: THRIFT-127. erlang: Skip fields that have the wrong type X-Git-Tag: 0.2.0~197 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=233ace53f04abe48b974aa0b51002ecb7134837b;p=common%2Fthrift.git THRIFT-127. erlang: Skip fields that have the wrong type In the other languages (AFAIK), if a field has the wrong type, it is silently skipped. Erlang currently assumes that the type is correct and de-synchronizes. This change makes it behave like the other languages (except that it is not silent). git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@760161 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/lib/erl/src/thrift_protocol.erl b/lib/erl/src/thrift_protocol.erl index a514d8fe..e6045e2e 100644 --- a/lib/erl/src/thrift_protocol.erl +++ b/lib/erl/src/thrift_protocol.erl @@ -140,19 +140,30 @@ read_struct_loop(IProto, SDict, RTuple) -> _Else -> case dict:find(Fid, SDict) of {ok, {Type, Index}} -> - {ok, Val} = read(IProto, Type), - thrift_protocol:read(IProto, field_end), - NewRTuple = setelement(Index, RTuple, Val), - read_struct_loop(IProto, SDict, NewRTuple); + case term_to_typeid(Type) of + FType -> + {ok, Val} = read(IProto, Type), + thrift_protocol:read(IProto, field_end), + NewRTuple = setelement(Index, RTuple, Val), + read_struct_loop(IProto, SDict, NewRTuple); + Expected -> + error_logger:info_msg( + "Skipping field ~p with wrong type (~p != ~p)~n", + [Fid, FType, Expected]), + skip_field(FType, IProto, SDict, RTuple) + end; _Else2 -> - error_logger:info_msg("Skipping fid ~p~n", [Fid]), - FTypeAtom = thrift_protocol:typeid_to_atom(FType), - thrift_protocol:skip(IProto, FTypeAtom), - read(IProto, field_end), - read_struct_loop(IProto, SDict, RTuple) + error_logger:info_msg("Skipping field ~p with unknown fid~n", [Fid]), + skip_field(FType, IProto, SDict, RTuple) end end. +skip_field(FType, IProto, SDict, RTuple) -> + FTypeAtom = thrift_protocol:typeid_to_atom(FType), + thrift_protocol:skip(IProto, FTypeAtom), + read(IProto, field_end), + read_struct_loop(IProto, SDict, RTuple). + skip(Proto, struct) -> ok = read(Proto, struct_begin), diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift index 3faaa6ab..f3f892fe 100644 --- a/test/ThriftTest.thrift +++ b/test/ThriftTest.thrift @@ -42,6 +42,15 @@ struct Xtruct2 3: i32 i32_thing } +struct Xtruct3 +{ + 1: string string_thing, + 4: i32 changed, + 9: i32 i32_thing, + 11: i64 i64_thing +} + + struct Insanity { 1: map userMap, diff --git a/test/erl/src/test_membuffer.erl b/test/erl/src/test_membuffer.erl index dd900c61..fdcdc827 100644 --- a/test/erl/src/test_membuffer.erl +++ b/test/erl/src/test_membuffer.erl @@ -23,6 +23,24 @@ t1() -> Result = TestData. +t2() -> + {ok, Transport} = thrift_memory_buffer:new(), + {ok, Protocol} = thrift_binary_protocol:new(Transport), + TestData = test_data(), + ok = thrift_protocol:write(Protocol, + {{struct, element(2, thriftTest_types:struct_info('xtruct'))}, + TestData}), + {ok, Result} = thrift_protocol:read(Protocol, + {struct, element(2, thriftTest_types:struct_info('xtruct3'))}, + 'xtruct3'), + + Result = #xtruct3{string_thing = TestData#xtruct.string_thing, + changed = undefined, + i32_thing = TestData#xtruct.i32_thing, + i64_thing = TestData#xtruct.i64_thing}. + + t() -> - t1(). + t1(), + t2().