Skip to content

Commit 84f00af

Browse files
authored
Conformance: accept nulls for repeated and maps in JSON decoder (#393)
* Conformance: accept nulls for repeated and maps in JSON decoder * Use adequate protobuf type in test * Remove irrelevant field from test
1 parent 914422d commit 84f00af

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

lib/protobuf/json/decode.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ defmodule Protobuf.JSON.Decode do
278278
end
279279
end
280280

281+
defp decode_map(_prop, nil), do: nil
282+
281283
defp decode_map(prop, bad_map), do: throw({:bad_map, prop.name_atom, bad_map})
282284

283285
defp decode_key(type, key, field) when is_binary(key) do
@@ -301,6 +303,8 @@ defmodule Protobuf.JSON.Decode do
301303
for val <- value, do: decode_singular(prop, val)
302304
end
303305

306+
defp decode_repeated(_prop, nil), do: nil
307+
304308
defp decode_repeated(prop, value) do
305309
throw({:bad_repeated, prop.name_atom, value})
306310
end

test/protobuf/conformance_regressions_test.exs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,33 @@ defmodule Protobuf.ConformanceRegressionsTest do
5757
end
5858
end
5959

60+
test "Required.Proto2.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput" do
61+
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
62+
problematic_payload = <<194, 3, 0>>
63+
assert %{map_int32_int32: %{0 => 0}} = mod.decode(problematic_payload)
64+
end
65+
66+
test "Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.JsonOutput" do
67+
mod = ProtobufTestMessages.Proto3.TestAllTypesProto3
68+
problematic_payload = ~S({"optionalInt32": "1e5"})
69+
assert %{optional_int32: 100_000} = Protobuf.JSON.decode!(problematic_payload, mod)
70+
end
71+
72+
test "Required.Proto2.JsonInput.AllFieldAcceptNull.ProtobufOutput" do
73+
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
74+
problematic_payload = ~S({
75+
"map_bool_bool": null,
76+
"repeated_int32": null
77+
})
78+
79+
assert %{
80+
map_bool_bool: map_bool_bool,
81+
repeated_int32: []
82+
} = Protobuf.JSON.decode!(problematic_payload, mod)
83+
84+
assert is_map(map_bool_bool) and map_size(map_bool_bool) == 0
85+
end
86+
6087
describe "proto2" do
6188
setup :url_to_message
6289
setup :decode_conformance_input
@@ -83,18 +110,6 @@ defmodule Protobuf.ConformanceRegressionsTest do
83110

84111
@describetag message_type: "protobuf_test_messages.proto3.TestAllTypesProto3"
85112

86-
test "Required.Proto2.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput" do
87-
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
88-
problematic_payload = <<194, 3, 0>>
89-
assert %{map_int32_int32: %{0 => 0}} = mod.decode(problematic_payload)
90-
end
91-
92-
test "Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.JsonOutput" do
93-
mod = ProtobufTestMessages.Proto3.TestAllTypesProto3
94-
problematic_payload = ~S({"optionalInt32": "1e5"})
95-
assert %{optional_int32: 100_000} = Protobuf.JSON.decode!(problematic_payload, mod)
96-
end
97-
98113
test "Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator",
99114
%{message_mod: message_mod} do
100115
json = "{\"oneofNullValue\": null}"

0 commit comments

Comments
 (0)