summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/notes.xml29
-rw-r--r--erts/emulator/beam/erl_node_tables.c2
-rw-r--r--erts/etc/common/erlc.c4
-rw-r--r--erts/vsn.mk2
-rw-r--r--lib/common_test/doc/src/ct_suite.xml8
-rw-r--r--lib/common_test/doc/src/run_test_chapter.xml2
-rw-r--r--lib/common_test/doc/src/write_test_chapter.xml6
-rw-r--r--lib/common_test/src/ct_suite.erl4
-rw-r--r--lib/compiler/doc/src/notes.xml15
-rw-r--r--lib/compiler/src/beam_ssa_check.erl5
-rw-r--r--lib/compiler/src/beam_ssa_private_append.erl21
-rw-r--r--lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl27
-rw-r--r--lib/compiler/test/beam_ssa_check_SUITE_data/sanity_checks.erl16
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/os_mon/doc/src/notes.xml17
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/ssl/doc/src/ssl.xml64
-rw-r--r--lib/ssl/src/ssl.erl45
-rw-r--r--lib/ssl/src/tls_client_connection_1_3.erl10
-rw-r--r--lib/ssl/src/tls_v1.erl18
-rw-r--r--lib/ssl/test/ssl_reject_SUITE.erl5
-rw-r--r--lib/ssl/test/tls_api_SUITE.erl22
-rw-r--r--lib/wx/c_src/Makefile.in6
-rwxr-xr-xotp_build10
-rw-r--r--otp_versions.table1
-rwxr-xr-xscripts/otp_build_check344
-rw-r--r--system/doc/general_info/upcoming_incompatibilities.xml60
27 files changed, 704 insertions, 43 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index d31a438ede..1f372823e8 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,35 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 13.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If a runtime system which was starting the distribution
+ already had existing pids, ports, or references referring
+ to a node with the same nodename/creation pair that the
+ runtime system was about to use, these already existing
+ pids, ports, or references would not work as expected in
+ various situations after the node had gone alive. This
+ could only occur if the runtime system was communicated
+ such pids, ports, or references prior to the distribution
+ was started. That is, it was extremely unlikely to happen
+ unless the distribution was started dynamically and was
+ even then very unlikely to happen. The runtime system now
+ checks for already existing pids, ports, and references
+ with the same nodename/creation pair that it is about to
+ use. If such are found another creation will be chosen in
+ order to avoid these issues.</p>
+ <p>
+ Own Id: OTP-18570 Aux Id: PR-7190 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 13.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index c2d9b0967d..dac24d0310 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2022. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2023. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index 3683a47064..1493c6f6ff 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -748,8 +748,10 @@ call_compile_server(char** argv)
ei_x_encode_atom(&args, "command_line");
argc = 0;
while (argv[argc]) {
+ char *arg;
ei_x_encode_list_header(&args, 1);
- ei_x_encode_binary(&args, possibly_unquote(argv[argc]), strlen(argv[argc]));
+ arg = possibly_unquote(argv[argc]);
+ ei_x_encode_binary(&args, arg, strlen(arg));
argc++;
}
ei_x_encode_empty_list(&args); /* End of command_line */
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 44cd2f0475..67df301d2e 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 13.2.1
+VSN = 13.2.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/common_test/doc/src/ct_suite.xml b/lib/common_test/doc/src/ct_suite.xml
index 8740a3ff79..cc926fbcbb 100644
--- a/lib/common_test/doc/src/ct_suite.xml
+++ b/lib/common_test/doc/src/ct_suite.xml
@@ -85,7 +85,9 @@
<fsummary>Returns the list of all test case groups and test cases
in the module.</fsummary>
<type>
- <v><seetype marker="#ct_test_def">ct_test_def()</seetype> = TestCase | {group, GroupName} | {group, GroupName, Properties} | {group, GroupName, Properties, SubGroups}</v>
+ <v><seetype marker="#ct_test_def">ct_test_def()</seetype> = TestCase |
+ {group, GroupName} | {group, GroupName, Properties} | {group, GroupName,
+ Properties, SubGroups} | {testcase, TestCase, TestCaseRepeatType}</v>
<v>TestCase = <seetype marker="#ct_testname">ct_testname()</seetype></v>
<v>GroupName = <seetype marker="#ct_groupname">ct_groupname()</seetype></v>
<v>Properties = [parallel | sequence | Shuffle | {RepeatType, N}] | default</v>
@@ -93,6 +95,7 @@
<v>Shuffle = shuffle | {shuffle, Seed}</v>
<v>Seed = {integer(), integer(), integer()}</v>
<v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v>
+ <v>TestCaseRepeatType = [{repeat, N} | {repeat_until_ok, N} | {repeat_until_fail, N}]</v>
<v>N = integer() | forever</v>
<v>Reason = term()</v>
</type>
@@ -135,11 +138,12 @@
<v><seetype marker="#ct_group_def">ct_group_def()</seetype> = {GroupName, Properties, GroupsAndTestCases}</v>
<v>GroupName = <seetype marker="#ct_groupname">ct_groupname()</seetype></v>
<v>Properties = [parallel | sequence | Shuffle | {RepeatType, N}]</v>
- <v>GroupsAndTestCases = [Group | {group, GroupName} | TestCase]</v>
+ <v>GroupsAndTestCases = [Group | {group, GroupName} | TestCase | {testcase, TestCase, TestCaseRepeatType}]</v>
<v>TestCase = <seetype marker="#ct_testname">ct_testname()</seetype></v>
<v>Shuffle = shuffle | {shuffle, Seed}</v>
<v>Seed = {integer(), integer(), integer()}</v>
<v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v>
+ <v>TestCaseRepeatType = [{repeat, N} | {repeat_until_ok, N} | {repeat_until_fail, N}]</v>
<v>N = integer() | forever</v>
</type>
diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml
index f9416e1bee..ea33b9d8f9 100644
--- a/lib/common_test/doc/src/run_test_chapter.xml
+++ b/lib/common_test/doc/src/run_test_chapter.xml
@@ -763,7 +763,7 @@
finally function <c>end_per_group</c>. Also, if particular
test cases in a group are specified, <c>init_per_group</c>
and <c>end_per_group</c>, for the group in question, are
- called. If a group defined (in <c>Suite:group/0</c>) as
+ called. If a group defined (in <c>Suite:groups/0</c>) as
a subgroup of another group, is specified (or if particular test
cases of a subgroup are), <c>Common Test</c> calls the configuration
functions for the top-level groups and for the subgroup
diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml
index 8f7c7e8177..99571bbdae 100644
--- a/lib/common_test/doc/src/write_test_chapter.xml
+++ b/lib/common_test/doc/src/write_test_chapter.xml
@@ -515,14 +515,14 @@
<c>{group,GroupName,Properties,SubGroups}</c>
Where, <c>SubGroups</c> is a list of tuples, <c>{GroupName,Properties}</c> or
<c>{GroupName,Properties,SubGroups}</c> representing the subgroups.
- Any subgroups defined in <c>group/0</c> for a group, that are not specified
+ Any subgroups defined in <c>groups/0</c> for a group, that are not specified
in the <c>SubGroups</c> list, executes with their predefined
properties.</p>
<p><em>Example:</em></p>
<pre>
- groups() -> {tests1, [], [{tests2, [], [t2a,t2b]},
- {tests3, [], [t31,t3b]}]}.</pre>
+ groups() -> [{tests1, [], [{tests2, [], [t2a,t2b]},
+ {tests3, [], [t31,t3b]}]}].</pre>
<p>To execute group <c>tests1</c> twice with different properties for <c>tests2</c>
each time:</p>
<pre>
diff --git a/lib/common_test/src/ct_suite.erl b/lib/common_test/src/ct_suite.erl
index a2d23e15ef..860efe3ae2 100644
--- a/lib/common_test/src/ct_suite.erl
+++ b/lib/common_test/src/ct_suite.erl
@@ -47,9 +47,9 @@
{group, ct_groupname(), ct_group_props_ref()} |
{group, ct_groupname(), ct_group_props_ref(), ct_subgroups_def()}.
-type ct_testcase_ref() :: {testcase, ct_testname(), ct_testcase_repeat_prop()}.
--type ct_testcase_repeat_prop() :: {repeat, ct_test_repeat()} |
+-type ct_testcase_repeat_prop() :: [{repeat, ct_test_repeat()} |
{repeat_until_ok, ct_test_repeat()} |
- {repeat_until_fail, ct_test_repeat()}.
+ {repeat_until_fail, ct_test_repeat()}].
-type ct_info() :: {timetrap, ct_info_timetrap()} |
{require, ct_info_required()} |
{require, Name :: atom(), ct_info_required()} |
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 75396f4c0f..f92505409c 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -32,6 +32,21 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 8.2.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed type handling bugs that could cause an internal
+ error in the compiler for correct code.</p>
+ <p>
+ Own Id: OTP-18565 Aux Id: GH-7147 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 8.2.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/src/beam_ssa_check.erl b/lib/compiler/src/beam_ssa_check.erl
index 0d3faa0ee2..f344286943 100644
--- a/lib/compiler/src/beam_ssa_check.erl
+++ b/lib/compiler/src/beam_ssa_check.erl
@@ -285,8 +285,9 @@ env_post1(_Pattern, _Actual, _Env) ->
?DP("Failed to match ~p <-> ~p~n", [_Pattern, _Actual]),
error({internal_pattern_match_error,env_post1}).
-post_bitstring(Bytes, Actual, _Env) ->
- Actual = build_bitstring(Bytes, <<>>).
+post_bitstring(Bytes, Actual, Env) ->
+ Actual = build_bitstring(Bytes, <<>>),
+ Env.
%% Convert the parsed literal binary to an actual bitstring.
build_bitstring([{integer,_,V}|Bytes], Acc) ->
diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl
index bf51e8b81a..c295492762 100644
--- a/lib/compiler/src/beam_ssa_private_append.erl
+++ b/lib/compiler/src/beam_ssa_private_append.erl
@@ -86,6 +86,17 @@ find_appends_blk([], _, Found) ->
Found.
find_appends_is([#b_set{dst=Dst, op=bs_create_bin,
+ args=[#b_literal{val=append},
+ _,
+ Lit=#b_literal{val= <<>>}|_]}|Is],
+ Fun, Found0) ->
+ %% Special case for when the first fragment is a literal <<>> as
+ %% it won't be annotated as unique nor will it die with the
+ %% instruction.
+ AlreadyFound = maps:get(Fun, Found0, []),
+ Found = Found0#{Fun => [{append,Dst,Lit}|AlreadyFound]},
+ find_appends_is(Is, Fun, Found);
+find_appends_is([#b_set{dst=Dst, op=bs_create_bin,
args=[#b_literal{val=append},SegmentInfo,Var|_],
anno=#{first_fragment_dies:=Dies}=Anno}|Is],
Fun, Found0) ->
@@ -468,6 +479,16 @@ patch_appends_is([I0=#b_set{dst=Dst}|Rest], PD0, Cnt0, Acc, BlockAdditions0)
Ps = keysort(1, map(ExtractOpargs, Patches)),
{Is, Cnt} = patch_opargs(I0, Ps, Cnt0),
patch_appends_is(Rest, PD, Cnt, Is++Acc, BlockAdditions0);
+ [{append,Dst,#b_literal{val= <<>>}=Lit}] ->
+ %% Special case for when the first fragment is a literal
+ %% <<>> and it has to be replaced with a bs_init_writable.
+ #b_set{op=bs_create_bin,dst=Dst,args=Args0}=I0,
+ [#b_literal{val=append},SegInfo,Lit|OtherArgs] = Args0,
+ {V,Cnt} = new_var(Cnt0),
+ Init = #b_set{op=bs_init_writable,dst=V,args=[#b_literal{val=256}]},
+ I = I0#b_set{args=[#b_literal{val=private_append},
+ SegInfo,V|OtherArgs]},
+ patch_appends_is(Rest, PD, Cnt, [I,Init|Acc], BlockAdditions0);
[{append,Dst,_}] ->
#b_set{op=bs_create_bin,dst=Dst,args=Args0}=I0,
[#b_literal{val=append}|OtherArgs] = Args0,
diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl
index 4d4b0f1bbd..c1edc54460 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl
@@ -22,6 +22,8 @@
%%
-module(private_append).
+-feature(maybe_expr, enable).
+
-export([transformable0/1,
transformable1/1,
transformable1b/1,
@@ -76,7 +78,9 @@
not_transformable14/0,
not_transformable15/2,
- id/1]).
+ id/1,
+
+ bs_create_bin_on_literal/0]).
%% Trivial smoke test
transformable0(L) ->
@@ -977,3 +981,24 @@ not_transformable15(_, V) ->
id(I) ->
I.
+
+%% Check that we don't try to private_append to something created by
+%% bs_create_bin `append`, _, `<<>>`, ...
+bs_create_bin_on_literal() ->
+%ssa% () when post_ssa_opt ->
+%ssa% X = bs_init_writable(_),
+%ssa% Y = bs_create_bin(private_append, _, X, ...),
+%ssa% Z = bs_create_bin(private_append, _, Y, ...),
+%ssa% ret(Z).
+ <<
+ <<
+ (maybe
+ 2147483647 ?= ok
+ else
+ <<_>> ->
+ ok;
+ _ ->
+ <<>>
+ end)/bytes
+ >>/binary
+ >>.
diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/sanity_checks.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/sanity_checks.erl
index ae4bb28eea..47c60fd8d6 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE_data/sanity_checks.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE_data/sanity_checks.erl
@@ -18,6 +18,8 @@
-module(sanity_checks).
+-compile(no_ssa_opt_private_append).
+
-export([check_fail/0,
check_wrong_pass/0,
check_xfail/0,
@@ -33,7 +35,9 @@
t25/0, t26/0, t27/0, t28/0, t29/0,
t30/0, t31/0, t32/1, t33/1, t34/1,
t35/1, t36/0, t37/0, t38/0, t39/1,
- t40/0, t41/0, t42/0, t43/0, t44/0]).
+ t40/0, t41/0, t42/0, t43/0, t44/0,
+
+ check_env/0]).
%% Check that we do not trigger on the wrong pass
check_wrong_pass() ->
@@ -325,3 +329,13 @@ t44() ->
%ssa% () when post_ssa_opt ->
%ssa% _ = call(fun e:f0/1, {...}).
e:f0({}).
+
+%% Ensure bug which trashed the environment after matching a literal
+%% bitstring stays fixed.
+check_env() ->
+%ssa% () when post_ssa_opt ->
+%ssa% X = bs_create_bin(append, _, <<>>, ...),
+%ssa% ret(X).
+ A = <<>>,
+ B = ex:f(),
+ <<A/binary, B/binary>>.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 0c4eae4d45..fa46ea4097 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 8.2.5
+COMPILER_VSN = 8.2.6
diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index 1fac53d330..439c1e839a 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -31,6 +31,23 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Avoid error report from failing <c>erlang:port_close</c>
+ at shutdown of <c>cpu_sup</c> and <c>memsup</c>. Bug
+ exists since OTP 25.3 (os_mon-2.8.1).</p>
+ <p>
+ Own Id: OTP-18559 Aux Id: ERIERL-942 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.8.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index 9e64a83612..d6878e6773 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.8.1
+OS_MON_VSN = 2.8.2
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 700709ed7a..b4a30a68c8 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -477,12 +477,10 @@
{sha384, ecdsa},
{sha384, rsa},
{sha256, ecdsa},
-{sha256, rsa},
-{sha224, ecdsa},
-{sha224, rsa}
+{sha256, rsa}
]</code>
-<p>Support for {md5, rsa} was removed from the the TLS-1.2 default in ssl-8.0 (OTP-22) and support for SHA1 {sha, _} was removed in ssl-11.0 (OTP-26) </p>
+<p>Support for {md5, rsa} was removed from the the TLS-1.2 default in ssl-8.0 (OTP-22) and support for SHA1 {sha, _} and SHA224 {sha224, _} was removed in ssl-11.0 (OTP-26) </p>
<p><c> rsa_pss_schemes =</c></p>
<code>
@@ -521,10 +519,10 @@ rsa_pss_schemes()
<p>EDDSA was made highest priority in ssl-10.8 (OTP-25) </p>
<p>TLS-1.3 default is</p>
-<code>Default_TLS_13_Schemes ++ Legacy_TLS_13_Schemes </code>
+<code>Default_TLS_13_Schemes</code>
<p>If both TLS-1.3 and TLS-1.2 are supported the default will be</p>
-<code>Default_TLS_13_Schemes ++ Default_TLS_12_Alg_Pairs </code>
+<code>Default_TLS_13_Schemes ++ TLS_13_Legacy_Schemes ++ Default_TLS_12_Alg_Pairs (not represented in TLS_13_Legacy_Schemes) </code>
<p>so appropriate algorithms can be chosen for the negotiated
version.
@@ -2175,6 +2173,60 @@ fun(srp, Username :: binary(), UserState :: term()) ->
is useful.</p>
</desc>
</func>
+
+ <func>
+ <name since="OTP @OTP-18572@" name="signature_algs" arity="2" />
+ <fsummary>Returns a list of signature algorithms/schemes </fsummary>
+ <desc>
+ <p>Lists all possible signature algorithms corresponding to
+ <c>Description</c> that are available. The
+ <c>exclusive</c> option will exclusively list
+ algorithms/schemes for that protocol version, whereas the
+ <c>default</c> and <c>all</c> options lists the combined list to support the
+ range of protocols from (D)TLS-1.2, the first version to support
+ configuration of the signature algorithms, to <c>Version</c>.</p>
+
+ <p> Example: <c>
+
+ 1&gt; ssl:signature_algs(default, 'tlsv1.3').
+ [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
+ ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
+ rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
+ rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
+ rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
+ {sha512,ecdsa},
+ {sha384,ecdsa},
+ {sha256,ecdsa}]
+
+ 2&gt;ssl:signature_algs(all, 'tlsv1.3').
+ [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
+ ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
+ rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
+ rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
+ rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
+ {sha512,ecdsa},
+ {sha384,ecdsa},
+ {sha256,ecdsa},
+ {sha224,ecdsa},
+ {sha224,rsa},
+ {sha,rsa},
+ {sha,dsa}]
+
+ 3&gt; ssl:signature_algs(exclusive, 'tlsv1.3').
+ [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
+ ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
+ rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
+ rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]
+ </c></p>
+
+ <note><p>Some TLS-1-3 scheme names overlap with TLS-1.2
+ algorithm-tuple-pair-names and then TLS-1.3 names will be
+ used, for example <c>rsa_pkcs1_sha256</c> instead of
+ <c>{sha256, rsa}</c> these are legacy algorithms in TLS-1.3
+ that apply only to certificate signatures in this version of
+ the protocol.</p></note>
+ </desc>
+ </func>
<func>
<name since="" name="sockname" arity="1" />
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index c96173e98b..0a1db06804 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -81,6 +81,7 @@
filter_cipher_suites/2,
prepend_cipher_suites/2,
append_cipher_suites/2,
+ signature_algs/2,
eccs/0,
eccs/1,
versions/0,
@@ -183,12 +184,11 @@
-type hash() :: sha2() |
legacy_hash(). % exported
--type sha2() :: sha224 |
- sha256 |
- sha384 |
- sha512.
+-type sha2() :: sha256 |
+ sha384 |
+ sha512.
--type legacy_hash() :: sha | md5.
+-type legacy_hash() :: sha224 | sha | md5.
-type sign_algo() :: rsa | dsa | ecdsa | eddsa. % exported
@@ -1106,6 +1106,41 @@ append_cipher_suites(Filters, Suites) ->
(Suites -- Deferred) ++ Deferred.
%%--------------------------------------------------------------------
+-spec signature_algs(Description, Version) -> [signature_algs()] when
+ Description :: default | all | exclusive,
+ Version :: protocol_version().
+
+%% Description: Returns possible signature algorithms/schemes
+%% for TLS/DTLS version
+%%--------------------------------------------------------------------
+
+signature_algs(default, 'tlsv1.3') ->
+ tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3'),
+ tls_record:protocol_version_name('tlsv1.2')]);
+signature_algs(default, 'tlsv1.2') ->
+ tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.2')]);
+signature_algs(all, 'tlsv1.3') ->
+ tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3'),
+ tls_record:protocol_version_name('tlsv1.2')]) ++
+ tls_v1:legacy_signature_algs_pre_13();
+signature_algs(all, 'tlsv1.2') ->
+ tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.2')]) ++
+ tls_v1:legacy_signature_algs_pre_13();
+signature_algs(exclusive, 'tlsv1.3') ->
+ tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3')]);
+signature_algs(exclusive, 'tlsv1.2') ->
+ Algs = tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.2')]),
+ Algs ++ tls_v1:legacy_signature_algs_pre_13();
+signature_algs(Description, 'dtlsv1.2') ->
+ signature_algs(Description, 'tlsv1.2');
+signature_algs(Description, Version) when Description == default;
+ Description == all;
+ Description == exclusive->
+ {error, {signature_algs_not_supported_in_protocol_version, Version}};
+signature_algs(Description,_) ->
+ {error, {badarg, Description}}.
+
+%%--------------------------------------------------------------------
-spec eccs() -> NamedCurves when
NamedCurves :: [named_curve()].
diff --git a/lib/ssl/src/tls_client_connection_1_3.erl b/lib/ssl/src/tls_client_connection_1_3.erl
index d5742ea390..8f7486d419 100644
--- a/lib/ssl/src/tls_client_connection_1_3.erl
+++ b/lib/ssl/src/tls_client_connection_1_3.erl
@@ -316,6 +316,10 @@ hello_middlebox_assert(enter, _, State) ->
{keep_state, State};
hello_middlebox_assert(internal, #change_cipher_spec{}, State) ->
tls_gen_connection:next_event(wait_ee, no_record, State);
+hello_middlebox_assert(internal = Type, #encrypted_extensions{} = Msg, #state{ssl_options = #{log_level := Level}} = State) ->
+ ssl_logger:log(warning, Level, #{description => "Failed to assert middlebox server message",
+ reason => [{missing, #change_cipher_spec{}}]}, ?LOCATION),
+ ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State);
hello_middlebox_assert(info, Msg, State) ->
tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
hello_middlebox_assert(Type, Msg, State) ->
@@ -331,8 +335,10 @@ hello_retry_middlebox_assert(enter, _, State) ->
{keep_state, State};
hello_retry_middlebox_assert(internal, #change_cipher_spec{}, State) ->
tls_gen_connection:next_event(wait_sh, no_record, State);
-hello_retry_middlebox_assert(internal, #server_hello{}, State) ->
- tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State, [postpone]);
+hello_retry_middlebox_assert(internal = Type, #server_hello{} = Msg, #state{ssl_options = #{log_level := Level}} = State) ->
+ ssl_logger:log(warning, Level, #{description => "Failed to assert middlebox server message",
+ reason => [{missing, #change_cipher_spec{}}]}, ?LOCATION),
+ ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State);
hello_retry_middlebox_assert(info, Msg, State) ->
tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
hello_retry_middlebox_assert(Type, Msg, State) ->
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 7404365520..8eda30506a 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -55,6 +55,7 @@
oid_to_enum/1,
enum_to_oid/1,
default_signature_algs/1,
+ legacy_signature_algs_pre_13/0,
signature_algs/2,
signature_schemes/2,
rsa_schemes/0,
@@ -885,7 +886,8 @@ signature_algs(?TLS_1_2, HashSigns) ->
default_signature_algs([?TLS_1_3]) ->
default_signature_schemes(?TLS_1_3) ++ legacy_signature_schemes(?TLS_1_3);
default_signature_algs([?TLS_1_3, ?TLS_1_2 | _]) ->
- default_signature_schemes(?TLS_1_3) ++ default_pre_1_3_signature_algs_only();
+ default_signature_schemes(?TLS_1_3) ++ legacy_signature_schemes(?TLS_1_3)
+ ++ default_pre_1_3_signature_algs_only();
default_signature_algs([?TLS_1_2 = Version |_]) ->
Default = [%% SHA2 ++ PSS
{sha512, ecdsa},
@@ -899,9 +901,7 @@ default_signature_algs([?TLS_1_2 = Version |_]) ->
{sha256, ecdsa},
rsa_pss_pss_sha256,
rsa_pss_rsae_sha256,
- {sha256, rsa},
- {sha224, ecdsa},
- {sha224, rsa}
+ {sha256, rsa}
],
signature_algs(Version, Default);
default_signature_algs(_) ->
@@ -910,16 +910,14 @@ default_signature_algs(_) ->
default_pre_1_3_signature_algs_only() ->
Default = [%% SHA2
{sha512, ecdsa},
- {sha512, rsa},
{sha384, ecdsa},
- {sha384, rsa},
- {sha256, ecdsa},
- {sha256, rsa},
- {sha224, ecdsa},
- {sha224, rsa}
+ {sha256, ecdsa}
],
signature_algs(?TLS_1_2, Default).
+legacy_signature_algs_pre_13() ->
+ [{sha224, ecdsa}, {sha224, rsa}, {sha, rsa}, {sha, dsa}].
+
signature_schemes(Version, [_|_] =SignatureSchemes) when is_tuple(Version)
andalso ?TLS_GTE(Version, ?TLS_1_2) ->
CryptoSupports = crypto:supports(),
diff --git a/lib/ssl/test/ssl_reject_SUITE.erl b/lib/ssl/test/ssl_reject_SUITE.erl
index cc24ffbcfe..be79e0543b 100644
--- a/lib/ssl/test/ssl_reject_SUITE.erl
+++ b/lib/ssl/test/ssl_reject_SUITE.erl
@@ -184,9 +184,12 @@ accept_sslv3_record_hello(Config) when is_list(Config) ->
Allversions = all_versions(),
+ AllSigAlgs = ssl:signature_algs(all, 'tlsv1.3'),
+
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {options, [{versions, Allversions} | ServerOpts]}]),
+ {options, [{versions, Allversions},
+ {signature_algs, AllSigAlgs} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
%% TLS-1.X Hello with SSL-3.0 record version
diff --git a/lib/ssl/test/tls_api_SUITE.erl b/lib/ssl/test/tls_api_SUITE.erl
index 405bb74b2d..74b4e76566 100644
--- a/lib/ssl/test/tls_api_SUITE.erl
+++ b/lib/ssl/test/tls_api_SUITE.erl
@@ -109,7 +109,9 @@
accept_pool/0,
accept_pool/1,
reuseaddr/0,
- reuseaddr/1
+ reuseaddr/1,
+ signature_algs/0,
+ signature_algs/1
]).
%% Apply export
@@ -1307,6 +1309,24 @@ tls_password_badarg(Config) when is_list(Config) ->
{error, {keyfile,badarg}}).
%%--------------------------------------------------------------------
+signature_algs() ->
+ [{doc, "Check that listing of signature algorithms for different version and configure combinations"}].
+signature_algs(Config) when is_list(Config) ->
+ true = [] =/= [Alg || Alg <- ssl:signature_algs(default, 'tlsv1.3'), is_tuple(Alg)],
+ true = [] == [Alg || Alg <- ssl:signature_algs(exclusive, 'tlsv1.3'), is_tuple(Alg)],
+ true = ssl:signature_algs(exclusive, 'tlsv1.3') =/= ssl:signature_algs(exclusive, 'tlsv1.2'),
+ true = length(ssl:signature_algs(defalt, 'tlsv1.2')) <
+ length(ssl:signature_algs(all, 'tlsv1.2')),
+ TLS_1_3_All = ssl:signature_algs(all, 'tlsv1.3'),
+ true = lists:member(rsa_pkcs1_sha512, TLS_1_3_All) andalso (not lists:member({sha512, rsa}, TLS_1_3_All)),
+ true = lists:member(rsa_pkcs1_sha384, TLS_1_3_All) andalso (not lists:member({sha384, rsa}, TLS_1_3_All)),
+ true = lists:member(rsa_pkcs1_sha256, TLS_1_3_All) andalso (not lists:member({sha256, rsa}, TLS_1_3_All)),
+ TLS_1_2_All = ssl:signature_algs(all, 'tlsv1.2'),
+ true = (not lists:member(rsa_pkcs1_sha512, TLS_1_2_All)) andalso lists:member({sha512, rsa}, TLS_1_2_All),
+ true = (not lists:member(rsa_pkcs1_sha384, TLS_1_2_All)) andalso lists:member({sha384, rsa}, TLS_1_2_All),
+ true = (not lists:member(rsa_pkcs1_sha256, TLS_1_2_All)) andalso lists:member({sha256, rsa}, TLS_1_2_All).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in
index 87fc0354b6..6371f401c0 100644
--- a/lib/wx/c_src/Makefile.in
+++ b/lib/wx/c_src/Makefile.in
@@ -199,7 +199,11 @@ release_spec: opt
$(INSTALL_PROGRAM) $(TARGET_DIR)/wxe_driver$(SO_EXT) "$(RELSYSDIR)/priv/"
$(INSTALL_PROGRAM) $(TARGET_DIR)/erl_gl$(SO_EXT) "$(RELSYSDIR)/priv/"
ifneq ($(WEBVIEW_LOADER_DLL_ORIG),)
- $(INSTALL_PROGRAM) $(WEBVIEW_LOADER_DLL_DEST) "$(RELSYSDIR)/priv/"
+ $(INSTALL_PROGRAM) $(WEBVIEW_LOADER_DLL_DEST) "$(RELSYSDIR)/priv/"
+endif
+ifeq ($(SYS_TYPE),win32)
+ $(INSTALL_PROGRAM) $(TARGET_DIR)/wxe_driver.pdb "$(RELSYSDIR)/priv/"
+ $(INSTALL_PROGRAM) $(TARGET_DIR)/erl_gl.pdb "$(RELSYSDIR)/priv/"
endif
release_docs_spec:
diff --git a/otp_build b/otp_build
index 5fec5b2551..c9d118c2a4 100755
--- a/otp_build
+++ b/otp_build
@@ -56,6 +56,8 @@ usage ()
echo " release <target_dir> - creates a small release to <target_dir>"
echo " release [-a|-s|-t] <target_dir> - creates full release to <target_dir>"
echo " tests <dir> - Build testsuites to <dir>"
+ echo " check [--help|...] - Perform various build checks. See --help for more info"
+ echo " and options."
echo ""
echo "-a builds all applications"
echo "-s builds a small system (default)"
@@ -998,6 +1000,11 @@ do_tests ()
fi
}
+do_check ()
+{
+ exec $ERL_TOP/scripts/otp_build_check "$@"
+}
+
do_debuginfo_win32 ()
{
setup_make
@@ -1294,6 +1301,9 @@ case "$1" in
echo_env_cross "$2";;
env_bootstrap)
echo_env_bootstrap;;
+ check)
+ shift;
+ do_check "$@";;
*)
usage;;
esac
diff --git a/otp_versions.table b/otp_versions.table
index 0032616639..9da37263b9 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,3 +1,4 @@
+OTP-25.3.2 : compiler-8.2.6 erts-13.2.2 os_mon-2.8.2 # asn1-5.0.21 common_test-1.24 crypto-5.1.4 debugger-5.3.1 dialyzer-5.0.5 diameter-2.2.7 edoc-1.2 eldap-1.2.11 erl_docgen-1.4 erl_interface-5.3.2 et-1.6.5 eunit-2.8.2 ftp-1.1.4 inets-8.3.1 jinterface-1.13.2 kernel-8.5.4 megaco-4.4.3 mnesia-4.21.4 observer-2.14 odbc-2.14 parsetools-2.4.1 public_key-1.13.3 reltool-0.9.1 runtime_tools-1.19 sasl-4.2 snmp-5.13.5 ssh-4.15.3 ssl-10.9.1 stdlib-4.3.1 syntax_tools-3.0.1 tftp-1.0.4 tools-3.5.3 wx-2.2.2 xmerl-1.3.31 :
OTP-25.3.1 : compiler-8.2.5 crypto-5.1.4 eldap-1.2.11 erl_interface-5.3.2 erts-13.2.1 inets-8.3.1 snmp-5.13.5 ssl-10.9.1 stdlib-4.3.1 wx-2.2.2 # asn1-5.0.21 common_test-1.24 debugger-5.3.1 dialyzer-5.0.5 diameter-2.2.7 edoc-1.2 erl_docgen-1.4 et-1.6.5 eunit-2.8.2 ftp-1.1.4 jinterface-1.13.2 kernel-8.5.4 megaco-4.4.3 mnesia-4.21.4 observer-2.14 odbc-2.14 os_mon-2.8.1 parsetools-2.4.1 public_key-1.13.3 reltool-0.9.1 runtime_tools-1.19 sasl-4.2 ssh-4.15.3 syntax_tools-3.0.1 tftp-1.0.4 tools-3.5.3 xmerl-1.3.31 :
OTP-25.3 : common_test-1.24 compiler-8.2.4 crypto-5.1.3 debugger-5.3.1 dialyzer-5.0.5 erl_interface-5.3.1 erts-13.2 eunit-2.8.2 ftp-1.1.4 inets-8.3 jinterface-1.13.2 kernel-8.5.4 megaco-4.4.3 mnesia-4.21.4 os_mon-2.8.1 public_key-1.13.3 reltool-0.9.1 snmp-5.13.4 ssh-4.15.3 ssl-10.9 stdlib-4.3 syntax_tools-3.0.1 tftp-1.0.4 xmerl-1.3.31 # asn1-5.0.21 diameter-2.2.7 edoc-1.2 eldap-1.2.10 erl_docgen-1.4 et-1.6.5 observer-2.14 odbc-2.14 parsetools-2.4.1 runtime_tools-1.19 sasl-4.2 tools-3.5.3 wx-2.2.1 :
OTP-25.2.3 : erts-13.1.5 inets-8.2.2 ssh-4.15.2 ssl-10.8.7 # asn1-5.0.21 common_test-1.23.3 compiler-8.2.3 crypto-5.1.2 debugger-5.3 dialyzer-5.0.4 diameter-2.2.7 edoc-1.2 eldap-1.2.10 erl_docgen-1.4 erl_interface-5.3 et-1.6.5 eunit-2.8.1 ftp-1.1.3 jinterface-1.13.1 kernel-8.5.3 megaco-4.4.2 mnesia-4.21.3 observer-2.14 odbc-2.14 os_mon-2.8 parsetools-2.4.1 public_key-1.13.2 reltool-0.9 runtime_tools-1.19 sasl-4.2 snmp-5.13.3 stdlib-4.2 syntax_tools-3.0 tftp-1.0.3 tools-3.5.3 wx-2.2.1 xmerl-1.3.30 :
diff --git a/scripts/otp_build_check b/scripts/otp_build_check
new file mode 100755
index 0000000000..ee6e656cdf
--- /dev/null
+++ b/scripts/otp_build_check
@@ -0,0 +1,344 @@
+#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2023. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# %CopyrightEnd%
+#
+
+#
+# Performs a lot of (but not always all) build checking that you want to do...
+#
+
+docs=yes
+dialyzer=yes
+tests=all
+opt_only=no
+format_check=yes
+
+have_printf=no
+
+print_error() {
+ if [ $have_printf = yes ]; then
+ printf "\033[31mERROR: %s\033[0m\n" "$1" 1>&2
+ else
+ echo "ERROR: $1" 1>&2
+ fi
+}
+
+progress() {
+ if [ $have_printf = yes ]; then
+ printf "\n\033[33m*** %s ***\033[0m\n\n" "$1" 1>&2
+ else
+ echo "\n*** $1 ***\n" 1>&2
+ fi
+}
+
+print_usage() {
+ cat <<EOF
+Usage:
+ otp_build check [--help|-h] [--only-opt|-o] [--no-docs|-d] \\
+ [--no-dialyzer|-y] [--no-tests|-n] [--no-format-check|-f] \\
+ [--tests|-t <App0> ... <AppN>]
+
+
+By default all currently implemented checks will be performed. If any of the
+currently used tools are missing, checking will fail. If libraries or tools
+needed to support certain conditional features are missing, those features
+will not be checked.
+
+If any of these checks do not pass, the code is *not* ready for testing in OTP
+daily builds. Note that this script does not check all requirements for testing
+in OTP daily builds. These checks are the bare minimum for even considering
+testing in OTP daily builds. Currently the following will be performed by
+default:
+
+ * Build all applications in optimized mode. If configure already has been run,
+ it wont be run again.
+ * Debug compile C-code in all applications.
+ * Format checking of JIT code.
+ * Run dialyzer on all applications.
+ * Build all documentation.
+ * Run xmllint on all documentation.
+ * Run html link check on all documentation.
+ * Build all test suites.
+
+Certain build checking can be disabled using the following options:
+* [--only-opt|-o] - Only build optimized system. No debug, etc.
+* [--no-format-check|-f] - No JIT format checking.
+* [--no-docs|-d] - No documentation checking.
+* [--no-dialyzer|-y] - No dialyzer checking.
+* [--no-tests|-n] - No build checking of test suites.
+* [--tests|-t <App0> ... <AppN>] - Only build checking of test suites for
+ listed applications.
+
+Only disable build checking for parts of the system that you are certain your
+changes wont effect. Note that even though you've made no changes in
+documentation source files, documentation build is effected by type changes
+in code.
+
+Environment variables used:
+* CONFIG_FLAGS - Arguments to pass to configure if it is executed.
+
+Build results will be placed under the \$ERL_TOP/release/<TARGET> directory
+
+EOF
+}
+
+usage () {
+ print_error "$1"
+ print_usage >&2
+ exit 1
+}
+
+fail () {
+ print_error "$1"
+ exit 1
+}
+
+type printf >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+ have_printf=yes
+fi
+
+[ "$ERL_TOP" != "" ] || fail "ERL_TOP needs to be set"
+
+cd "$ERL_TOP" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $ERL_TOP"
+}
+
+[ -f "$ERL_TOP/OTP_VERSION" ] || fail "ERL_TOP not valid"
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ --help|-h)
+ print_usage
+ exit 0;;
+ --only-opt|-o)
+ opt_only=yes;;
+ --no-docs|-d)
+ docs=no;;
+ --no-dialyzer|-y)
+ dialyzer=no;;
+ --no-format-check|-f)
+ format_check=no;;
+ --no-tests|-n)
+ tests=none;;
+ --tests|-t)
+ shift
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -*)
+ break;;
+ test_server|emulator|system|epmd)
+ ;;
+ *)
+ [ -d "$ERL_TOP/lib/$1/test" ] || {
+ fail "Invalid application: $1"
+ }
+ ;;
+ esac
+ tapps="$1 $tapps"
+ shift
+ done
+ [ "$tapps" != "" ] || usage "No test apps given"
+ tests="$tapps"
+ continue;;
+ *)
+ usage "Invalid option: $1"
+ esac
+ shift
+done
+
+[ -f "$ERL_TOP/make/config.status" ] || {
+ ./configure $CONFIG_FLAGS || fail "configure failed"
+}
+
+type gmake >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+ export MAKE="gmake"
+else
+ type make >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ export MAKE="make"
+ fi
+fi
+
+target=`$MAKE target_configured` || fail "Failed to determine target directory"
+
+unset TESTROOT
+unset RELEASE_ROOT
+unset ERL_LIBS
+unset OTP_SMALL_BUILD
+unset OTP_TINY_BUILD
+unset TARGET
+
+progress "Building OTP in $ERL_TOP"
+$MAKE || fail "OTP build failed"
+progress "Booting optimized runtime"
+$ERL_TOP/bin/cerl -eval "erlang:halt()" || {
+ fail "Failed to boot runtime"
+}
+
+[ $opt_only = yes ] || {
+ progress "Building debug OTP in $ERL_TOP"
+ $MAKE TYPE=debug || fail "OTP debug build failed"
+ progress "Booting debug runtime"
+ $ERL_TOP/bin/cerl -debug -eval "erlang:halt()" || {
+ fail "Failed to boot debug runtime"
+ }
+}
+
+[ $format_check = no ] || {
+ clang-format --help 2>&1 >/dev/null || {
+ fail "clang-format not installed. Use --no-format-check option to skip."
+ }
+
+ progress "Checking C & C++ code formatting"
+ $MAKE format-check || {
+ fail "Failed to format C & C++ code"
+ }
+}
+
+progress "Releasing OTP"
+$MAKE release || fail "Releasing OTP failed"
+
+cd "$ERL_TOP/release/$target" 2>&1 >/dev/null || {
+ fail "Failed to change directory into release directory: $ERL_TOP/release/$target"
+}
+
+progress "Installing OTP"
+./Install -minimal `pwd` || fail "Failed to install release"
+
+progress "Booting optimized installed runtime"
+./bin/erl -eval "erlang:halt()" || {
+ fail "Failed to boot installed runtime"
+}
+
+cd "$ERL_TOP" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $ERL_TOP"
+}
+
+export PATH="$ERL_TOP/release/$target/bin:$PATH"
+
+[ $docs = no ] || {
+ progress "Building OTP documentation"
+ $MAKE docs || fail "Building documentation failed"
+ progress "Releasing OTP documentation"
+ $MAKE release_docs || fail "Releasing documentation failed"
+ progress "Running xmllint on OTP documentation"
+ $MAKE xmllint || fail "xmllint of documentation failed"
+ progress "Running HTML check on OTP documentation"
+ ./scripts/otp_html_check "$ERL_TOP/release/$target/" doc/index.html || {
+ fail "HTML check of documentation failed"
+ }
+}
+
+[ $dialyzer = no ] || {
+ progress "Running dialyzer on OTP"
+ $MAKE dialyzer || fail "Dialyzing OTP failed"
+}
+
+[ "$tests" = none ] || {
+ test_dir="$ERL_TOP/release/$target/test"
+ [ -d "$test_dir" ] || mkdir "$test_dir" 2>&1 >/dev/null || {
+ fail "Failed to create $test_dir directory"
+ }
+ if [ "$tests" = all ]; then
+ progress "Releasing all OTP tests"
+ ./otp_build tests "$test_dir" || fail "Release of tests failed"
+ else
+ for tapp in $tests; do
+ case $tapp in
+ test_server)
+ tapp_dir="$ERL_TOP/lib/test_server"
+ if [ ! -d "$tapp_dir" ]; then
+ tapp_dir="$ERL_TOP/lib/common_test/test_server"
+ fi
+ ;;
+ emulator) tapp_dir="$ERL_TOP/erts/emulator/test";;
+ system) tapp_dir="$ERL_TOP/erts/test";;
+ epmd) tapp_dir="$ERL_TOP/erts/epmd/test";;
+ *) tapp_dir="$ERL_TOP/lib/$tapp/test";;
+ esac
+ cd "$tapp_dir" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $tapp_dir"
+ }
+ progress "Releasing $tapp tests"
+ $MAKE "TESTROOT=$test_dir" release_tests || {
+ fail "Release of $tapp tests failed"
+ }
+ done
+
+ fi
+
+ cd "$test_dir" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $test_dir"
+ }
+
+ for dir in *; do
+
+ [ -d "$test_dir/$dir" ] || continue
+
+ progress "Building $dir tests"
+
+ cd "$test_dir/$dir" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $test_dir/$dir"
+ }
+
+ for mfile in *_data/Makefile.first; do
+
+ [ "$mfile" != '*_data/Makefile.first' ] || continue
+
+ ddir=`dirname $mfile` || fail "dirname on $test_dir/$dir/$mfile failed"
+
+ cd "$test_dir/$dir/$ddir" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $test_dir/$dir/$ddir"
+ }
+
+ $MAKE -f Makefile.first || {
+ fail "Make of $test_dir/$dir/$ddir/Makefile.first failed"
+ }
+
+ done
+
+ cd "$test_dir/$dir" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $test_dir/$dir"
+ }
+
+ if [ -f Emakefile ]; then
+ erl -noshell -eval 'case make:all() of error -> erlang:halt(1); _ -> init:stop() end.' || {
+ fail "Build of $dir failed"
+ }
+ else
+ erlc -I `erl -noshell -eval 'io:format("~ts",[code:lib_dir(common_test)]),init:stop()'`/include -I . *.erl || {
+ fail "Build of $dir failed"
+ }
+ fi
+
+ done
+
+ cd "$ERL_TOP" 2>&1 >/dev/null || {
+ fail "Failed to change directory into $ERL_TOP"
+ }
+}
+
+if [ $have_printf = yes ]; then
+ printf "\n\033[32m*** Success! ***\033[0m\n\n"
+else
+ echo "\n*** Success! ***\n"
+fi
+exit 0
diff --git a/system/doc/general_info/upcoming_incompatibilities.xml b/system/doc/general_info/upcoming_incompatibilities.xml
index 04ab4459c0..8538067b57 100644
--- a/system/doc/general_info/upcoming_incompatibilities.xml
+++ b/system/doc/general_info/upcoming_incompatibilities.xml
@@ -53,6 +53,7 @@
</section>
<section>
+ <marker id="maybe_expr"/>
<title>Feature maybe_expr will be enabled by default</title>
<p>
As of OTP 27, the <c>maybe_expr</c> feature will be approved
@@ -119,6 +120,65 @@
the regular expression before matching with it.</p></item>
</list>
</section>
+
+ <section>
+ <marker id="float_matching"/>
+ <title>0.0 and -0.0 will no longer be exactly equal</title>
+
+ <p>Currently, the floating point numbers <c>0.0</c> and <c>-0.0</c>
+ have distinct internal representations. That can be seen if they are
+ converted to binaries:</p>
+ <pre>
+1&gt; <input>&lt;&lt;0.0/float&gt;&gt;.</input>
+&lt;&lt;0,0,0,0,0,0,0,0&gt;&gt;
+2&gt; <input>&lt;&lt;-0.0/float&gt;>.</input>
+&lt;&lt;128,0,0,0,0,0,0,0>></pre>
+
+ <p>However, when they are matched against each other or compared
+ using the <c>=:=</c> operator, they are considered to be
+ equal. Thus, <c>0.0 =:= -0.0</c> currently returns
+ <c>true</c>.</p>
+
+ <p>In Erlang/OTP 27, <c>0.0 =:= -0.0</c> will return <c>false</c>, and matching
+ <c>0.0</c> against <c>-0.0</c> will fail. When used as map keys, <c>0.0</c> and
+ <c>-0.0</c> will be considered to be distinct.</p>
+
+ <p>The <c>==</c> operator will continue to return <c>true</c>
+ for <c>0.0 == -0.0</c>.</p>
+
+ <p>To help to find code that might need to be revised, in OTP 27
+ there will be a new compiler warning when matching against
+ <c>0.0</c> or comparing to that value using the <c>=:=</c>
+ operator. The warning can be suppressed by matching against
+ <c>+0.0</c> instead of <c>0.0</c>.</p>
+
+ <p>We plan to introduce the same warning in OTP 26.1, but by default it
+ will be disabled.</p>
+ </section>
+
+ <section>
+ <marker id="singleton_typevars"/>
+ <title>Singleton type variables will become a compile-time error</title>
+
+ <p>Before Erlang/OTP 26, the compiler would silenty accept the
+ following spec:</p>
+
+ <pre>
+-spec f(Opts) -> term() when
+ Opts :: {ok, Unknown} | {error, Unknown}.
+f(_) -> error.</pre>
+
+ <p>In OTP 26, the compiler emits a warning pointing out that the type variable
+ <c>Unknown</c> is unbound:</p>
+
+ <pre>
+t.erl:6:18: Warning: type variable 'Unknown' is only used once (is unbound)
+% 6| Opts :: {ok, Unknown} | {error, Unknown}.
+% | ^</pre>
+
+ <p>In OTP 27, that warning will become an error.</p>
+ </section>
+
</section>
<section>