aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-02-19 11:41:33 +0100
committerJohn Högberg <[email protected]>2019-02-20 18:40:24 +0100
commit23e645af120fe4f7f95860722cdd3867423905ed (patch)
tree64afb3f737ffe120187e88e2007eb73edc1c2183 /lib
parenta7dbb9cea6ade38a171f437489c35537a84789cf (diff)
downloadotp-23e645af120fe4f7f95860722cdd3867423905ed.tar.gz
otp-23e645af120fe4f7f95860722cdd3867423905ed.tar.bz2
otp-23e645af120fe4f7f95860722cdd3867423905ed.zip
beam_validator: Assert that no tuple elements are out of bounds
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_validator.erl21
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 42ffb04b98..2d75f80c5b 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1754,10 +1754,14 @@ meet(T1, T2) ->
{_, _, none} ->
none;
{[Sz1],[Sz2],_} ->
- {tuple,[erlang:max(Sz1, Sz2)],Es};
+ Sz = erlang:max(Sz1, Sz2),
+ assert_tuple_elements(Sz, Es),
+ {tuple,[Sz],Es};
{Sz1,[Sz2],_} when Sz2 =< Sz1 ->
+ assert_tuple_elements(Sz1, Es),
{tuple,Sz1,Es};
{Sz,Sz,_} ->
+ assert_tuple_elements(Sz, Es),
{tuple,Sz,Es};
{_,_,_} ->
none
@@ -1791,6 +1795,12 @@ meet_elements_1([Key | Keys], Es1, Es2, Acc) ->
meet_elements_1([], _Es1, _Es2, Acc) ->
Acc.
+%% No tuple elements may have an index above the known size.
+assert_tuple_elements(Limit, Es) ->
+ true = maps:fold(fun(Index, _T, true) ->
+ Index =< Limit
+ end, true, Es). %Assertion.
+
%% subtract(Type1, Type2) -> Type
%% Subtract Type2 from Type2. Example:
%% subtract(list, nil) -> cons
@@ -2067,9 +2077,9 @@ join({tuple,Size,EsA}, {tuple,Size,EsB}) ->
Es = join_tuple_elements(tuple_sz(Size), EsA, EsB),
{tuple, Size, Es};
join({tuple,A,EsA}, {tuple,B,EsB}) ->
- Size = [min(tuple_sz(A), tuple_sz(B))],
+ Size = min(tuple_sz(A), tuple_sz(B)),
Es = join_tuple_elements(Size, EsA, EsB),
- {tuple, Size, Es};
+ {tuple, [Size], Es};
join({Type,A}, {Type,B})
when Type =:= atom; Type =:= integer; Type =:= float ->
if A =:= B -> {Type,A};
@@ -2099,10 +2109,9 @@ join(T1, T2) when T1 =/= T2 ->
%% a 'term'.
join_list(T1, T2).
-join_tuple_elements(Size, EsA, EsB) ->
+join_tuple_elements(Limit, EsA, EsB) ->
Es0 = join_elements(EsA, EsB),
- MinSize = tuple_sz(Size),
- maps:filter(fun(Index, _Type) -> Index =< MinSize end, Es0).
+ maps:filter(fun(Index, _Type) -> Index =< Limit end, Es0).
join_elements(Es1, Es2) ->
Keys = if