aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_validator.erl6
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl38
-rw-r--r--lib/kernel/test/zlib_SUITE.erl23
-rw-r--r--lib/ssh/src/ssh_transport.erl21
4 files changed, 75 insertions, 13 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 00901077d3..be8908dd6b 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1430,13 +1430,13 @@ merge_types(bool, {atom,A}) ->
merge_bool(A);
merge_types({atom,A}, bool) ->
merge_bool(A);
-merge_types(#ms{id=Id1,valid=B0,slots=Slots},
- #ms{id=Id2,valid=B1,slots=Slots}) ->
+merge_types(#ms{id=Id1,valid=B1,slots=Slots1},
+ #ms{id=Id2,valid=B2,slots=Slots2}) ->
Id = if
Id1 =:= Id2 -> Id1;
true -> make_ref()
end,
- #ms{id=Id,valid=B0 band B1,slots=Slots};
+ #ms{id=Id,valid=B1 band B2,slots=min(Slots1, Slots2)};
merge_types(T1, T2) when T1 =/= T2 ->
%% Too different. All we know is that the type is a 'term'.
term.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 0ec05456ec..2fe8cd0cff 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -39,7 +39,7 @@
match_string_opt/1,select_on_integer/1,
map_and_binary/1,unsafe_branch_caching/1,
bad_literals/1,good_literals/1,constant_propagation/1,
- parse_xml/1,get_payload/1]).
+ parse_xml/1,get_payload/1,num_slots_different/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -71,7 +71,7 @@ groups() ->
match_string_opt,select_on_integer,
map_and_binary,unsafe_branch_caching,
bad_literals,good_literals,constant_propagation,parse_xml,
- get_payload]}].
+ get_payload,num_slots_different]}].
init_per_suite(Config) ->
@@ -1524,6 +1524,40 @@ do_get_payload(ExtHdr) ->
<<_:13,_:35>> = ExtHdr#ext_header.ext_hdr_opts,
ExtHdrOptions.
+%% ERL-490
+num_slots_different(_Config) ->
+ Ts = [{<<"de">>, <<"default">>, <<"Remove">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Remove from list">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Remove from the list">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Results">>, <<"Ergebnisse">>},
+ {<<"de">>, <<"default">>, <<"Reservatio">>, <<"a">>},
+ {<<"de">>, <<"navigation">>, <<"Results">>, <<"Ergebnisse">>},
+ {<<"de">>, <<"navigation">>, <<"Resources">>, <<"Ressourcen">>}],
+ _ = [{ok,Res} = lgettext(A, B, C) || {A,B,C,Res} <- Ts],
+
+ {'EXIT',_} = (catch lgettext(<<"d">>, <<"default">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext("", <<"default">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext(<<"de">>, <<"def">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext(<<"de">>, <<"default">>, <<"Res">>)),
+ ok.
+
+
+lgettext(<<"de">>, <<"default">>, <<"Remove">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Remove from list">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Remove from the list">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Results">>) ->
+ {ok, <<"Ergebnisse">>};
+lgettext(<<"de">>, <<"default">>, <<"Reservatio">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"navigation">>, <<"Results">>) ->
+ {ok, <<"Ergebnisse">>};
+lgettext(<<"de">>, <<"navigation">>, <<"Resources">>) ->
+ {ok, <<"Ressourcen">>}.
+
+
check(F, R) ->
R = F().
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index e246276262..d17eded811 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -276,10 +276,10 @@ api_inflateInit(Config) when is_list(Config) ->
?m(ok,zlib:close(Z12))
end, lists:seq(8,15)),
?m(?EXIT(badarg), zlib:inflateInit(gurka, -15)),
- ?m(?EXIT(already_initialized), zlib:inflateInit(Z1, 7)),
- ?m(?EXIT(already_initialized), zlib:inflateInit(Z1, -7)),
- ?m(?EXIT(already_initialized), zlib:inflateInit(Z1, 48)),
- ?m(?EXIT(already_initialized), zlib:inflateInit(Z1, -16)),
+ ?m(?EXIT(bad_windowbits), zlib:inflateInit(Z1, 7)),
+ ?m(?EXIT(bad_windowbits), zlib:inflateInit(Z1, -7)),
+ ?m(?EXIT(bad_windowbits), zlib:inflateInit(Z1, 48)),
+ ?m(?EXIT(bad_windowbits), zlib:inflateInit(Z1, -16)),
?m(ok, zlib:close(Z1)).
%% Test inflateSetDictionary.
@@ -416,6 +416,9 @@ api_inflateChunk(Config) when is_list(Config) ->
{more, Part1AsIOList} = zlib:inflateChunk(Z1, Compressed),
{more, Part2AsIOList} = zlib:inflateChunk(Z1),
{more, Part3AsIOList} = zlib:inflateChunk(Z1),
+
+ [] = zlib:inflateChunk(Z1),
+ [] = zlib:inflateChunk(Z1),
[] = zlib:inflateChunk(Z1),
?m(Part1, iolist_to_binary(Part1AsIOList)),
@@ -483,7 +486,8 @@ api_safeInflate(Config) when is_list(Config) ->
SafeInflateLoop(zlib:safeInflate(Z1, Compressed), []),
- ?m(?EXIT(data_error), zlib:safeInflate(Z1, Compressed)),
+ ?m({finished, []}, zlib:safeInflate(Z1, Compressed)),
+ ?m({finished, []}, zlib:safeInflate(Z1, Compressed)),
?m(ok, zlib:inflateReset(Z1)),
?m(?EXIT(badarg), zlib:safeInflate(gurka, Compressed)),
@@ -632,6 +636,7 @@ api_g_un_zip(Config) when is_list(Config) ->
?m(?EXIT(badarg),zlib:gzip(not_a_binary)),
Bin = <<1,11,1,23,45>>,
Comp = zlib:gzip(Bin),
+
?m(Comp, zlib:gzip(binary_to_list(Bin))),
?m(?EXIT(badarg), zlib:gunzip(not_a_binary)),
?m(?EXIT(data_error), zlib:gunzip(<<171,171,171,171,171>>)),
@@ -639,6 +644,14 @@ api_g_un_zip(Config) when is_list(Config) ->
?m(Bin, zlib:gunzip(Comp)),
?m(Bin, zlib:gunzip(binary_to_list(Comp))),
+ %% RFC 1952:
+ %%
+ %% "A gzip file consists of a series of "members" (compressed data
+ %% sets). [...] The members simply appear one after another in the file,
+ %% with no additional information before, between, or after them."
+ Concatenated = <<Bin/binary, Bin/binary>>,
+ ?m(Concatenated, zlib:gunzip([Comp, Comp])),
+
%% Bad CRC; bad length.
BadCrc = bad_crc_data(),
?m(?EXIT(data_error),(catch zlib:gunzip(BadCrc))),
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index c48c0800e4..0052347912 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -251,9 +251,9 @@ key_exchange_init_msg(Ssh0) ->
{SshPacket, Ssh} = ssh_packet(Msg, Ssh0),
{Msg, SshPacket, Ssh}.
-kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) ->
+kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs} = Ssh) ->
Random = ssh_bits:random(16),
- PrefAlgs = ?GET_OPT(preferred_algorithms, Opts),
+ PrefAlgs = adjust_algs_for_peer_version(Role, ?GET_OPT(preferred_algorithms, Opts), Ssh),
kexinit_message(Role, Random, PrefAlgs, HostKeyAlgs, Opts).
key_init(client, Ssh, Value) ->
@@ -261,7 +261,22 @@ key_init(client, Ssh, Value) ->
key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
-
+adjust_algs_for_peer_version(client, PrefAlgs, #ssh{s_version=V}) ->
+ adjust_algs_for_peer_version(V, PrefAlgs);
+adjust_algs_for_peer_version(server, PrefAlgs, #ssh{c_version=V}) ->
+ adjust_algs_for_peer_version(V, PrefAlgs).
+%%
+adjust_algs_for_peer_version("SSH-2.0-OpenSSH_6.2"++_, PrefAlgs) ->
+ C0 = proplists:get_value(cipher, PrefAlgs, same([])),
+ C = [{D,L} || D <- [client2server, server2client],
+ L <- [[K || K <- proplists:get_value(D, C0, []),
+ K =/= '[email protected]']]
+ ],
+ lists:keyreplace(cipher, 1, PrefAlgs, {cipher,C});
+adjust_algs_for_peer_version(_, PrefAlgs) ->
+ PrefAlgs.
+
kexinit_message(Role, Random, Algs, HostKeyAlgs, Opts) ->
#ssh_msg_kexinit{
cookie = Random,