diff options
Diffstat (limited to 'lib')
76 files changed, 1134 insertions, 228 deletions
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index af671ff7ba..75396f4c0f 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,6 +32,28 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 8.2.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>When a map update such as <c>#{}#{key:=value}</c> that + should fail with an exception was unused, the exception + would be lost.</p> + <p> + Own Id: OTP-18497 Aux Id: GH-6960, PR-6965 </p> + </item> + <item> + <p>Fixed bug in the validator that made it reject valid + code.</p> + <p> + Own Id: OTP-18516 Aux Id: GH-6969 </p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 8.2.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl index 8b9cb836fd..697566cecb 100644 --- a/lib/compiler/src/beam_call_types.erl +++ b/lib/compiler/src/beam_call_types.erl @@ -365,12 +365,19 @@ types(erlang, is_boolean, [Type]) -> types(erlang, is_float, [Type]) -> sub_unsafe_type_test(Type, #t_float{}); types(erlang, is_function, [Type, #t_integer{elements={Arity,Arity}}]) - when Arity >= 0, Arity =< ?MAX_FUNC_ARGS -> + when is_integer(Arity) -> RetType = - case meet(Type, #t_fun{arity=Arity}) of - Type -> #t_atom{elements=[true]}; - none -> #t_atom{elements=[false]}; - _ -> beam_types:make_boolean() + if + Arity < 0 -> + none; + 0 =< Arity, Arity =< ?MAX_FUNC_ARGS -> + case meet(Type, #t_fun{arity=Arity}) of + Type -> #t_atom{elements=[true]}; + none -> #t_atom{elements=[false]}; + _ -> beam_types:make_boolean() + end; + Arity > ?MAX_FUNC_ARGS -> + #t_atom{elements=[false]} end, sub_unsafe(RetType, [any, any]); types(erlang, is_function, [Type]) -> diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index 90672bab7c..9ae5a33d74 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -464,6 +464,7 @@ add_scope([I|Is], Scope) -> [I|add_scope(Is, Scope)]; add_scope([], _Scope) -> []. +is_shareable([{badmatch,_}|_]) -> false; is_shareable([build_stacktrace|_]) -> false; is_shareable([{case_end,_}|_]) -> false; is_shareable([{'catch',_,_}|_]) -> false; diff --git a/lib/compiler/src/beam_ssa.erl b/lib/compiler/src/beam_ssa.erl index 619a9f032a..448b3b4313 100644 --- a/lib/compiler/src/beam_ssa.erl +++ b/lib/compiler/src/beam_ssa.erl @@ -383,10 +383,21 @@ successors(#b_blk{last=Terminator}) -> -spec normalize(b_set() | terminator()) -> b_set() | terminator(). -normalize(#b_set{op={bif,Bif},args=Args}=Set) -> +normalize(#b_set{anno=Anno0,op={bif,Bif},args=Args}=Set) -> case {is_commutative(Bif),Args} of {true, [#b_literal{}=Lit,#b_var{}=Var]} -> - Set#b_set{args=[Var,Lit]}; + Anno = case Anno0 of + #{arg_types := ArgTypes0} -> + case ArgTypes0 of + #{1 := Type} -> + Anno0#{arg_types => #{0 => Type}}; + #{} -> + Anno0 + end; + #{} -> + Anno0 + end, + Set#b_set{anno=Anno,args=[Var,Lit]}; {_, _} -> Set end; diff --git a/lib/compiler/src/beam_ssa_codegen.erl b/lib/compiler/src/beam_ssa_codegen.erl index c4708e9b11..9f6169829b 100644 --- a/lib/compiler/src/beam_ssa_codegen.erl +++ b/lib/compiler/src/beam_ssa_codegen.erl @@ -1450,6 +1450,12 @@ cg_copy_1([], _St) -> []. element(1, Val) =:= atom orelse element(1, Val) =:= literal)). +bif_to_test(min, Args, Fail, St) -> + %% The min/2 and max/2 BIFs can only be rewritten to tests when + %% both arguments are known to be booleans. + bif_to_test('and', Args, Fail, St); +bif_to_test(max, Args, Fail, St) -> + bif_to_test('or', Args, Fail, St); bif_to_test('or', [V1,V2], {f,Lbl}=Fail, St0) when Lbl =/= 0 -> {SuccLabel,St} = new_label(St0), {[{test,is_eq_exact,{f,SuccLabel},[V1,{atom,false}]}, diff --git a/lib/compiler/src/beam_types.erl b/lib/compiler/src/beam_types.erl index 9c3da159c4..b668251f79 100644 --- a/lib/compiler/src/beam_types.erl +++ b/lib/compiler/src/beam_types.erl @@ -1182,11 +1182,24 @@ float_from_range(any) -> float_from_range({'-inf','+inf'}) -> #t_float{}; float_from_range({'-inf',Max}) -> - #t_float{elements={'-inf',float(Max)}}; + make_float_range('-inf', safe_float(Max)); float_from_range({Min,'+inf'}) -> - #t_float{elements={float(Min),'+inf'}}; + make_float_range(safe_float(Min), '+inf'); float_from_range({Min,Max}) -> - #t_float{elements={float(Min),float(Max)}}. + make_float_range(safe_float(Min), safe_float(Max)). + +safe_float(N) when is_number(N) -> + try + float(N) + catch + error:_ when N < 0 -> '-inf'; + error:_ when N > 0 -> '+inf' + end. + +make_float_range('-inf', '+inf') -> + #t_float{}; +make_float_range(Min, Max) -> + #t_float{elements={Min, Max}}. integer_from_range(none) -> none; diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 285db8a26a..217b7a2c97 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -1582,7 +1582,7 @@ update_create_bin_list([], Vst) -> Vst. update_create_bin_type(append) -> #t_bitstring{}; update_create_bin_type(private_append) -> #t_bitstring{}; update_create_bin_type(binary) -> #t_bitstring{}; -update_create_bin_type(float) -> #t_float{}; +update_create_bin_type(float) -> #t_number{}; update_create_bin_type(integer) -> #t_integer{}; update_create_bin_type(utf8) -> #t_integer{}; update_create_bin_type(utf16) -> #t_integer{}; @@ -3435,7 +3435,17 @@ bif_types(Op, Ss, Vst) -> Other end; {_,_} -> - beam_call_types:types(erlang, Op, Args) + Res0 = beam_call_types:types(erlang, Op, Args), + {Ret0, ArgTypes, SubSafe} = Res0, + + %% Match the non-converging range analysis done in + %% `beam_ssa_type:opt_ranges/1`. This is safe since the validator + %% doesn't have to worry about convergence. + case beam_call_types:arith_type({bif, Op}, Args) of + any -> Res0; + Ret0 -> Res0; + Ret -> {meet(Ret, Ret0), ArgTypes, SubSafe} + end end. join_tuple_elements(Tuple) -> diff --git a/lib/compiler/test/beam_jump_SUITE.erl b/lib/compiler/test/beam_jump_SUITE.erl index 713a1ea5ab..65fecd5b7c 100644 --- a/lib/compiler/test/beam_jump_SUITE.erl +++ b/lib/compiler/test/beam_jump_SUITE.erl @@ -82,6 +82,8 @@ ambiguous_catch_try_state(Config) -> {'EXIT',{{badmatch,0},_}} = (catch ambiguous_catch_try_state_2()), {'EXIT',{{badmatch,0},_}} = (catch ambiguous_catch_try_state_3()), + {'EXIT',{badarg,_}} = catch ambiguous_catch_try_state_4(), + ok. river() -> song. @@ -229,6 +231,12 @@ ambiguous_catch_try_state_3() -> end. +ambiguous_catch_try_state_4() -> + 0.0 = try binary_to_float(garbage_collect() orelse ((1.0 = tuple_to_list(ok)) -- ok)) + after + ok + end. + -record(message2, {id, p1}). -record(message3, {id, p1, p2}). diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl index 6a91bdd7b8..0bb485c7f1 100644 --- a/lib/compiler/test/beam_ssa_SUITE.erl +++ b/lib/compiler/test/beam_ssa_SUITE.erl @@ -27,7 +27,7 @@ beam_ssa_dead_crash/1,stack_init/1, mapfoldl/0,mapfoldl/1, grab_bag/1,redundant_br/1, - coverage/1]). + coverage/1,normalize/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -48,7 +48,8 @@ groups() -> stack_init, grab_bag, redundant_br, - coverage + coverage, + normalize ]}]. init_per_suite(Config) -> @@ -1260,5 +1261,90 @@ coverage_5() -> error end#coverage{name = whatever}. +%% Test beam_ssa:normalize/1, especially that argument types are +%% correctly updated when arguments are swapped. +normalize(_Config) -> + normalize_commutative({bif,'band'}), + normalize_commutative({bif,'+'}), + + normalize_noncommutative({bif,'div'}), + + ok. + +-record(b_var, {name}). +-record(b_literal, {val}). + +normalize_commutative(Op) -> + A = #b_var{name=a}, + B = #b_var{name=b}, + Lit = #b_literal{val=42}, + + normalize_same(Op, [A,B]), + normalize_same(Op, [A,Lit]), + + normalize_swapped(Op, [Lit,A]), + + ok. + +normalize_noncommutative(Op) -> + A = #b_var{name=a}, + B = #b_var{name=b}, + Lit = #b_literal{val=42}, + + normalize_same(Op, [A,B]), + normalize_same(Op, [A,Lit]), + + ArgTypes0 = [{1,beam_types:make_integer(0, 1023)}], + I1 = make_bset(ArgTypes0, Op, [Lit,A]), + I1 = beam_ssa:normalize(I1), + + ok. + +normalize_same(Op, Args) -> + I0 = make_bset(#{}, Op, Args), + I0 = beam_ssa:normalize(I0), + + ArgTypes0 = [{0,beam_types:make_integer(0, 1023)}], + I1 = make_bset(ArgTypes0, Op, Args), + I1 = beam_ssa:normalize(I1), + + case Args of + [#b_var{},#b_var{}] -> + ArgTypes1 = [{0,beam_types:make_integer(0, 1023)}, + {1,beam_types:make_integer(42)}], + I2 = make_bset(ArgTypes1, Op, Args), + I2 = beam_ssa:normalize(I2); + [_,_] -> + ok + end, + + ok. + +normalize_swapped(Op, [#b_literal{}=Lit,#b_var{}=Var]=Args) -> + EmptyAnno = #{}, + I0 = make_bset(EmptyAnno, Op, Args), + {b_set,EmptyAnno,#b_var{name=1000},Op,[Var,Lit]} = beam_ssa:normalize(I0), + + EmptyTypes = #{arg_types => #{}}, + I1 = make_bset(EmptyTypes, Op, Args), + {b_set,EmptyTypes,#b_var{name=1000},Op,[Var,Lit]} = beam_ssa:normalize(I1), + + IntRange = beam_types:make_integer(0, 1023), + ArgTypes0 = [{1,IntRange}], + I2 = make_bset(ArgTypes0, Op, Args), + {[{0,IntRange}],Op,[Var,Lit]} = unpack_bset(beam_ssa:normalize(I2)), + + ok. + +make_bset(ArgTypes, Op, Args) when is_list(ArgTypes) -> + Anno = #{arg_types => maps:from_list(ArgTypes)}, + {b_set,Anno,#b_var{name=1000},Op,Args}; +make_bset(Anno, Op, Args) when is_map(Anno) -> + {b_set,Anno,#b_var{name=1000},Op,Args}. + +unpack_bset({b_set,Anno,{b_var,1000},Op,Args}) -> + ArgTypes = maps:get(arg_types, Anno, #{}), + {lists:sort(maps:to_list(ArgTypes)),Op,Args}. + %% The identity function. id(I) -> I. diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl index 0b00e6d71c..18a29f2643 100644 --- a/lib/compiler/test/beam_type_SUITE.erl +++ b/lib/compiler/test/beam_type_SUITE.erl @@ -22,14 +22,16 @@ -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, init_per_group/2,end_per_group/2, integers/1,numbers/1,coverage/1,booleans/1,setelement/1, - cons/1,tuple/1,record_float/1,binary_float/1,float_compare/1, + cons/1,tuple/1, + record_float/1,binary_float/1,float_compare/1,float_overflow/1, arity_checks/1,elixir_binaries/1,find_best/1, test_size/1,cover_lists_functions/1,list_append/1,bad_binary_unit/1, none_argument/1,success_type_oscillation/1,type_subtraction/1, container_subtraction/1,is_list_opt/1,connected_tuple_elements/1, switch_fail_inference/1,failures/1, cover_maps_functions/1,min_max_mixed_types/1, - not_equal/1,infer_relops/1,binary_unit/1,premature_concretization/1]). + not_equal/1,infer_relops/1,binary_unit/1,premature_concretization/1, + funs/1]). %% Force id/1 to return 'any'. -export([id/1]). @@ -51,6 +53,7 @@ groups() -> record_float, binary_float, float_compare, + float_overflow, arity_checks, elixir_binaries, find_best, @@ -71,7 +74,8 @@ groups() -> not_equal, infer_relops, binary_unit, - premature_concretization + premature_concretization, + funs ]}]. init_per_suite(Config) -> @@ -741,11 +745,17 @@ record_float(R, N0) -> binary_float(_Config) -> <<-1/float>> = binary_negate_float(<<1/float>>), + {'EXIT',{badarg,_}} = catch binary_float_1(id(64.0), id(0)), ok. binary_negate_float(<<Float/float>>) -> <<-Float/float>>. +%% GH-7147. +binary_float_1(X, Y) -> + _ = <<Y:(ceil(64.0 = X))/float, (binary_to_integer(ok))>>, + ceil(X) band Y. + float_compare(_Config) -> false = do_float_compare(-42.0), false = do_float_compare(-42), @@ -765,6 +775,39 @@ do_float_compare(X) -> _T -> Y > 0 end. +float_overflow(_Config) -> + Res1 = id((1 bsl 1023) * two()), + Res1 = float_overflow_1(), + + Res2 = id((-1 bsl 1023) * two()), + Res2 = float_overflow_2(), + + ok. + +%% GH-7178: There would be an overflow when converting a number range +%% to a float range. +float_overflow_1() -> + round( + try + round(float(1 bsl 1023)) * two() + catch + _:_ -> + 0.0 + end + ). + +float_overflow_2() -> + round( + try + round(float(-1 bsl 1023)) * two() + catch + _:_ -> + 0.0 + end + ). + +two() -> 2. + arity_checks(_Config) -> %% ERL-549: an unsafe optimization removed a test_arity instruction, %% causing the following to return 'broken' instead of 'ok'. @@ -1363,5 +1406,20 @@ pm_concretization_2(_, Tagged) -> {error, Tagged}. pm_concretization_3(_) -> ok. pm_concretization_4(_) -> ok. +funs(_Config) -> + {'EXIT',{badarg,_}} = catch gh_7179(), + false = is_function(id(fun() -> ok end), 1024), + + ok. + +%% GH-7179: The beam_ssa_type pass would crash. +gh_7179() -> + << <<0>> || is_function([0 || <<_>> <= <<>>], -1), + [] <- [] >>. + +%%% +%%% Common utilities. +%%% + id(I) -> I. diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 6b63f561c1..2092d7401a 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -43,7 +43,7 @@ container_performance/1, infer_relops/1, not_equal_inference/1,bad_bin_unit/1,singleton_inference/1, - inert_update_type/1]). + inert_update_type/1,range_inference/1]). -include_lib("common_test/include/ct.hrl"). @@ -80,7 +80,7 @@ groups() -> bs_saved_position_units,parent_container, container_performance,infer_relops, not_equal_inference,bad_bin_unit,singleton_inference, - inert_update_type]}]. + inert_update_type,range_inference]}]. init_per_suite(Config) -> test_lib:recompile(?MODULE), @@ -1129,5 +1129,22 @@ mike([Head | _Rest]) -> joe(Head). joe({Name, 42}) -> Name; joe({sys_period, {A, _B}}) -> {41, 42, A}. +range_inference(_Config) -> + ok = range_inference_1(id(<<$a>>)), + ok = range_inference_1(id(<<0>>)), + ok = range_inference_1(id(<<1114111/utf8>>)), + + ok. + +range_inference_1(<<X/utf8>>) -> + case 9223372036854775807 - abs(X) of + Y when X < Y -> + ok; + 9223372036854775807 -> + ok; + -2147483648 -> + ok + end. + id(I) -> I. diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl index fc1d9ddfc0..e58db29114 100644 --- a/lib/compiler/test/bif_SUITE.erl +++ b/lib/compiler/test/bif_SUITE.erl @@ -25,7 +25,8 @@ init_per_group/2,end_per_group/2, beam_validator/1,trunc_and_friends/1,cover_safe_and_pure_bifs/1, cover_trim/1, - head_tail/1]). + head_tail/1, + min_max/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -34,12 +35,13 @@ all() -> [{group,p}]. groups() -> - [{p,[parallel], + [{p,test_lib:parallel(), [beam_validator, trunc_and_friends, cover_safe_and_pure_bifs, cover_trim, - head_tail + head_tail, + min_max ]}]. init_per_suite(Config) -> @@ -192,5 +194,40 @@ tail_case() -> X -> {X, ok} end. +min_max(_Config) -> + False = id(false), + True = id(true), + + false = bool_min_false(False, False), + false = bool_min_false(False, True), + false = bool_min_false(True, False), + true = bool_min_true(True, True), + + false = bool_max_false(False, False), + true = bool_max_true(False, True), + true = bool_max_true(True, False), + true = bool_max_true(True, True), + + ok. + +%% GH-7170: The following functions would cause a crash in +%% beam_ssa_codegen. + +bool_min_false(A, B) when is_boolean(A), is_boolean(B) -> + false = min(A, B). + +bool_min_true(A, B) when is_boolean(A), is_boolean(B) -> + true = min(A, B). + +bool_max_false(A, B) when is_boolean(A), is_boolean(B) -> + false = max(A, B). + +bool_max_true(A, B) when is_boolean(A), is_boolean(B) -> + true = max(A, B). + +%%% +%%% Common utilities. +%%% + id(I) -> I. diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 0a39fcf419..0c4eae4d45 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 8.2.4 +COMPILER_VSN = 8.2.5 diff --git a/lib/crypto/c_src/dh.c b/lib/crypto/c_src/dh.c index 92a339ab5f..15a08470a6 100644 --- a/lib/crypto/c_src/dh.c +++ b/lib/crypto/c_src/dh.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2010-2022. All Rights Reserved. + * Copyright Ericsson AB 2010-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/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h index 9c7b05660e..e356cf94fb 100644 --- a/lib/crypto/c_src/openssl_config.h +++ b/lib/crypto/c_src/openssl_config.h @@ -127,6 +127,15 @@ # define HAS_EVP_PKEY_CTX # define HAVE_EVP_CIPHER_CTX_COPY # endif +# if LIBRESSL_VERSION_NUMBER >= 0x3070200fL +# define HAVE_PKEY_new_raw_private_key +# endif +# if LIBRESSL_VERSION_NUMBER >= 0x3030300fL +# define HAVE_EVP_PKEY_new_CMAC_key +# endif +# if LIBRESSL_VERSION_NUMBER >= 0x3040100fL +# define HAVE_DigestSign_as_single_op +# endif #endif #if defined(HAS_EVP_PKEY_CTX) \ diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 954d5cd664..fa5e9d5bea 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 5.1.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + With this change, random errors are fixed for + crypto:generate_key calls with OpenSSL 3.</p> + <p> + Own Id: OTP-18555</p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 5.1.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 69b01e6418..6abaacad5c 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -685,8 +685,6 @@ hash_final_xof(Context, Length) -> -type hmac_hash_algorithm() :: sha1() | sha2() | sha3() | compatibility_only_hash(). -type cmac_cipher_algorithm() :: aes_128_cbc | aes_192_cbc | aes_256_cbc | aes_cbc - | aes_128_cfb128 | aes_192_cfb128 | aes_256_cfb128 | aes_cfb128 - | aes_128_cfb8 | aes_192_cfb8 | aes_256_cfb8 | aes_cfb8 | blowfish_cbc | des_cbc | des_ede3_cbc | rc2_cbc diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 516ad02ee2..0572feaf33 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -1,7 +1,7 @@ % %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2022. All Rights Reserved. +%% Copyright Ericsson AB 1999-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. @@ -411,11 +411,11 @@ groups() -> {ecdh, [], [compute, generate, use_all_ecdh_generate_compute]}, {eddh, [], [compute, generate, use_all_eddh_generate_compute]}, {srp, [], [generate_compute]}, - {des_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]}, + {des_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, {des_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]}, - {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac]}, + {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, {des_ede3_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]}, - {rc2_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]}, + {rc2_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, {aes_cfb8, [], []}, {aes_128_cfb8, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_192_cfb8, [], [api_ng, api_ng_one_shot, api_ng_tls]}, @@ -426,7 +426,7 @@ groups() -> {aes_192_cfb128, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_256_cfb128, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {no_aes_cfb128, [], [no_support]}, - {blowfish_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]}, + {blowfish_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, {blowfish_ecb, [], [api_ng, api_ng_one_shot]}, {blowfish_cfb64, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {blowfish_ofb64, [], [api_ng, api_ng_one_shot, api_ng_tls]}, @@ -473,15 +473,15 @@ groups() -> {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {des_ede3_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_128_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, - {aes_192_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]}, - {aes_256_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac]}, + {aes_192_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, + {aes_256_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls, cmac, cmac_update]}, {aes_128_ctr, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_192_ctr, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_256_ctr, [], [api_ng, api_ng_one_shot, api_ng_tls]}, {aes_128_ccm, [], [aead_ng, aead_bad_tag]}, {aes_192_ccm, [], [aead_ng, aead_bad_tag]}, {aes_256_ccm, [], [aead_ng, aead_bad_tag]}, - {aes_128_ecb, [], [api_ng, api_ng_one_shot, cmac_update]}, + {aes_128_ecb, [], [api_ng, api_ng_one_shot]}, {aes_192_ecb, [], [api_ng, api_ng_one_shot]}, {aes_256_ecb, [], [api_ng, api_ng_one_shot]}, {aes_128_gcm, [], [aead_ng, aead_bad_tag]}, @@ -2378,6 +2378,8 @@ do_configure_mac(cmac, Cipher, Config) -> case Cipher of aes_128_cbc -> fun() -> read_rsp(Config, Cipher, ["CMACGenAES128.rsp", "CMACVerAES128.rsp"]) end; + aes_192_cbc -> + fun() -> read_rsp(Config, Cipher, ["CMACGenAES192.rsp", "CMACVerAES192.rsp"]) end; aes_256_cbc -> fun() -> read_rsp(Config, Cipher, ["CMACGenAES256.rsp", "CMACVerAES256.rsp"]) end; des_ede3_cbc -> @@ -2933,10 +2935,9 @@ hmac_inc(_) -> [<<"Sampl">>, <<"e #1">>]. -cmac_key(aes_128_cbc) -> - hexstr2bin("8eeca0d146fd09ffbbe0d47edcddfcec"); -cmac_key(aes_128_ecb) -> - hexstr2bin("8eeca0d146fd09ffbbe0d47edcddfcec"). +cmac_key(SubType) -> + rand:bytes( + maps:get(key_length, crypto:cipher_info(SubType))). cmac_inc(_) -> [<<"Sampl">>, <<"e #1">>]. diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 41dfbaef97..56f5a0f48e 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 5.1.3 +CRYPTO_VSN = 5.1.4 diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml index 9a2b409348..334cfcb8d7 100644 --- a/lib/dialyzer/doc/src/dialyzer.xml +++ b/lib/dialyzer/doc/src/dialyzer.xml @@ -507,6 +507,32 @@ dialyzer --plts plt_1 ... plt_n -- files_to_analyze</code> <p>Currently the only option used is the <seeerl marker="#error_location"><c>error_location</c></seeerl> option. </p> + + <p><em>Dialyzer configuration file:</em></p> + + <p>Dialyzer's configuration file may also be used to augment the default + options and those given directly to the Dialyzer command. It is commonly + used to avoid repeating options which would otherwise need to be given + explicitly to Dialyzer on every invocation. + </p> + + <p>The location of the configuration file can be set via the + <c>DIALYZER_CONFIG</c> environment variable, and defaults to + within the <c>user_config</c> from <seemfa marker="stdlib:filename#basedir/3"> + <c>filename:basedir/3</c></seemfa>. + </p> + + <p>An example configuration file's contents might be:</p> + + <code type="none"> + {incremental, + {default_apps,[stdlib,kernel,erts]}, + {default_warning_apps,[stdlib]} + }. + {warnings, [no_improper_lists]}. + {add_pathsa,["/users/samwise/potatoes/ebin"]}. + {add_pathsz,["/users/smeagol/fish/ebin"]}. + </code> </section> <section> diff --git a/lib/dialyzer/src/dialyzer.app.src b/lib/dialyzer/src/dialyzer.app.src index 9693aa66cd..311c019a31 100644 --- a/lib/dialyzer/src/dialyzer.app.src +++ b/lib/dialyzer/src/dialyzer.app.src @@ -56,6 +56,6 @@ {registered, []}, {applications, [compiler, kernel, stdlib]}, {env, []}, - {runtime_dependencies, ["wx-2.0","syntax_tools-2.0","stdlib-4.0", + {runtime_dependencies, ["wx-2.0","syntax_tools-2.0","stdlib-@OTP-18558@", "kernel-8.0","erts-12.0", "compiler-8.0"]}]}. diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index a502f7107d..ecfc509e34 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -415,8 +415,8 @@ message_to_string({app_call, [M, F, Args, Culprit, ExpectedType, FoundType]}, [M, F, a(Args, I), c(Culprit, I), t(ExpectedType, I), t(FoundType, I)]); message_to_string({bin_construction, [Culprit, Size, Seg, Type]}, I, _E) -> - io_lib:format("Binary construction will fail since the ~s field ~s in" - " segment ~s has type ~s\n", + io_lib:format("Binary construction will fail since the ~ts field ~ts in" + " segment ~ts has type ~ts\n", [Culprit, c(Size, I), c(Seg, I), t(Type, I)]); message_to_string({call, [M, F, Args, ArgNs, FailReason, SigArgs, SigRet, Contract]}, I, _E) -> diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 6d163c2cf9..b5cc6c7392 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -504,10 +504,11 @@ expand_files(Analysis = #analysis{files = Files, start_from = StartFrom}) -> case expand_files(Files, Ext, []) of [] -> Msg = "No " ++ Ext ++ " files to analyze" ++ - case StartFrom of - byte_code -> " (no --src specified?)"; - src_code -> "" - end, + case StartFrom of + byte_code -> " (no --src specified?)"; + src_code -> "" + end ++ + "\nConsider setting some default apps in your dialyzer.config file", exit({error, Msg}); NewFiles -> Analysis#analysis{files = NewFiles} diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl index fe7ad2af01..2babea0073 100644 --- a/lib/dialyzer/src/dialyzer_cl_parse.erl +++ b/lib/dialyzer/src/dialyzer_cl_parse.erl @@ -252,6 +252,8 @@ Note: the syntax of defines and includes is the same as that used by \"erlc\". " ++ warning_options_msg() ++ " +" ++ configuration_file_msg() ++ " + The exit status of the command line version is: 0 - No problems were encountered during the analysis and no warnings were emitted. @@ -383,3 +385,29 @@ They are primarily intended to be used with the -dialyzer attribute: -Wno_missing_return Suppress warnings about functions that return values that are not part of the specification. ". + +configuration_file_msg() -> + "Configuration file: + Dialyzer's configuration file may also be used to augment the default + options and those given directly to the Dialyzer command. It is commonly + used to avoid repeating options which would otherwise need to be given + explicitly to Dialyzer on every invocation. + + The location of the configuration file can be set via the + DIALYZER_CONFIG environment variable, and defaults to + within the user_config location given by filename:basedir/3. + + On your system, the location is currently configured as: + " ++ dialyzer_options:get_default_config_filename() ++ + " + + An example configuration file's contents might be: + + {incremental, + {default_apps,[stdlib,kernel,erts]}, + {default_warning_apps,[stdlib]} + }. + {warnings, [no_improper_lists]}. + {add_pathsa,[\"/users/samwise/potatoes/ebin\"]}. + {add_pathsz,[\"/users/smeagol/fish/ebin\"]}. +". diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index bb77ea972f..7e0a75f062 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -1602,20 +1602,23 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) -> UnitVal = cerl:concrete(cerl:bitstr_unit(Seg)), Size = cerl:bitstr_size(Seg), case bitstr_bitsize_type(Size) of - all -> - binary = SegType, [] = Segs, %% just an assert + {literal, all} -> + binary = SegType, [] = Segs, %Assertion. T = t_inf(t_bitstr(UnitVal, 0), BinType), {Map1, [Type]} = do_bind_pat_vars([Val], [T], Map, State, false, []), Type1 = remove_local_opaque_types(Type, State#state.opaques), bind_bin_segs(Segs, t_bitstr(0, 0), [Type1|Acc], Map1, State); - utf -> % XXX: can possibly be strengthened - true = lists:member(SegType, [utf8, utf16, utf32]), + SizeType when SegType =:= utf8; SegType =:= utf16; SegType =:= utf32 -> + {literal, undefined} = SizeType, %Assertion. {Map1, [_]} = do_bind_pat_vars([Val], [t_integer()], Map, State, false, []), Type = t_binary(), bind_bin_segs(Segs, BinType, [Type|Acc], Map1, State); - any -> + {literal, N} when not is_integer(N); N < 0 -> + %% Bogus literal size, fails in runtime. + bind_error([Seg], BinType, t_none(), bind); + _ -> {Map1, [SizeType]} = do_bind_pat_vars([Size], [t_non_neg_integer()], Map, State, false, []), Opaques = State#state.opaques, @@ -1668,14 +1671,8 @@ bind_bin_segs([], _BinType, Acc, Map, _State) -> bitstr_bitsize_type(Size) -> case cerl:is_literal(Size) of - true -> - case cerl:concrete(Size) of - all -> all; - undefined -> utf; - _ -> any - end; - false -> - any + true -> {literal, cerl:concrete(Size)}; + false -> variable end. %% Return the infimum (meet) of ExpectedType and Type if it describes a diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index 27da2f9c83..de35f5f204 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -18,7 +18,7 @@ -module(dialyzer_options). --export([build/1, build_warnings/2]). +-export([build/1, build_warnings/2, get_default_config_filename/0]). -include("dialyzer.hrl"). @@ -48,9 +48,12 @@ build(Opts) -> ?WARN_UNDEFINED_CALLBACK, ?WARN_UNKNOWN], DefaultWarns1 = ordsets:from_list(DefaultWarns), - DefaultOpts = #options{}, - DefaultOpts1 = DefaultOpts#options{legal_warnings = DefaultWarns1}, try + WarningsFromConfig = proplists:get_value(warnings, get_config(), []), + update_path_from_config(), + DefaultWarns2 = build_warnings(WarningsFromConfig, DefaultWarns1), + DefaultOpts = #options{}, + DefaultOpts1 = DefaultOpts#options{legal_warnings = DefaultWarns2}, Opts1 = preprocess_opts(Opts), Env = env_default_opts(), ErrLoc = proplists:get_value(error_location, Env, ?ERROR_LOCATION), @@ -61,6 +64,31 @@ build(Opts) -> throw:{dialyzer_options_error, Msg} -> {error, Msg} end. +update_path_from_config() -> + Config = get_config(), + PAs = proplists:get_value(add_pathsa, Config, []), + PZs = proplists:get_value(add_pathsz, Config, []), + case is_list(PAs) of + true -> ok; + false -> bad_option("Bad list of paths in config", {add_pathsa, PAs}) + end, + case is_list(PZs) of + true -> ok; + false -> bad_option("Bad list of paths in config", {add_pathsz, PZs}) + end, + %% Add paths one-by-one so that we can report issues + %% if any path is invalid + %% (code:add_pathsa/1 and code:add_pathsz/1 always return ok) + [ case code:add_patha(PA) of + true -> ok; + {error, _} -> bad_option("Failed to add path from config", {add_patha, PA}) + end || PA <- PAs ], + [ case code:add_pathz(PZ) of + true -> ok; + {error, _} -> bad_option("Failed to add path from config", {add_pathz, PZ}) + end || PZ <- PZs ], + ok. + preprocess_opts([]) -> []; preprocess_opts([{init_plt, File}|Opts]) -> [{plts, [File]}|preprocess_opts(Opts)]; @@ -79,7 +107,7 @@ postprocess_opts(Opts = #options{}) -> check_module_lookup_file_validity(Opts1), Opts2 = check_output_plt(Opts1), check_init_plt_kind(Opts2), - Opts3 = manage_default_apps(Opts2), + Opts3 = manage_default_incremental_apps(Opts2), adapt_get_warnings(Opts3). check_metrics_file_validity(#options{analysis_type = incremental, metrics_file = none}) -> @@ -160,31 +188,49 @@ check_init_plt_kind(#options{analysis_type = _NotIncremental, init_plts = InitPl lists:foreach(RunCheck, InitPlts). %% If no apps are set explicitly, we fall back to config -manage_default_apps(Opts = #options{analysis_type = incremental, files = [], files_rec = [], warning_files = [], warning_files_rec = []}) -> - DefaultConfig = get_default_config_filename(), - case file:consult(DefaultConfig) of - {ok, [{incremental, {default_apps, DefaultApps}=Term}]} when +manage_default_incremental_apps(Opts = #options{analysis_type = incremental, files = [], files_rec = [], warning_files = [], warning_files_rec = []}) -> + set_default_apps(get_config(), Opts); +manage_default_incremental_apps(Opts) -> + Opts. + +set_default_apps([ConfigElem|MoreConfig], Opts) -> + case ConfigElem of + {incremental, {default_apps, DefaultApps}=Term} when is_list(DefaultApps) -> AppDirs = get_app_dirs(DefaultApps), assert_filenames_form(Term, AppDirs), Opts#options{files_rec = AppDirs}; - {ok, [{incremental, {default_apps, DefaultApps}=TermApps, - {default_warning_apps, DefaultWarningApps}=TermWarns}]} when + {incremental, {default_apps, DefaultApps}=TermApps, + {default_warning_apps, DefaultWarningApps}=TermWarns} when is_list(DefaultApps), is_list(DefaultWarningApps) -> - AppDirs = get_app_dirs(DefaultApps), + AppDirs = get_app_dirs(DefaultApps ++ DefaultWarningApps), assert_filenames_form(TermApps, AppDirs), WarningAppDirs = get_app_dirs(DefaultWarningApps), assert_filenames_form(TermWarns, WarningAppDirs), Opts#options{files_rec = AppDirs, warning_files_rec = WarningAppDirs}; - {ok, _Terms} -> - bad_option("Given Erlang terms could not be understood as Dialyzer config", DefaultConfig); - {error, Reason} -> - bad_option(file:format_error(Reason), DefaultConfig) + _ when element(1, ConfigElem) =:= incremental -> + bad_option("Given Erlang terms in 'incremental' section could not be understood as Dialyzer config", ConfigElem); + _ -> + set_default_apps(MoreConfig, Opts) end; -manage_default_apps(Opts) -> +set_default_apps([], Opts) -> Opts. +get_config() -> + DefaultConfig = get_default_config_filename(), + case filelib:is_regular(DefaultConfig) of + true -> + case file:consult(DefaultConfig) of + {ok, Config} when is_list(Config) -> Config; + {error, Reason} -> + bad_option(file:format_error(Reason), DefaultConfig) + end; + false -> + [] + end. + % Intended to work like dialyzer_iplt:get_default_iplt_filename() +-spec get_default_config_filename() -> string(). get_default_config_filename() -> case os:getenv("DIALYZER_CONFIG") of false -> diff --git a/lib/dialyzer/test/incremental_SUITE.erl b/lib/dialyzer/test/incremental_SUITE.erl index 831e718777..1bf5731db8 100644 --- a/lib/dialyzer/test/incremental_SUITE.erl +++ b/lib/dialyzer/test/incremental_SUITE.erl @@ -30,6 +30,8 @@ default_apps_config_xdg/1, default_apps_config_env_var/1, default_apps_config_env_var_prioritised_over_xdg/1, + legal_warnings_config_xdg/1, + paths_config_xdg/1, multiple_plts_unsupported_in_incremental_mode/1]). suite() -> @@ -54,6 +56,8 @@ all() -> [report_new_plt_test, default_apps_config_xdg, default_apps_config_env_var, default_apps_config_env_var_prioritised_over_xdg, + legal_warnings_config_xdg, + paths_config_xdg, multiple_plts_unsupported_in_incremental_mode]. erlang_module() -> @@ -739,7 +743,7 @@ default_apps_config_xdg(Config) -> [{"HOME", TestHome}] end, - io:format("~p\n", [HomeEnv]), + io:format("~p~n", [HomeEnv]), PrivDir = ?config(priv_dir, Config), PltFile = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME) ++ ".iplt"), @@ -892,6 +896,176 @@ default_apps_config_env_var_prioritised_over_xdg(Config) -> peer:stop(Peer). +legal_warnings_config_xdg(Config) -> + TestHome = filename:join(?config(priv_dir, Config), ?FUNCTION_NAME), + + %% We change the $HOME of the emulator to run this test + HomeEnv = + case os:type() of + {win32, _} -> + [Drive | Path] = filename:split(TestHome), + [{"APPDATA", filename:join(TestHome, "AppData")}, + {"HOMEDRIVE", Drive}, + {"HOMEPATH", filename:join(Path)}]; + _ -> + [{"HOME", TestHome}] + end, + + io:format("~p~n", [HomeEnv]), + + {ok, Peer, Node} = ?CT_PEER(#{ env => HomeEnv }), + + SrcWithImproperList = <<" + -module(my_improper_list_module). + -export([g/0]). + + g() -> [a|b]. % Improper list: Last element is not the empty list + ">>, + + {ok, BeamFileWithImproperList} = + compile(Config, SrcWithImproperList, my_improper_list_module, []), + + AppsConfig = + {incremental, {default_apps, [stdlib, kernel, erts, compiler, mnesia, ftp]}}, + + erpc:call( + Node, + fun() -> + %% Find out the path of the config file + HomeConfigFilename = + filename:join(filename:basedir(user_config, "erlang"), + "dialyzer.config"), + io:format("~ts\n", [HomeConfigFilename]), + ok = filelib:ensure_dir(HomeConfigFilename), + + %% Write configuration file + WarningsConfig1 = + {warnings, [no_unknown, no_improper_lists]}, + ok = file:write_file(HomeConfigFilename, + io_lib:format("~p.~n~p.~n", [AppsConfig, WarningsConfig1])), + WarningsWithConfigSet = + dialyzer:run([{analysis_type, incremental}, + {files, [BeamFileWithImproperList]}, + {from, byte_code}]), + ?assertEqual([], WarningsWithConfigSet), + + %% Write alternative configuration file + WarningsConfig2 = + {warnings, [no_unknown]}, + ok = file:write_file(HomeConfigFilename, + io_lib:format("~p.~n~p.~n", [AppsConfig, WarningsConfig2])), + WarningsWithoutConfigSet = + dialyzer:run([{analysis_type, incremental}, + {files, [BeamFileWithImproperList]}, + {from, byte_code}]), + ?assertMatch([{warn_non_proper_list, _Loc, _Msg}], WarningsWithoutConfigSet) + end), + + peer:stop(Peer). + +paths_config_xdg(Config) -> + TestHome = filename:join(?config(priv_dir, Config), ?FUNCTION_NAME), + + %% We change the $HOME of the emulator to run this test + HomeEnv = + case os:type() of + {win32, _} -> + [Drive | Path] = filename:split(TestHome), + [{"APPDATA", filename:join(TestHome, "AppData")}, + {"HOMEDRIVE", Drive}, + {"HOMEPATH", filename:join(Path)}]; + _ -> + [{"HOME", TestHome}] + end, + + io:format("~p~n", [HomeEnv]), + + ExtraModulesDirOrig = + filename:join(?config(data_dir, Config), "extra_modules"), + ExtraModulesDir = + filename:join(?config(priv_dir, Config), "extra_modules"), + ok = filelib:ensure_path(ExtraModulesDir), + ok = filelib:ensure_path(filename:join(ExtraModulesDir,"ebin")), + ok = filelib:ensure_path(filename:join(ExtraModulesDir,"src")), + + {ok, _} = + file:copy( + filename:join([ExtraModulesDirOrig, "src", "extra_modules.app.src"]), + filename:join([ExtraModulesDir, "src", "extra_modules.app.src"]) + ), + {ok, _} = + file:copy( + filename:join([ExtraModulesDirOrig, "src", "extra_module.erl"]), + filename:join([ExtraModulesDir, "src", "extra_module.erl"]) + ), + + {ok, Peer, Node} = ?CT_PEER(#{ env => HomeEnv }), + {ok, _} = + compile:file( + filename:join([ExtraModulesDir,"src","extra_module.erl"]), + [{outdir, filename:join([ExtraModulesDir,"ebin"])}, debug_info] + ), + + AppsConfig = + {incremental, + {default_apps, + [stdlib, + kernel, + erts, + extra_modules + ] + }, + {default_warning_apps, + [extra_modules % Only on path if added explicitly via config below + ] + } + }, + + WarningsConfig = + {warnings, [no_unknown]}, + + erpc:call( + Node, + fun() -> + %% Find out the path of the config file + HomeConfigFilename = + filename:join(filename:basedir(user_config, "erlang"), + "dialyzer.config"), + io:format("~ts~n", [HomeConfigFilename]), + ok = filelib:ensure_dir(HomeConfigFilename), + + %% Write configuration file + PathConfig = {add_pathsa, [ExtraModulesDir, filename:join(ExtraModulesDir, "ebin"), filename:join(ExtraModulesDir, "src")]}, + ok = + file:write_file( + HomeConfigFilename, + io_lib:format( + "~p.~n~p.~n~p.~n", + [AppsConfig, WarningsConfig, PathConfig])), + + {Warnings, ModAnalyzed} = + % Will analyse apps from config, including the `extra_modules` app + % which contains a Dialyzer error + dialyzer:run_report_modules_analyzed([ + {analysis_type, incremental}, + {from, byte_code}]), + + % Check we did actually analyze the module + ?assert( + lists:member(extra_module, ModAnalyzed), + lists:flatten(io_lib:format("Looking for 'extra_module' in ~tp~n", [ModAnalyzed]))), + + % Check we got the warnings we expected from modules + % added to the path + ?assertMatch( + [ {warn_contract_types, {_,_}, {invalid_contract, [extra_module,f,1, {[1],true}, "(atom()) -> string()", "(integer()) -> nonempty_improper_list(integer(),3)"]}}, + {warn_non_proper_list, {_,_}, {improper_list_constr,["3"]}} + ], + Warnings) + end), + + peer:stop(Peer). + multiple_plts_unsupported_in_incremental_mode(Config) -> PrivDir = proplists:get_value(priv_dir, Config), BazPltFile = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME) ++ "-baz.iplt"), diff --git a/lib/dialyzer/test/incremental_SUITE_data/extra_modules/ebin/.gitignore b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/ebin/.gitignore new file mode 100644 index 0000000000..9aedd49be8 --- /dev/null +++ b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/ebin/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file, to force the directory to stick around +# for the tests to later make use of +!.gitignore diff --git a/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_module.erl b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_module.erl new file mode 100644 index 0000000000..21bb42ee61 --- /dev/null +++ b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_module.erl @@ -0,0 +1,14 @@ +-module(extra_module). + +-export([start/2,stop/1,f/1]). + +start(StartType, StartArgs) -> + error. + +stop(State) -> + error. + +% Purposely broken to generate a warning if the module is loaded and analysed +-spec f(atom()) -> string(). +f(N) when is_integer(N) -> + [N + 1|3]. diff --git a/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_modules.app.src b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_modules.app.src new file mode 100644 index 0000000000..01b38e4098 --- /dev/null +++ b/lib/dialyzer/test/incremental_SUITE_data/extra_modules/src/extra_modules.app.src @@ -0,0 +1,8 @@ +{application, extra_modules, + [{description, "An app with some extra modules"}, + {vsn, "1"}, + {modules, [extra_module]}, + {registered, []}, + {applications, [kernel, stdlib]}, + {mod, {extra_module,[]}} + ]}. diff --git a/lib/dialyzer/test/small_SUITE_data/results/bs_segments b/lib/dialyzer/test/small_SUITE_data/results/bs_segments new file mode 100644 index 0000000000..0c3c9a0717 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/bs_segments @@ -0,0 +1,3 @@ + +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/results/gh_7153 b/lib/dialyzer/test/small_SUITE_data/results/gh_7153 new file mode 100644 index 0000000000..c596a89f82 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/gh_7153 @@ -0,0 +1,3 @@ + +gh_7153.erl:4:1: Function t/1 has no local return +gh_7153.erl:5:7: Binary construction will fail since the value field X in segment X/utf8 has type '原子' diff --git a/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl b/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl new file mode 100644 index 0000000000..b1b8a2e866 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/bs_segments.erl @@ -0,0 +1,7 @@ +-module(bs_segments). + +-export([t/1]). + +%% GH-7138: bogus segment sizes crashed the analysis. +t(<<_:undefined>>) -> + ok. diff --git a/lib/dialyzer/test/small_SUITE_data/src/gh_7153.erl b/lib/dialyzer/test/small_SUITE_data/src/gh_7153.erl new file mode 100644 index 0000000000..ef2ef3a25b --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/gh_7153.erl @@ -0,0 +1,5 @@ +-module(gh_7153). +-export([t/1]). + +t(X = '原子') -> + <<X/utf8>>. diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src index dca7ba72ef..4d6fedef61 100644 --- a/lib/diameter/src/diameter.appup.src +++ b/lib/diameter/src/diameter.appup.src @@ -69,8 +69,9 @@ {"2.2.4", [{restart_application, diameter}]}, %% 23.3.4 {"2.2.5", [{restart_application, diameter}]}, %% 24.3 {"2.2.6", [{restart_application, diameter}]}, %% 25.0 - {"2.2.7", [{restart_application, diameter}]} %% 25.1 - ], + {"2.2.7", [{restart_application, diameter}]}, %% 25.1 + {"2.3", [{restart_application, diameter}]} +], [ {"0.9", [{restart_application, diameter}]}, {"0.10", [{restart_application, diameter}]}, @@ -120,6 +121,7 @@ {"2.2.4", [{restart_application, diameter}]}, {"2.2.5", [{restart_application, diameter}]}, {"2.2.6", [{restart_application, diameter}]}, - {"2.2.7", [{restart_application, diameter}]} + {"2.2.7", [{restart_application, diameter}]}, + {"2.3", [{restart_application, diameter}]} ] }. diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml index 0b5577fe2f..b97bdebd16 100644 --- a/lib/eldap/doc/src/eldap.xml +++ b/lib/eldap/doc/src/eldap.xml @@ -549,7 +549,7 @@ Control2 = eldap:paged_result_control(PageSize, Cookie1), </desc> </func> <func> - <name since="OTP @OTP-18480@">info(Handle) -> connection_info()</name> + <name since="OTP 25.3.1">info(Handle) -> connection_info()</name> <fsummary>Returns information about the LDAP connection. </fsummary> <type> diff --git a/lib/eldap/doc/src/notes.xml b/lib/eldap/doc/src/notes.xml index 563f75e827..881c1215b4 100644 --- a/lib/eldap/doc/src/notes.xml +++ b/lib/eldap/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the Eldap application.</p> +<section><title>Eldap 1.2.11</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added a new function eldap:info/1 that returns the socket + and the transport protocol for the eldap connection.</p> + <p> + Own Id: OTP-18480</p> + </item> + </list> + </section> + +</section> + <section><title>Eldap 1.2.10</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk index 77d89248c9..a25f97cb89 100644 --- a/lib/eldap/vsn.mk +++ b/lib/eldap/vsn.mk @@ -1 +1 @@ -ELDAP_VSN = 1.2.10 +ELDAP_VSN = 1.2.11 diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index a1bb84f224..7bac4913ab 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 5.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed configure tests for a few ARM-specific + instructions, which prevented the emulator from being + built on some platforms.</p> + <p> + Own Id: OTP-18554</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 5.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index badd74c6da..683e6643c7 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 5.3.1 +EI_VSN = 5.3.2 ERL_INTERFACE_VSN = $(EI_VSN) diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 9b234c37f1..a10ee19030 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,33 @@ <file>notes.xml</file> </header> - <section><title>Inets 8.3</title> + <section><title>Inets 8.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Correct timing related pipelining/keepalive queue bug, + that could result in unexpected "socket_remotly_closed" + errors.</p> + <p> + Own Id: OTP-18509 Aux Id: OTP-18476 </p> + </item> + <item> + <p> + With this change, upon remote socket closure current + request is added to a retried queue (either pipeline or + keep_alive, but not both).</p> + <p> + Own Id: OTP-18545 Aux Id: OTP-18509, ERIERL-937, + ERIERL-928 </p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 8.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 99285501c5..78efa696d8 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 8.3 +INETS_VSN = 8.3.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/kernel/Makefile b/lib/kernel/Makefile index 534b564c2c..7586a4c981 100644 --- a/lib/kernel/Makefile +++ b/lib/kernel/Makefile @@ -35,7 +35,7 @@ SPECIAL_TARGETS = # ---------------------------------------------------- include $(ERL_TOP)/make/otp_subdir.mk -DIA_PLT_APPS=crypto +DIA_PLT_APPS=crypto compiler TEST_NEEDS_RELEASE=true include $(ERL_TOP)/make/app_targets.mk diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml index 1bc90f1e8b..ffa77641de 100644 --- a/lib/kernel/doc/src/code.xml +++ b/lib/kernel/doc/src/code.xml @@ -427,7 +427,7 @@ zip:create("mnesia-4.4.7.ez", </func> <func> <name name="add_pathsa" arity="1" since=""/> - <name name="add_pathsa" arity="2" since=""/> + <name name="add_pathsa" arity="2" since="OTP @OTP-18466@"/> <fsummary>Add directories to the beginning of the code path.</fsummary> <desc> <p>Traverses <c><anno>Dirs</anno></c> and adds diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml index dc774538fb..dc6f9ba5bf 100644 --- a/lib/kernel/doc/src/disk_log.xml +++ b/lib/kernel/doc/src/disk_log.xml @@ -713,7 +713,7 @@ </desc> </func> <func> - <name name="next_file" arity="1" since=""/> + <name name="next_file" arity="1" since="OTP @OTP-18331@"/> <fsummary>Change to the next log file of a disk log.</fsummary> <type name="next_file_error_rsn"/> <type name="invalid_header"/> diff --git a/lib/kernel/doc/src/socket.xml b/lib/kernel/doc/src/socket.xml index e8e77b8295..2861108da6 100644 --- a/lib/kernel/doc/src/socket.xml +++ b/lib/kernel/doc/src/socket.xml @@ -148,69 +148,8 @@ <c>Info</c> will be <c>{SelectHandle, closed}</c>. </p> </note> - <marker id="asynchronous-call"/> <note> - <p>OLD NOTE</p> - <p>Select-based <i>asynchronous</i> message interface. </p> - <p> - Some functions allow for an <i>asynchronous</i> call. - This is achieved by setting the <c>Timeout</c> argument to - <c>nowait</c>. - For instance, if calling the - <seeerl marker="#recv-nowait"><c>recv/3</c></seeerl> - function with Timeout set to <c>nowait</c> - (<c>recv(Sock, 0, nowait)</c>) - when there is actually nothing to read, it will return with - <c>{select, </c> - <seetype marker="#select_info"><c>SelectInfo</c></seetype><c>}</c> - (<c>SelectInfo</c> contains the - <seetype marker="socket#select_handle">SelectHandle</seetype>). - When data eventually arrives a 'select' message - will be sent to the caller: - </p> - <taglist> - <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> - <tag></tag> - <item><c>{'$socket', socket(), select, SelectHandle}</c></item> - </taglist> - <p> - The caller can now call the <c>recv</c> function again - and probably expect data - (it is really up to the OS network protocol implementation). - </p> - <p> - Note that all other users are <em>locked out</em> until the - 'current user' has called the function (<c>recv</c> in this case) - and its return value shows that the operation has completed. - An operation can also be cancelled with - <seemfa marker="#cancel/2"><c>cancel/2</c></seemfa>. - </p> - <p> - Instead of <c>Timeout = nowait</c> it is equivalent to create a - <seetype marker="socket#select_handle"><c>SelectHandle</c></seetype>) - with - <seemfa marker="erts:erlang#make_ref/0"><c>make_ref()</c></seemfa> - and give as <c>Timeout</c>. - This will then be the <c>SelectHandle</c> in the 'select' message, - which enables a compiler optimization for receiving - a message containing a newly created <c>reference()</c> - (ignore the part of the message queue that had arrived - before the the <c>reference()</c> was created). - </p> - <p>Another message the user must be prepared for (when making asynchronous - calls) is the <c>abort</c> message:</p> - <taglist> - <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> - <tag></tag> - <item><c>{'$socket', socket(), abort, Info}</c></item> - </taglist> - <p>This message indicates - that the (asynchronous) operation has been aborted. - If, for instance, the socket has been closed (by another process), - <c>Info</c> will be <c>{SelectHandle, closed}</c>. </p> - </note> - <note> - <p>There is currently <em>no</em> support for Windows. </p> + <p>The Windows support has currently <em>pre-release</em> status. </p> <p>Support for IPv6 has been implemented but not <em>fully</em> tested. </p> <p>SCTP has only been partly implemented (and not tested). </p> @@ -1652,7 +1591,72 @@ <func> <name name="cancel" arity="2" clause_i="1" since="OTP 22.1"/> - <name name="cancel" arity="2" clause_i="2" since="OTP-18029"/> + <fsummary>Cancel an asynchronous request.</fsummary> + <desc> + <p>Cancel an asynchronous (select) request.</p> + <p> + Call this function in order to cancel a previous + asynchronous call to, e.g. + <seemfa marker="#recv/3"><c>recv/3</c></seemfa>. + </p> + <p> + An ongoing asynchronous operation blocks the socket + until the operation has been finished in good order, + or until it has been cancelled by this function. + </p> + <p> + Any other process that tries an operation + of the same basic type (accept / send / recv) will be + enqueued and notified with the regular <c>select</c> + mechanism for asynchronous operations + when the current operation and all enqueued before it + has been completed. + </p> + <p> + If <c><anno>SelectInfo</anno></c> does not match an + operation in progress for the calling process, + this function returns + <c>{error, {invalid, SelectInfo}}</c>. + </p> + </desc> + </func> + + <func> + <name name="cancel" arity="2" clause_i="2" since="OTP 26.0"/> + <fsummary>Cancel an asynchronous request.</fsummary> + <desc> + <p>Cancel an asynchronous (completion) request.</p> + <p> + Call this function in order to cancel a previous + asynchronous call to, e.g. + <seemfa marker="#recv/3"><c>recv/3</c></seemfa>. + </p> + <p> + An ongoing asynchronous operation blocks the socket + until the operation has been finished in good order, + or until it has been cancelled by this function. + </p> + <p> + Any other process that tries an operation + of the same basic type (accept / send / recv) will be + enqueued and notified with the regular <c>select</c> + mechanism for asynchronous operations + when the current operation and all enqueued before it + has been completed. + </p> + <p> + If <c><anno>CompletionInfo</anno></c> does not match an + operation in progress for the calling process, + this function returns + <c>{error, {invalid, CompletionInfo}}</c>. + </p> + </desc> + </func> + + <!-- + <func> + <name name="cancel" arity="2" clause_i="1" since="OTP 22.1"/> + <name name="cancel" arity="2" clause_i="2" since="OTP 26.0"/> <fsummary>Cancel an asynchronous request.</fsummary> <desc> <p>Cancel an asynchronous request.</p> @@ -1683,6 +1687,7 @@ </p> </desc> </func> + --> <func> <name name="close" arity="1" since="OTP 22.0"/> diff --git a/lib/kernel/src/gen_tcp_socket.erl b/lib/kernel/src/gen_tcp_socket.erl index 84ea036c3f..fb0f807cc1 100644 --- a/lib/kernel/src/gen_tcp_socket.erl +++ b/lib/kernel/src/gen_tcp_socket.erl @@ -729,8 +729,10 @@ socket_close(Socket) -> -compile({inline, [socket_cancel/2]}). socket_cancel(Socket, SelectInfo) -> case socket:cancel(Socket, SelectInfo) of - ok -> ok; - {error, closed} -> ok + ok -> ok; + {error, closed} -> ok; + {error, _} = ERROR -> ERROR + end. %%% ======================================================================== @@ -1575,7 +1577,7 @@ handle_event( info = SelectInfo, from = From, listen_socket = ListenSocket}, {P, D}) -> - socket_cancel(ListenSocket, SelectInfo), + _ = socket_cancel(ListenSocket, SelectInfo), {next_state, 'closed', {P, D}, [{reply, From, {error, timeout}}]}; handle_event(Type, Content, #accept{} = State, P_D) -> @@ -1661,7 +1663,7 @@ handle_event( {timeout, connect}, connect, #connect{info = SelectInfo, from = From}, {#params{socket = Socket} = _P, _D} = P_D) -> - socket_cancel(Socket, SelectInfo), + _ = socket_cancel(Socket, SelectInfo), _ = socket_close(Socket), {next_state, 'closed', P_D, [{reply, From, {error, timeout}}]}; @@ -2268,11 +2270,11 @@ cleanup_close_read(P, D, State, Reason) -> case State of #accept{ info = SelectInfo, from = From, listen_socket = ListenSocket} -> - socket_cancel(ListenSocket, SelectInfo), + _ = socket_cancel(ListenSocket, SelectInfo), {D, [{reply, From, {error, Reason}}]}; #connect{info = SelectInfo, from = From} -> - socket_cancel(P#params.socket, SelectInfo), + _ = socket_cancel(P#params.socket, SelectInfo), {D, [{reply, From, {error, Reason}}]}; _ -> @@ -2283,7 +2285,7 @@ cleanup_recv(P, D, State, Reason) -> %% ?DBG({P#params.socket, State, Reason}), case State of #recv{info = SelectInfo} -> - socket_cancel(P#params.socket, SelectInfo), + _ = socket_cancel(P#params.socket, SelectInfo), cleanup_recv_reply(P, D, [], Reason); _ -> cleanup_recv_reply(P, D, [], Reason) diff --git a/lib/kernel/src/socket.erl b/lib/kernel/src/socket.erl index 25be82543f..02e199d088 100644 --- a/lib/kernel/src/socket.erl +++ b/lib/kernel/src/socket.erl @@ -4548,6 +4548,7 @@ ioctl(Socket, SetRequest, Arg1, Arg2) -> Socket :: socket(), SelectInfo :: select_info(), Reason :: 'closed' | invalid(); + (Socket, CompletionInfo) -> 'ok' | {'error', Reason} when Socket :: socket(), CompletionInfo :: completion_info(), @@ -4590,14 +4591,10 @@ cancel(Socket, Info) -> erlang:error(badarg, [Socket, Info]). -%% What about completion? There is no way to cancel a -%% I/O completion "request" once it has been issued. -%% But we may still have "stuff" in our own queues, -%% which needs to be cleared out. cancel(SockRef, Op, Handle) -> case prim_socket:cancel(SockRef, Op, Handle) of select_sent -> - flush_select_msg(SockRef, Handle), + _ = flush_select_msg(SockRef, Handle), _ = flush_abort_msg(SockRef, Handle), ok; not_found -> @@ -4605,6 +4602,9 @@ cancel(SockRef, Op, Handle) -> _ = flush_abort_msg(SockRef, Handle), invalid; Result -> + %% Since we do not actually if we are using + %% select or completion here, so flush both... + _ = flush_select_msg(SockRef, Handle), _ = flush_completion_msg(SockRef, Handle), _ = flush_abort_msg(SockRef, Handle), Result diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 0aab4e4fa0..4aefee8a79 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -2639,6 +2639,10 @@ do_simple_sockaddr_send_recv(#{family := _Fam} = SockAddr, _) -> ?P("[server] send failed: ~p", [Reason1]), exit({skip, Reason1}); + {error, enetunreach = Reason1} -> + ?P("[server] send failed: ~p", + [Reason1]), + exit({skip, Reason1}); {error, Reason1} -> exit({send_failed, Reason1}) end @@ -2664,6 +2668,10 @@ do_simple_sockaddr_send_recv(#{family := _Fam} = SockAddr, _) -> ?P("[server] send failed: ~p", [Reason2]), exit({skip, Reason2}); + {error, enetunreach = Reason2} -> + ?P("[server] send failed: ~p", + [Reason2]), + exit({skip, Reason2}); {error, Reason2} -> exit({send_failed, Reason2}) end diff --git a/lib/kernel/test/socket_SUITE.erl b/lib/kernel/test/socket_SUITE.erl index 5f0fd15923..196af34521 100644 --- a/lib/kernel/test/socket_SUITE.erl +++ b/lib/kernel/test/socket_SUITE.erl @@ -744,8 +744,11 @@ -define(TPP_LARGE_NUM, 50). -define(TPP_NUM(Config, Base), (Base) div lookup(kernel_factor, 1, Config)). +-define(WINDOWS, {win32,nt}). + -define(TTEST_RUNTIME, ?SECS(1)). -define(TTEST_MIN_FACTOR, 3). +-define(TTEST_MIN_FACTOR_WIN, ?TTEST_MIN_FACTOR-1). -define(TTEST_DEFAULT_SMALL_MAX_OUTSTANDING, 50). -define(TTEST_DEFAULT_MEDIUM_MAX_OUTSTANDING, ?TTEST_MK_DEFAULT_MAX_OUTSTANDING( @@ -1404,7 +1407,12 @@ traffic_pp_sendmsg_recvmsg_cases() -> %% No point in running these cases unless the machine is %% reasonably fast. ttest_condition(Config) -> + OsType = os:type(), case ?config(kernel_factor, Config) of + Factor when (OsType =:= ?WINDOWS) andalso + is_integer(Factor) andalso + (Factor =< ?TTEST_MIN_FACTOR_WIN) -> + ok; Factor when is_integer(Factor) andalso (Factor =< ?TTEST_MIN_FACTOR) -> ok; Factor when is_integer(Factor) -> @@ -3492,7 +3500,10 @@ api_b_send_and_recv_seqpL(_Config) when is_list(_Config) -> api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> ?TT(?SECS(10)), tc_try(api_b_sendmsg_and_recvmsg_tcp4, - fun() -> has_support_ipv4() end, + fun() -> + is_not_windows(), + has_support_ipv4() + end, fun() -> Send = fun(Sock, Data) -> Msg = #{iov => [Data]}, @@ -6926,7 +6937,8 @@ api_a_connect_tcp(InitState) -> {ok, State#{asynch_tag => select, connect_tag => ST}}; - {completion, {completion_info, CT, CompletionRef}} + {completion, + {completion_info, CT, CompletionRef}} when SR =:= nowait -> ?SEV_IPRINT("completion nowait ->" "~n tag: ~p" @@ -6935,7 +6947,8 @@ api_a_connect_tcp(InitState) -> {ok, State#{asynch_tag => completion, connect_tag => CT, connect_ref => CompletionRef}}; - {completion, {completion_info, CT, CR}} + {completion, + {completion_info, CT, CR}} when is_reference(CR) -> ?SEV_IPRINT("completion ref ->" "~n tag: ~p" @@ -7988,7 +8001,10 @@ api_a_sendmsg_and_recvmsg_tcp4(Config) when is_list(Config) -> ?TT(?SECS(10)), Nowait = nowait(Config), tc_try(api_a_sendmsg_and_recvmsg_tcp4, - fun() -> has_support_ipv4() end, + fun() -> + is_not_windows(), + has_support_ipv4() + end, fun() -> Send = fun(Sock, Data) -> Msg = #{iov => [Data]}, @@ -9488,6 +9504,7 @@ api_a_recv_cancel_tcp(InitState) -> cmd => fun(#{tester := Tester} = _State) -> ?SEV_AWAIT_CONTINUE(Tester, tester, recv) end}, + #{desc => "try recv request (with nowait, expect select|completion)", cmd => fun(#{csock := Sock, recv := Recv, @@ -9506,13 +9523,15 @@ api_a_recv_cancel_tcp(InitState) -> "~n Ref: ~p", [T, Ref]), {ok, State#{recv_select_info => SI}}; - {completion, {completion_info, T, R} = CI} + {completion, + {completion_info, T, R} = CI} when Ref =:= nowait -> ?SEV_IPRINT("recv completion nowait: " "~n Tag: ~p" "~n Ref: ~p", [T, R]), {ok, State#{recv_completion_info => CI}}; - {completion, {completion_info, T, Ref} = CI} + {completion, + {completion_info, T, Ref} = CI} when is_reference(Ref) -> ?SEV_IPRINT("recv completion ref: " "~n Tag: ~p" @@ -10913,6 +10932,7 @@ api_a_mrecvmsg_cancel_tcp4(Config) when is_list(Config) -> Nowait = nowait(Config), tc_try(?FUNCTION_NAME, fun() -> + is_not_windows(), has_support_ipv4() end, fun() -> @@ -10937,7 +10957,10 @@ api_a_mrecvmsg_cancel_tcp6(Config) when is_list(Config) -> ?TT(?SECS(20)), Nowait = nowait(Config), tc_try(?FUNCTION_NAME, - fun() -> has_support_ipv6() end, + fun() -> + is_not_windows(), + has_support_ipv6() + end, fun() -> Recv = fun(Sock) -> socket:recvmsg(Sock, Nowait) @@ -14034,6 +14057,10 @@ api_opt_sock_broadcast() -> ?SEV_IPRINT("Expected Success: " "broadcast message sent"), ok; + {error, eaddrnotavail = Reason} -> + ?SEV_EPRINT("Unexpected Failure: ~p => SKIP", + [Reason]), + {skip, Reason}; {error, eacces = Reason} -> ?SEV_EPRINT("Unexpected Failure: ~p => SKIP", [Reason]), @@ -21126,6 +21153,37 @@ api_opt_ip_recvttl_udp(InitState) -> {skip, ?F("Cannot send with TTL: ~p", [Info])}; + {error, + {completion_status, + #{file := File, + function := Function, + line := Line, + raw_info := RawInfo, + info := invalid_parameter = Info}}} -> + %% IF we can't send it the test will not work + ?SEV_EPRINT("Cannot send TTL: " + "~p => SKIP: " + "~n File: ~s" + "~n Function: ~s" + "~n Line: ~p" + "~n Raw Info: ~p", + [Info, + File, Function, Line, + RawInfo]), + (catch socket:close(SSock)), + (catch socket:close(DSock)), + {skip, + ?F("Cannot send with TTL: ~p", [Info])}; + {error, {completion_status, + invalid_parameter = Info}} -> + %% IF we can't send it the test will not work + ?SEV_EPRINT("Cannot send TTL: " + "~p => SKIP", [Info]), + (catch socket:close(SSock)), + (catch socket:close(DSock)), + {skip, + ?F("Cannot send with TTL: ~p", [Info])}; + {error, _Reason} = ERROR -> ERROR end @@ -23420,7 +23478,7 @@ api_opt_ipv6_tclass_udp(InitState) -> #{desc => "send req (to dst) (w explicit tc = 1)", cmd => fun(#{sock_src := Sock, sa_dst := Dst, send := Send}) -> case Send(Sock, ?BASIC_REQ, Dst, 1) of - {error, + {error, {get_overlapped_result, #{file := File, function := Function, @@ -23449,6 +23507,35 @@ api_opt_ipv6_tclass_udp(InitState) -> {skip, ?F("Cannot send with TClass: ~p", [Info])}; + {error, + {completion_status, + #{file := File, + function := Function, + line := Line, + raw_info := RawInfo, + info := invalid_parameter = Info}}} -> + %% IF we can't send it the test will not work + ?SEV_EPRINT("Cannot send TClass: " + "~p => SKIP: " + "~n File: ~s" + "~n Function: ~s" + "~n Line: ~p" + "~n Raw Info: ~p", + [Info, + File, Function, Line, + RawInfo]), + (catch socket:close(Sock)), + {skip, + ?F("Cannot send with TClass: ~p", [Info])}; + {error, {completion_status, + invalid_parameter = Info}} -> + %% IF we can't send it the test will not work + ?SEV_EPRINT("Cannot send TClass: " + "~p => SKIP", [Info]), + (catch socket:close(Sock)), + {skip, + ?F("Cannot send with TClass: ~p", [Info])}; + Other -> Other end @@ -32985,8 +33072,11 @@ sc_lc_receive_response_udp(InitState) -> sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) -> ?TT(?SECS(10)), - tc_try(sc_lc_recvmsg_response_tcp4, - fun() -> has_support_ipv4() end, + tc_try(?FUNCTION_NAME, + fun() -> + is_not_windows(), + has_support_ipv4() + end, fun() -> Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet, @@ -33003,8 +33093,11 @@ sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) -> sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) -> ?TT(?SECS(10)), - tc_try(sc_recvmsg_response_tcp6, - fun() -> has_support_ipv6() end, + tc_try(?FUNCTION_NAME, + fun() -> + is_not_windows(), + has_support_ipv6() + end, fun() -> Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet6, @@ -36503,7 +36596,10 @@ traffic_send_and_recv_counters_tcpL(_Config) when is_list(_Config) -> traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) -> ?TT(?SECS(15)), tc_try(traffic_sendmsg_and_recvmsg_counters_tcp4, - fun() -> has_support_ipv4() end, + fun() -> + is_not_windows(), + has_support_ipv4() + end, fun() -> InitState = #{domain => inet, proto => tcp, @@ -36532,7 +36628,10 @@ traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) -> traffic_sendmsg_and_recvmsg_counters_tcp6(_Config) when is_list(_Config) -> ?TT(?SECS(15)), tc_try(traffic_sendmsg_and_recvmsg_counters_tcp6, - fun() -> has_support_ipv6() end, + fun() -> + is_not_windows(), + has_support_ipv6() + end, fun() -> InitState = #{domain => inet6, proto => tcp, @@ -48842,7 +48941,7 @@ otp16359_maccept_tcp(InitState) -> %% This test case is to verify that we do not leak monitors. otp18240_accept_mon_leak_tcp4(Config) when is_list(Config) -> - ?TT(?SECS(10)), + ?TT(?SECS(30)), tc_try(?FUNCTION_NAME, fun() -> has_support_ipv4() end, fun() -> @@ -48857,7 +48956,7 @@ otp18240_accept_mon_leak_tcp4(Config) when is_list(Config) -> %% This test case is to verify that we do not leak monitors. otp18240_accept_mon_leak_tcp6(Config) when is_list(Config) -> - ?TT(?SECS(10)), + ?TT(?SECS(30)), tc_try(?FUNCTION_NAME, fun() -> has_support_ipv6() end, fun() -> @@ -48883,26 +48982,42 @@ otp18240_accept_tcp(#{domain := Domain, otp18240_await_acceptor(Pid, Mon) -> receive - {'DOWN', Mon, process, Pid, Info} -> - i("acceptor terminated: " - "~n ~p", [Info]) + {'DOWN', Mon, process, Pid, ok} -> + i("acceptor successfully terminated"), + ok; + {'DOWN', Mon, process, Pid, {skip, _} = SKIP} -> + i("acceptor successfully terminated"), + exit(SKIP); + {'DOWN', Mon, process, Pid, Info} -> + i("acceptor unexpected termination: " + "~n ~p", [Info]), + exit({unexpected_result, Info}) after 5000 -> - i("acceptor info" + i("acceptor process (~p) info" "~n Refs: ~p" "~n Info: ~p", - [monitored_by(Pid), erlang:process_info(Pid)]), + [Pid, monitored_by(Pid), erlang:process_info(Pid)]), otp18240_await_acceptor(Pid, Mon) end. otp18240_acceptor(Parent, Domain, Proto, NumSocks) -> i("[acceptor] begin with: " + "~n Parent: ~p" "~n Domain: ~p" - "~n Protocol: ~p", [Domain, Proto]), + "~n Protocol: ~p", [Parent, Domain, Proto]), MonitoredBy0 = monitored_by(), - {ok, LSock} = socket:open(Domain, stream, Proto, - #{use_registry => false}), - ok = socket:bind(LSock, #{family => Domain, port => 0, addr => any}), + ?SLEEP(?SECS(5)), + Addr = case ?LIB:which_local_host_info(Domain) of + {ok, #{addr := A}} -> + A; + {error, Reason} -> + exit({skip, Reason}) + end, + {ok, LSock} = socket:open(Domain, stream, Proto, + #{use_registry => false}), + ok = socket:bind(LSock, #{family => Domain, addr => Addr, port => 0}), ok = socket:listen(LSock, NumSocks), + ?SLEEP(?SECS(5)), MonitoredBy1 = monitored_by(), i("[acceptor]: listen socket created" "~n 'Montored By' before listen socket: ~p" @@ -48922,7 +49037,7 @@ otp18240_acceptor(Parent, Domain, Proto, NumSocks) -> _Clients = [spawn_link(fun() -> otp18240_client(CID, Domain, Proto, - Port) + Addr, Port) end) || CID <- lists:seq(1, NumSocks)], i("[acceptor] accept ~w connections", [NumSocks]), @@ -48956,26 +49071,49 @@ otp18240_acceptor(Parent, Domain, Proto, NumSocks) -> end. -otp18240_client(ID, Domain, Proto, PortNo) -> +otp18240_client(ID, Domain, Proto, Addr, PortNo) -> i("[connector ~w] try create connector socket", [ID]), {ok, Sock} = socket:open(Domain, stream, Proto, #{use_registry => false}), - ok = socket:bind(Sock, #{family => Domain, port => 0, addr => any}), + ok = socket:bind(Sock, #{family => Domain, addr => Addr, port => 0}), %% ok = socket:setopt(Sock, otp, debug, true), i("[connector ~w] try connect", [ID]), - ok = socket:connect(Sock, #{family => Domain, addr => any, port => PortNo}), - i("[connector ~w] connected - now try recv", [ID]), - case socket:recv(Sock) of - {ok, Data} -> - i("[connector ~w] received unexpected data: " - "~n ~p", [ID, Data]), - (catch socket:close(Sock)), - exit('unexpected data'); - {error, closed} -> - i("[connector ~w] expected socket close", [ID]); - {error, Reason} -> - i("[connector ~w] unexpected error when reading: " - "~n ~p", [ID, Reason]), - (catch socket:close(Sock)) + case socket:connect(Sock, + #{family => Domain, addr => Addr, port => PortNo}) of + ok -> + i("[connector ~w] connected - now try recv", [ID]), + case socket:recv(Sock) of + {ok, Data} -> + i("[connector ~w] received unexpected data: " + "~n ~p", [ID, Data]), + (catch socket:close(Sock)), + exit('unexpected data'); + {error, closed} -> + i("[connector ~w] expected socket close", [ID]); + {error, Reason} -> + i("[connector ~w] unexpected error when reading: " + "~n ~p", [ID, Reason]), + (catch socket:close(Sock)) + end; + {error, {completion_status, #{info := invalid_netname = R} = Reason}} -> + i("[connector ~w] failed connecting: " + "~n ~p", [ID, Reason]), + (catch socket:close(Sock)), + exit({skip, R}); + {error, {completion_status, invalid_netname = Reason}} -> + i("[connector ~w] failed connecting: " + "~n ~p", [ID, Reason]), + (catch socket:close(Sock)), + exit({skip, Reason}); + {error, enetunreach = Reason} -> + i("[connector ~w] failed connecting: " + "~n ~p", [ID, Reason]), + (catch socket:close(Sock)), + exit({skip, Reason}); + + {error, Reason} -> + i("[connector ~w] failed connecting: " + "~n ~p", [ID, Reason]), + (catch socket:close(Sock)) end, i("[connector ~w] done", [ID]), ok. diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index cb4eb5985f..01cff8fa4b 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -34,7 +34,23 @@ </header> - <section><title>SNMP 5.13.4</title> + <section><title>SNMP 5.13.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Attempts to minimize the number of the error reports + during a failed agent init.</p> + <p> + Own Id: OTP-18422 Aux Id: ERIERL-873 </p> + </item> + </list> + </section> + +</section> + +<section><title>SNMP 5.13.4</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 4c11344234..13c7e9790e 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 5.13.4 +SNMP_VSN = 5.13.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 6ff15d429a..911055d742 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -27,6 +27,30 @@ </header> <p>This document describes the changes made to the SSL application.</p> +<section><title>SSL 10.9.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + With this change, ssl:connection_information/2 returns + correct keylog data after TLS1.3 key update.</p> + <p> + Own Id: OTP-18489</p> + </item> + <item> + <p> + Client signature algorithm list input order is now + honored again , it was accidently reversed by a previous + fix.</p> + <p> + Own Id: OTP-18550</p> + </item> + </list> + </section> + +</section> + <section><title>SSL 10.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index 7b821e2bc8..db6de41e50 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 10.9 +SSL_VSN = 10.9.1 diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index 403abf2be8..0906db1359 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 4.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The type specs in the <c>erl_parse</c> module has been + updated to include the <c>maybe</c> construct and the + <c>!</c> operator.</p> + <p> + Own Id: OTP-18506 Aux Id: GH-6956 </p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 4.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 0cb84fd3dc..13efc74d85 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -54,7 +54,9 @@ {<<"^4\\.1\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^4\\.1\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^4\\.2$">>,[restart_new_emulator]}, - {<<"^4\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], + {<<"^4\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^4\\.3$">>,[restart_new_emulator]}, + {<<"^4\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], [{<<"^3\\.13$">>,[restart_new_emulator]}, {<<"^3\\.13\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.13\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, @@ -81,4 +83,6 @@ {<<"^4\\.1\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^4\\.1\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^4\\.2$">>,[restart_new_emulator]}, - {<<"^4\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. + {<<"^4\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^4\\.3$">>,[restart_new_emulator]}, + {<<"^4\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index cd81d52182..d6706e69bf 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 4.3 +STDLIB_VSN = 4.3.1 diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl index 641f21eccd..eef715b83a 100644 --- a/lib/wx/api_gen/gl_gen.erl +++ b/lib/wx/api_gen/gl_gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2021. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl index 7c9f97867c..06fc6c9e58 100644 --- a/lib/wx/api_gen/gl_gen_erl.erl +++ b/lib/wx/api_gen/gl_gen_erl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/api_gen/gl_gen_nif.erl b/lib/wx/api_gen/gl_gen_nif.erl index b8a6be3908..a84bf454a5 100644 --- a/lib/wx/api_gen/gl_gen_nif.erl +++ b/lib/wx/api_gen/gl_gen_nif.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2021. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/api_gen/wx_gen_nif.erl b/lib/wx/api_gen/wx_gen_nif.erl index fa2fd52fe4..e768f483fe 100644 --- a/lib/wx/api_gen/wx_gen_nif.erl +++ b/lib/wx/api_gen/wx_gen_nif.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index 31bb522bc0..be9529d40c 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/c_src/egl_impl.c b/lib/wx/c_src/egl_impl.c index 84e1601a7f..868b32ab79 100644 --- a/lib/wx/c_src/egl_impl.c +++ b/lib/wx/c_src/egl_impl.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2011-2022. All Rights Reserved. + * Copyright Ericsson AB 2011-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/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp index 7ad6abb659..e2327cfb54 100644 --- a/lib/wx/c_src/wxe_gl.cpp +++ b/lib/wx/c_src/wxe_gl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2022. All Rights Reserved. + * Copyright Ericsson AB 2008-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/lib/wx/c_src/wxe_gl.h b/lib/wx/c_src/wxe_gl.h index 612432c22f..12aea9bb8c 100644 --- a/lib/wx/c_src/wxe_gl.h +++ b/lib/wx/c_src/wxe_gl.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2021. All Rights Reserved. + * Copyright Ericsson AB 2008-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/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 52e9757d2e..5ea1371524 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2022. All Rights Reserved. + * Copyright Ericsson AB 2008-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/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h index 45e80a77d1..a99c30a254 100644 --- a/lib/wx/c_src/wxe_impl.h +++ b/lib/wx/c_src/wxe_impl.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2022. All Rights Reserved. + * Copyright Ericsson AB 2008-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/lib/wx/c_src/wxe_nif.c b/lib/wx/c_src/wxe_nif.c index 6d9ed300ac..a7d3fea885 100644 --- a/lib/wx/c_src/wxe_nif.c +++ b/lib/wx/c_src/wxe_nif.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2017-2022. All Rights Reserved. + * Copyright Ericsson AB 2017-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/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp index 621e39f16b..8728dafcf9 100644 --- a/lib/wx/c_src/wxe_return.cpp +++ b/lib/wx/c_src/wxe_return.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2022. All Rights Reserved. + * Copyright Ericsson AB 2008-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/lib/wx/doc/src/gl.xml b/lib/wx/doc/src/gl.xml index 865ce91bb9..1f35f8fa89 100644 --- a/lib/wx/doc/src/gl.xml +++ b/lib/wx/doc/src/gl.xml @@ -7,7 +7,7 @@ <erlref> <header> <copyright> - <year>2020</year> + <year>2020</year><year>2023</year> <holder>Ericsson AB. All Rights Reserved.</holder></copyright> <legalnotice> Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index f155b7a551..08e339e097 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the wxErlang application.</p> +<section><title>Wx 2.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Improve debug prints from the nifs. Some minor fixes for + wxWidgets-3.2. Fixed OpenGL debug functions.</p> + <p> + Own Id: OTP-18512</p> + </item> + </list> + </section> + +</section> + <section><title>Wx 2.2.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl index dd6eb4f159..f0bb1e64e7 100644 --- a/lib/wx/src/wxe_master.erl +++ b/lib/wx/src/wxe_master.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/src/wxe_util.erl b/lib/wx/src/wxe_util.erl index 4f123ffc09..217e7118ff 100644 --- a/lib/wx/src/wxe_util.erl +++ b/lib/wx/src/wxe_util.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index 267ad4d336..5275defce6 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl index fa4e456c42..fb3e5ba598 100644 --- a/lib/wx/test/wx_opengl_SUITE.erl +++ b/lib/wx/test/wx_opengl_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2022. All Rights Reserved. +%% Copyright Ericsson AB 2008-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/lib/wx/vsn.mk b/lib/wx/vsn.mk index e7144bd6a2..78f0fd3395 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 2.2.1 +WX_VSN = 2.2.2 |