Skip to content

Commit ef8f5b4

Browse files
authored
Don't encode a struct as another struct (#371)
1 parent 1636b66 commit ef8f5b4

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

lib/protobuf/encoder.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,16 @@ defmodule Protobuf.Encoder do
143143

144144
defp encode_from_type(mod, msg) do
145145
case msg do
146-
%{__struct__: ^mod} -> encode_to_iodata(msg)
147-
%_{} -> encode_to_iodata(struct(mod, Map.from_struct(msg)))
148-
_ -> encode_to_iodata(struct(mod, msg))
146+
%{__struct__: ^mod} ->
147+
encode_to_iodata(msg)
148+
149+
%other_mod{} = struct ->
150+
raise Protobuf.EncodeError,
151+
message:
152+
"struct #{inspect(other_mod)} can't be encoded as #{inspect(mod)}: #{inspect(struct)}"
153+
154+
_ ->
155+
encode_to_iodata(struct(mod, msg))
149156
end
150157
end
151158

test/protobuf/encoder_test.exs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,26 @@ defmodule Protobuf.EncoderTest do
264264
end
265265
end
266266

267+
test "raises for invalid types" do
268+
message = ~r/123 is invalid for type :string/
269+
270+
assert_raise Protobuf.EncodeError, message, fn ->
271+
Encoder.encode(%TestMsg.Foo{c: 123})
272+
end
273+
274+
message = ~r/protocol Enumerable not implemented for 123/
275+
276+
assert_raise Protobuf.EncodeError, message, fn ->
277+
Encoder.encode(%TestMsg.Foo{e: 123})
278+
end
279+
280+
message = ~r/struct TestMsg.Foo.Baz can't be encoded as TestMsg.Foo.Bar/
281+
282+
assert_raise Protobuf.EncodeError, message, fn ->
283+
Encoder.encode(%TestMsg.Foo{e: %TestMsg.Foo.Baz{a: 123}})
284+
end
285+
end
286+
267287
test "encodes with transformer module" do
268288
msg = %TestMsg.ContainsTransformModule{field: 0}
269289
assert Encoder.encode(msg) == <<10, 0>>

test/protobuf/message_merge_test.exs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ defmodule Protobuf.MessageMergeTest do
4949
test "oneof fields with the same tag are merged"
5050

5151
test "the latest oneof field takes precedence if the two have different tags" do
52-
msg1 = %TestAllTypesProto3{oneof_field: {:oneof_nested_message, %TestAllTypesProto3{}}}
52+
msg1 = %TestAllTypesProto3{
53+
oneof_field: {:oneof_nested_message, %TestAllTypesProto3.NestedMessage{}}
54+
}
55+
5356
msg2 = %TestAllTypesProto3{oneof_field: {:oneof_string, "foo"}}
5457

5558
decoded = concat_and_decode([msg1, msg2])

test/support/test_msg.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ defmodule TestMsg do
1414
field :b, 2, type: :string
1515
end
1616

17+
defmodule Foo.Baz do
18+
@moduledoc false
19+
use Protobuf, syntax: :proto3
20+
21+
field :a, 1, type: :int32
22+
field :b, 2, type: :string
23+
field :c, 3, type: :string
24+
end
25+
1726
defmodule EnumFoo do
1827
@moduledoc false
1928
use Protobuf, enum: true, syntax: :proto3

0 commit comments

Comments
 (0)