Skip to content

Commit f702f93

Browse files
fertapricjosevalim
authored andcommitted
Raise compile errors on bad binary types
Both size and unit must be non-negative integers. These checks were previously performed by erl_lint.
1 parent b3f59d9 commit f702f93

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

lib/elixir/lib/kernel/typespec.ex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,13 @@ defmodule Kernel.Typespec do
449449
_,
450450
state
451451
)
452-
when is_atom(ctx1) and is_atom(ctx2) and is_integer(unit) do
452+
when is_atom(ctx1) and is_atom(ctx2) and is_integer(unit) and unit >= 0 do
453453
line = line(meta)
454454
{{:type, line, :binary, [{:integer, line, 0}, {:integer, line(unit_meta), unit}]}, state}
455455
end
456456

457457
defp typespec({:<<>>, meta, [{:::, size_meta, [{:_, _, ctx}, size]}]}, _, _, state)
458-
when is_atom(ctx) and is_integer(size) do
458+
when is_atom(ctx) and is_integer(size) and size >= 0 do
459459
line = line(meta)
460460
{{:type, line, :binary, [{:integer, line(size_meta), size}, {:integer, line, 0}]}, state}
461461
end
@@ -474,11 +474,19 @@ defmodule Kernel.Typespec do
474474
state
475475
)
476476
when is_atom(ctx1) and is_atom(ctx2) and is_atom(ctx3) and is_integer(size) and
477-
is_integer(unit) do
477+
is_integer(unit) and size >= 0 and unit >= 0 do
478478
args = [{:integer, line(size_meta), size}, {:integer, line(unit_meta), unit}]
479479
{{:type, line(meta), :binary, args}, state}
480480
end
481481

482+
defp typespec({:<<>>, _meta, _args}, _vars, caller, _state) do
483+
message =
484+
"invalid binary specification, expected <<_::size>>, <<_::_*unit>>, " <>
485+
"or <<_::size, _::_*unit>> with size and unit being non-negative integers"
486+
487+
compile_error(caller, message)
488+
end
489+
482490
## Handle maps and structs
483491
defp typespec({:map, meta, args}, _vars, _caller, state) when args == [] or is_atom(args) do
484492
{{:type, line(meta), :map, :any}, state}

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,35 @@ defmodule TypespecTest do
367367
end
368368

369369
test "@type with invalid binary spec" do
370-
assert_raise CompileError, fn ->
370+
assert_raise CompileError, ~r"invalid binary specification", fn ->
371371
test_module do
372372
@type my_type :: <<_::3*8>>
373373
end
374374
end
375+
376+
assert_raise CompileError, ~r"invalid binary specification", fn ->
377+
test_module do
378+
@type my_type :: <<_::atom>>
379+
end
380+
end
381+
382+
assert_raise CompileError, ~r"invalid binary specification", fn ->
383+
test_module do
384+
@type my_type :: <<_::(-4)>>
385+
end
386+
end
387+
388+
assert_raise CompileError, ~r"invalid binary specification", fn ->
389+
test_module do
390+
@type my_type :: <<_::3, _::_*atom>>
391+
end
392+
end
393+
394+
assert_raise CompileError, ~r"invalid binary specification", fn ->
395+
test_module do
396+
@type my_type :: <<_::3, _::_*(-8)>>
397+
end
398+
end
375399
end
376400

377401
test "@type with a range op" do

0 commit comments

Comments
 (0)