Skip to content

Commit 588e0c8

Browse files
committed
Raise a nice error for bad wire types
Closes #339.
1 parent f550f27 commit 588e0c8

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

lib/protobuf/decoder.ex

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,10 @@ defmodule Protobuf.Decoder do
109109
skip_delimited(rest, message, props, groups)
110110

111111
wire_32bits() ->
112-
<<_skip::bits-32, rest::bits>> = rest
113-
skip_field(rest, message, props, groups)
112+
rest |> skip_bits(32) |> skip_field(message, props, groups)
114113

115114
wire_64bits() ->
116-
<<_skip::bits-64, rest::bits>> = rest
117-
skip_field(rest, message, props, groups)
115+
rest |> skip_bits(64) |> skip_field(message, props, groups)
118116

119117
wire_type ->
120118
message =
@@ -140,6 +138,13 @@ defmodule Protobuf.Decoder do
140138
skip_field(rest, message, props, groups)
141139
end
142140

141+
defp skip_bits(binary, length) do
142+
case binary do
143+
<<_::bits-size(length), rest::bits>> -> rest
144+
_ -> raise DecodeError, message: "insufficient data for skipping #{length} bits"
145+
end
146+
end
147+
143148
defdecoderp decode_varint(field_number, message, props) do
144149
handle_value(rest, field_number, wire_varint(), value, message, props)
145150
end

test/protobuf/decoder_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ defmodule Protobuf.DecoderTest do
221221
end
222222
end
223223

224+
# Regression for #339
225+
test "raises a nice error in some cases" do
226+
assert_raise Protobuf.DecodeError, "insufficient data for skipping 32 bits", fn ->
227+
Decoder.decode("{}", TestMsg.Oneof)
228+
end
229+
end
230+
224231
describe "groups" do
225232
test "skips all groups and their fields" do
226233
a = <<8, 42>>

test/protobuf/protoc/cli_integration_test.exs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,23 @@ defmodule Protobuf.Protoc.CLIIntegrationTest do
102102
assert [{Foo.User, docs}] = modules_and_docs
103103
assert {:docs_v1, _, :elixir, _, :hidden, _, _} = docs
104104
end
105+
106+
defp get_docs_and_clean_modules_on_exit(path) do
107+
modules_and_docs =
108+
path
109+
|> Code.compile_file()
110+
|> Enum.map(fn {mod, bytecode} ->
111+
{mod, fetch_docs_from_bytecode(bytecode)}
112+
end)
113+
114+
on_exit(fn ->
115+
modules_and_docs
116+
|> Enum.map(fn {mod, _bytecode} -> mod end)
117+
|> TestHelpers.purge_modules()
118+
end)
119+
120+
modules_and_docs
121+
end
105122
end
106123

107124
test "package_prefix mypkg", %{tmp_dir: tmp_dir, proto_path: proto_path} do
@@ -323,21 +340,4 @@ defmodule Protobuf.Protoc.CLIIntegrationTest do
323340

324341
modules
325342
end
326-
327-
defp get_docs_and_clean_modules_on_exit(path) do
328-
modules_and_docs =
329-
path
330-
|> Code.compile_file()
331-
|> Enum.map(fn {mod, bytecode} ->
332-
{mod, fetch_docs_from_bytecode(bytecode)}
333-
end)
334-
335-
on_exit(fn ->
336-
modules_and_docs
337-
|> Enum.map(fn {mod, _bytecode} -> mod end)
338-
|> TestHelpers.purge_modules()
339-
end)
340-
341-
modules_and_docs
342-
end
343343
end

0 commit comments

Comments
 (0)