Skip to content

Commit 2e5d6ca

Browse files
authored
Raise when encoding/decoding invalid UTF-8 (#346)
1 parent 9801e93 commit 2e5d6ca

File tree

5 files changed

+41
-3
lines changed

5 files changed

+41
-3
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ jobs:
129129
130130
conformance-test:
131131
name: Conformance test (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})
132-
runs-on: ubuntu-18.04
132+
runs-on: ubuntu-22.04
133133
strategy:
134134
fail-fast: false
135135
matrix:

lib/protobuf/wire.ex

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,16 @@ defmodule Protobuf.Wire do
7171
@spec encode(proto_type(), proto_value()) :: iodata()
7272
def encode(type, value)
7373

74-
def encode(type, binary) when is_binary(binary) and type in [:string, :bytes],
74+
def encode(:string, binary) when is_binary(binary) do
75+
unless String.valid?(binary) do
76+
raise Protobuf.EncodeError,
77+
message: "invalid UTF-8 data for type string: #{inspect(binary)}"
78+
end
79+
80+
encode_from_wire_type(wire_delimited(), binary)
81+
end
82+
83+
def encode(:bytes, binary) when is_binary(binary),
7584
do: encode_from_wire_type(wire_delimited(), binary)
7685

7786
def encode(:int32, n) when n in @sint32_range, do: encode_from_wire_type(wire_varint(), n)
@@ -133,7 +142,16 @@ defmodule Protobuf.Wire do
133142
@spec decode(proto_type(), binary() | integer()) :: proto_value()
134143
def decode(type, value)
135144

136-
def decode(type, val) when type in [:string, :bytes], do: val
145+
def decode(:string, binary) when is_binary(binary) do
146+
unless String.valid?(binary) do
147+
raise Protobuf.DecodeError,
148+
message: "invalid UTF-8 data for type string: #{inspect(binary)}"
149+
end
150+
151+
binary
152+
end
153+
154+
def decode(:bytes, binary) when is_binary(binary), do: binary
137155

138156
def decode(:int32, val) do
139157
<<n::signed-integer-32>> = <<val::32>>

test/protobuf/decoder_test.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ defmodule Protobuf.DecoderTest do
198198
%TestMsg.Oneof{first: {:b, ""}, second: {:c, 0}}
199199
end
200200

201+
test "raises on invalid UTF-8" do
202+
assert_raise Protobuf.DecodeError, "invalid UTF-8 data for type string: <<255>>", fn ->
203+
Decoder.decode(<<10, 1, 255>>, TestMsg.Scalars)
204+
end
205+
end
206+
201207
test "decodes with transformer module" do
202208
assert TestMsg.WithTransformModule.decode(<<8, 42>>) == 42
203209

test/protobuf/encoder_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ defmodule Protobuf.EncoderTest do
254254
255, 1, 202, 62, 3, 102, 111, 111>>
255255
end
256256

257+
test "raises on invalid UTF-8" do
258+
message =
259+
"Got error when encoding TestMsg.Scalars#string: " <>
260+
"** (Protobuf.EncodeError) invalid UTF-8 data for type string: <<255>>"
261+
262+
assert_raise Protobuf.EncodeError, message, fn ->
263+
Encoder.encode(%TestMsg.Scalars{string: <<255>>})
264+
end
265+
end
266+
257267
test "encodes with transformer module" do
258268
msg = %TestMsg.ContainsTransformModule{field: 0}
259269
assert Encoder.encode(msg) == <<10, 0>>

test/protobuf/wire_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ defmodule Protobuf.WireTest do
9999

100100
test "string" do
101101
assert encode(:string, "testing") == <<7, 116, 101, 115, 116, 105, 110, 103>>
102+
103+
assert_raise Protobuf.EncodeError, fn -> encode(:string, <<255>>) end
102104
end
103105

104106
test "bytes" do
@@ -340,6 +342,8 @@ defmodule Protobuf.WireTest do
340342

341343
test "string" do
342344
assert "testing" == Wire.decode(:string, <<116, 101, 115, 116, 105, 110, 103>>)
345+
346+
assert_raise Protobuf.DecodeError, fn -> Wire.decode(:string, <<255>>) end
343347
end
344348

345349
test "bytes" do

0 commit comments

Comments
 (0)