From 23e645af120fe4f7f95860722cdd3867423905ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 19 Feb 2019 11:41:33 +0100 Subject: beam_validator: Assert that no tuple elements are out of bounds --- lib/compiler/src/beam_validator.erl | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'lib') 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 -- cgit v1.2.3