Skip to content

Commit

Permalink
Conformance: accept nulls for repeated and maps in JSON decoder (#393)
Browse files Browse the repository at this point in the history
* Conformance: accept nulls for repeated and maps in JSON decoder

* Use adequate protobuf type in test

* Remove irrelevant field from test
  • Loading branch information
v0idpwn authored Jan 5, 2025
1 parent 914422d commit 84f00af
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
4 changes: 4 additions & 0 deletions lib/protobuf/json/decode.ex
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ defmodule Protobuf.JSON.Decode do
end
end

defp decode_map(_prop, nil), do: nil

defp decode_map(prop, bad_map), do: throw({:bad_map, prop.name_atom, bad_map})

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

defp decode_repeated(_prop, nil), do: nil

defp decode_repeated(prop, value) do
throw({:bad_repeated, prop.name_atom, value})
end
Expand Down
39 changes: 27 additions & 12 deletions test/protobuf/conformance_regressions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,33 @@ defmodule Protobuf.ConformanceRegressionsTest do
end
end

test "Required.Proto2.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput" do
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
problematic_payload = <<194, 3, 0>>
assert %{map_int32_int32: %{0 => 0}} = mod.decode(problematic_payload)
end

test "Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.JsonOutput" do
mod = ProtobufTestMessages.Proto3.TestAllTypesProto3
problematic_payload = ~S({"optionalInt32": "1e5"})
assert %{optional_int32: 100_000} = Protobuf.JSON.decode!(problematic_payload, mod)
end

test "Required.Proto2.JsonInput.AllFieldAcceptNull.ProtobufOutput" do
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
problematic_payload = ~S({
"map_bool_bool": null,
"repeated_int32": null
})

assert %{
map_bool_bool: map_bool_bool,
repeated_int32: []
} = Protobuf.JSON.decode!(problematic_payload, mod)

assert is_map(map_bool_bool) and map_size(map_bool_bool) == 0
end

describe "proto2" do
setup :url_to_message
setup :decode_conformance_input
Expand All @@ -83,18 +110,6 @@ defmodule Protobuf.ConformanceRegressionsTest do

@describetag message_type: "protobuf_test_messages.proto3.TestAllTypesProto3"

test "Required.Proto2.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput" do
mod = ProtobufTestMessages.Proto2.TestAllTypesProto2
problematic_payload = <<194, 3, 0>>
assert %{map_int32_int32: %{0 => 0}} = mod.decode(problematic_payload)
end

test "Required.Proto3.JsonInput.Int32FieldQuotedExponentialValue.JsonOutput" do
mod = ProtobufTestMessages.Proto3.TestAllTypesProto3
problematic_payload = ~S({"optionalInt32": "1e5"})
assert %{optional_int32: 100_000} = Protobuf.JSON.decode!(problematic_payload, mod)
end

test "Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator",
%{message_mod: message_mod} do
json = "{\"oneofNullValue\": null}"
Expand Down

0 comments on commit 84f00af

Please sign in to comment.