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 a514d8f..e6045e2 100644
--- a/lib/erl/src/thrift_protocol.erl
+++ b/lib/erl/src/thrift_protocol.erl
@@ -140,19 +140,30 @@
_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 3faaa6a..f3f892f 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -42,6 +42,15 @@
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<Numberz, UserId> userMap,
diff --git a/test/erl/src/test_membuffer.erl b/test/erl/src/test_membuffer.erl
index dd900c6..fdcdc82 100644
--- a/test/erl/src/test_membuffer.erl
+++ b/test/erl/src/test_membuffer.erl
@@ -23,6 +23,24 @@
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().