File 0343-cerl-Fix-crash-on-undefined-segment-size.patch of Package erlang

From ec44a576c8e00810bfb4129fab0b7c5fb9feb065 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Mon, 5 Jun 2023 13:35:34 +0200
Subject: [PATCH] cerl: Fix crash on 'undefined' segment size

Fixes #7325
---
 lib/compiler/src/cerl.erl                     | 29 ++++++++++---------
 .../test/small_SUITE_data/results/bs_segments |  2 ++
 .../test/small_SUITE_data/src/bs_segments.erl |  6 +++-
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index f824703a8a..7e4e5af98c 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -2385,21 +2385,22 @@ bitstr_size(Node) ->
 -spec bitstr_bitsize(c_bitstr()) -> 'all' | 'any' | 'utf' | non_neg_integer().
 
 bitstr_bitsize(Node) ->
-    Size = Node#c_bitstr.size,
+    #c_bitstr{size=Size,type=Type,unit=Unit} = Node,
     case is_literal(Size) of
-	true ->
-	    case concrete(Size) of
-		all ->
-		    all;
-		undefined ->
-		     %% just an assertion below
-		    "utf" ++ _ = atom_to_list(concrete(Node#c_bitstr.type)),
-		    utf;
-		S when is_integer(S) ->
-		    S * concrete(Node#c_bitstr.unit)
-	    end;
-	false ->
-	    any
+        true ->
+            case {concrete(Size), concrete(Type)} of
+                {all, binary} ->
+                    all;
+                {undefined, T} when T =:= utf8; T =:= utf16; T =:= utf32 ->
+                    utf;
+                {S, _} when is_integer(S), S >= 0 ->
+                    S * concrete(Unit);
+                {_, _} ->
+                    %% Bogus literal size, fails in runtime.
+                    any
+            end;
+        false ->
+            any
     end.
 
 
diff --git a/lib/dialyzer/test/small_SUITE_data/results/bs_segments b/lib/dialyzer/test/small_SUITE_data/results/bs_segments
index 0c3c9a0717..83436d91b6 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/bs_segments
+++ b/lib/dialyzer/test/small_SUITE_data/results/bs_segments
@@ -1,3 +1,5 @@
 
+bs_segments.erl:10:1: Function f/0 has no local return
+bs_segments.erl:11:10: Binary construction will fail since the size field 'undefined' in segment 0 has type 'undefined'
 bs_segments.erl:6:1: Function t/1 has no local return
 bs_segments.erl:6:1: The pattern <<_>> can never match the type any()
diff --git a/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl b/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl
index b1b8a2e866..95d9d1263b 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl
@@ -1,7 +1,11 @@
 -module(bs_segments).
 
--export([t/1]).
+-export([t/1, f/0]).
 
 %% GH-7138: bogus segment sizes crashed the analysis.
 t(<<_:undefined>>) ->
     ok.
+
+%% GH-7325: variant of the above.
+f() ->
+    <<0:(undefined)>>.
-- 
2.35.3

openSUSE Build Service is sponsored by