File 0629-Eliminate-compiler-crash-in-binary-construction.patch of Package erlang
From 0e2be1da7bea6a49333e8942475c6a0a9ba07307 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 19 Jan 2023 07:12:51 +0100
Subject: [PATCH] Eliminate compiler crash in binary construction
Constructing a binary with an explicit `all` size would crash
the compiler.
Closes #6707
---
lib/compiler/src/v3_core.erl | 22 ++++++++++++++--------
lib/compiler/test/bs_construct_SUITE.erl | 4 ++++
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 974d3413b1..734ea0b770 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1408,28 +1408,34 @@ bitstr({bin_element,{sl,Seg,Line},E0,Size0,[Type,{unit,Unit}|Flags]}, St0) ->
Eps,St2}.
bin_element({bin_element,Line,Expr,Size0,Type0}) ->
- {Size,Type} = make_bit_type(Line, Size0, Type0),
+ {Size,Type} = make_bit_type(Line, Size0, Type0, construction),
{bin_element,Line,Expr,Size,Type}.
-make_bit_type(Line, default, Type0) ->
+make_bit_type(Line, default, Type0, _Context) ->
case erl_bits:set_bit_type(default, Type0) of
{ok,all,Bt} -> {make_all_size(Line),erl_bits:as_list(Bt)};
{ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)};
{ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}
end;
-make_bit_type(_Line, {atom,Anno,all}=Size, Type0) ->
+make_bit_type(_Line, {atom,Anno,all}=Size, Type0, Context) ->
+ {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
+ Type = erl_bits:as_list(Bt),
case erl_anno:generated(Anno) of
true ->
%% This `all` was created by the compiler from a binary
%% segment without a size.
- {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
- {Size,erl_bits:as_list(Bt)};
+ {Size,Type};
false ->
%% This `all` was present in the source code. It is not
%% a valid size.
- throw(nomatch)
+ case Context of
+ matching ->
+ throw(nomatch);
+ construction ->
+ {{atom,Anno,bad_size},Type}
+ end
end;
-make_bit_type(_Line, Size0, Type0) -> %Integer or 'all'
+make_bit_type(_Line, Size0, Type0, _Context) ->
{ok,Size1,Bt} = erl_bits:set_bit_type(Size0, Type0),
Size = case Size1 of
{char,Anno,CharVal} -> {integer,Anno,CharVal};
@@ -2118,7 +2124,7 @@ pat_segments([P0|Ps0], St0) ->
pat_segments([], St) -> {[],St}.
pat_segment({bin_element,L,Val,Size0,Type0}, St) ->
- {Size1,Type1} = make_bit_type(L, Size0, Type0),
+ {Size1,Type1} = make_bit_type(L, Size0, Type0, matching),
[Type,{unit,Unit}|Flags] = Type1,
Anno = lineno_anno(L, St),
{Pval0,St1} = pattern(Val, St),
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index 201b411656..b6a8b6e295 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -708,6 +708,7 @@ bad_size(_Config) ->
{'EXIT',{badarg,_}} = (catch bad_binary_size()),
{'EXIT',{badarg,_}} = (catch bad_binary_size(<<"xyz">>)),
{'EXIT',{badarg,_}} = (catch bad_binary_size2()),
+ {'EXIT',{badarg,_}} = (catch bad_binary_size3(id(<<"abc">>))),
ok.
bad_float_size() ->
@@ -737,3 +738,6 @@ bad_binary_size2() ->
<<
<<(id(42))>>:[ <<>> || <<123:true>> <= <<>> ]/binary,
<<(id(100))>>:7>>.
+
+bad_binary_size3(Bin) ->
+ <<Bin:all/binary>>.
--
2.35.3