diff options
-rw-r--r-- | OTP_VERSION | 2 | ||||
-rw-r--r-- | erts/doc/src/notes.xml | 21 | ||||
-rw-r--r-- | erts/emulator/drivers/unix/ttsl_drv.c | 76 | ||||
-rw-r--r-- | erts/vsn.mk | 2 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_gen.erl | 68 | ||||
-rw-r--r-- | lib/inets/doc/src/notes.xml | 36 | ||||
-rw-r--r-- | lib/inets/src/http_lib/http_uri.erl | 4 | ||||
-rw-r--r-- | lib/inets/src/inets_app/inets.appup.src | 4 | ||||
-rw-r--r-- | lib/inets/test/uri_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/inets/vsn.mk | 2 | ||||
-rw-r--r-- | lib/stdlib/src/edlin.erl | 8 | ||||
-rw-r--r-- | otp_versions.table | 1 |
12 files changed, 157 insertions, 71 deletions
diff --git a/OTP_VERSION b/OTP_VERSION index 0ffaf17a11..b09651c1d0 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -20.0.4 +20.0.5 diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index f6bc6e984b..139057adb7 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,27 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 9.0.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug in <c>binary_to_term</c> and + <c>binary_to_atom</c> that could cause VM crash. + Typically happens when the last character of an UTF8 + string is in the range 128 to 255, but truncated to only + one byte. Bug exists in <c>binary_to_term</c> since ERTS + version 5.10.2 (OTP_R16B01) and <c>binary_to_atom</c> + since ERTS version 9.0 (OTP-20.0).</p> + <p> + Own Id: OTP-14590 Aux Id: ERL-474 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 9.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index f3c1aa1c4a..2a508b02eb 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -936,10 +936,10 @@ static int put_chars(byte *s, int l) int n; n = insert_buf(s, l); + if (lpos > llen) + llen = lpos; if (n > 0) write_buf(lbuf + lpos - n, n); - if (lpos > llen) - llen = lpos; return TRUE; } @@ -1016,7 +1016,7 @@ static int del_chars(int n) outc(' '); move_left(1); } - move_cursor(llen + l, lpos); + move_cursor(llen + gcs, lpos); } else if (pos < lpos) { l = lpos - pos; /* Buffer characters */ @@ -1036,7 +1036,7 @@ static int del_chars(int n) outc(' '); move_left(1); } - move_cursor(llen + l, lpos); + move_cursor(llen + gcs, lpos); } return TRUE; } @@ -1095,6 +1095,7 @@ static int insert_buf(byte *s, int n) ch = 0; } while (lpos % 8); } else if (ch == '\e') { + DEBUGLOG(("insert_buf: ANSI Escape: \\e")); lbuf[lpos++] = (CONTROL_TAG | ((Uint32) ch)); } else if (ch == '\n' || ch == '\r') { write_buf(lbuf + buffpos, lpos - buffpos); @@ -1156,7 +1157,7 @@ static int write_buf(Uint32 *s, int n) --n; s++; } } else if (*s == (CONTROL_TAG | ((Uint32) '\e'))) { - outc('\e'); + outc(lastput = '\e'); --n; ++s; } else if (*s & CONTROL_TAG) { @@ -1251,26 +1252,63 @@ static int move_cursor(int from_pos, int to_pos) return to_col-from_col; } -static int cp_pos_to_col(int cp_pos) +/* + * Returns the length of an ANSI escape code in a buffer, this function only consider + * color escape sequences like `\e[33m` or `\e[21;33m`. If a sequence has no valid + * terminator, the length is equal the number of characters between `\e` and the first + * invalid character, inclusive. + */ + +static int ansi_escape_width(Uint32 *s, int max_length) { -#ifdef HAVE_WCWIDTH int i; - int col = 0; - - for (i = 0; i < cp_pos; i++) { - int w = wcwidth(lbuf[i]); - if (w > 0) { - col += w; - } + + if (*s != (CONTROL_TAG | ((Uint32) '\e'))) { + return 0; + } else if (max_length <= 1) { + return 1; + } else if (s[1] != '[') { + return 2; } - return col; -#else + + for (i = 2; i < max_length && (s[i] == ';' || (s[i] >= '0' && s[i] <= '9')); i++); + + return i + 1; +} + +static int cp_pos_to_col(int cp_pos) +{ /* - * We dont' have any character width information. Assume that - * code points are one column wide. + * If we don't have any character width information. Assume that + * code points are one column wide */ - return cp_pos; + int w = 1; + int col = 0; + int i = 0; + int j; + + if (cp_pos > llen) { + col += cp_pos - llen; + cp_pos = llen; + } + + while (i < cp_pos) { + j = ansi_escape_width(lbuf + i, llen - i); + + if (j > 0) { + i += j; + } else { +#ifdef HAVE_WCWIDTH + w = wcwidth(lbuf[i]); #endif + if (w > 0) { + col += w; + } + i++; + } + } + + return col; } static int start_termcap(void) diff --git a/erts/vsn.mk b/erts/vsn.mk index 8ed3993177..c231c9c27d 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 9.0.4 +VSN = 9.0.5 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl index 6add06ea38..d3b9f704fe 100644 --- a/lib/diameter/src/base/diameter_gen.erl +++ b/lib/diameter/src/base/diameter_gen.erl @@ -471,9 +471,6 @@ field(_) -> %% AVP not in dictionary: try an alternate. -dec(_, _, 'AVP', _Mod, none, _, Avp) -> %% none decode is no-op - Avp; - dec(Data, Name, 'AVP', Mod, Fmt, Opts, Avp) -> dec_AVP(dicts(Mod, Opts), Data, Name, Mod, Fmt, Opts, Avp); @@ -596,13 +593,9 @@ dec_AVP([], _, _, _, _, _, _, _, Avp) -> %% A Grouped AVP is represented as a #diameter_avp{} list with AVP %% as head and component AVPs as tail. -set('Grouped', none, Avp, V) -> - {_Rec, As} = V, - [Avp | As]; - -set('Grouped', _, Avp, V) -> +set('Grouped', Fmt, Avp, V) -> {Rec, As} = V, - [Avp#diameter_avp{value = Rec} | As]; + [set(Fmt, Avp, Rec) | As]; set(_, _, Avp, V) -> Avp#diameter_avp{value = V}. @@ -611,15 +604,23 @@ set(_, _, Avp, V) -> %% %% Error when decoding a grouped AVP. -decode_error(true, none, _, Avp) -> - Avp; - -decode_error(true, _, {Rec, _, _}, Avp) -> - Avp#diameter_avp{value = Rec}; +%% Ignoring errors in Failed-AVP. +decode_error(true, Fmt, {Rec, ComponentAvps, _Errors}, Avp) -> + [set(Fmt, Avp, Rec) | ComponentAvps]; +%% Or not. A faulty component is encoded by itself in Failed-AVP, as +%% suggested by 7.5 of RFC 6733 (quoted below), so that errors are +%% reported unambigiously. decode_error(false, _, {_, ComponentAvps, [{RC,A} | _]}, Avp) -> {RC, [Avp | ComponentAvps], Avp#diameter_avp{data = [A]}}. +%% set/3 + +set(none, Avp, _Name) -> + Avp; +set(_, Avp, Rec) -> + Avp#diameter_avp{value = Rec}. + %% decode_error/6 %% %% Error when decoding a non-grouped AVP. @@ -633,7 +634,22 @@ decode_error(false, Reason, Name, Mod, Opts, Avp) -> ?MODULE, ?LINE, {Reason, Name, Avp#diameter_avp.name, Mod, Stack}), - rc(Reason, Avp, Opts, Mod). + case Reason of + {'DIAMETER', 5014 = RC, _} -> + %% Length error communicated from diameter_types or a + %% @custom_types/@codecs module. + AvpName = Avp#diameter_avp.name, + {RC, Avp#diameter_avp{data = Mod:empty_value(AvpName, Opts)}}; + _ -> + {5004, Avp} + end. + +%% 3588/6733: +%% +%% DIAMETER_INVALID_AVP_VALUE 5004 +%% The request contained an AVP with an invalid value in its data +%% portion. A Diameter message indicating this error MUST include +%% the offending AVPs within a Failed-AVP AVP. %% avp/6 @@ -789,22 +805,6 @@ avp_arity(Name, 'AVP' = AvpName, Mod, Opts, M) -> avp_arity(Name, AvpName, Mod, _, _) -> Mod:avp_arity(Name, AvpName). -%% rc/4 - -%% Length error communicated from diameter_types or a -%% @custom_types/@codecs module. -rc({'DIAMETER', 5014 = RC, _}, #diameter_avp{name = AvpName} = A, Opts, Mod) -> - {RC, A#diameter_avp{data = Mod:empty_value(AvpName, Opts)}}; - -%% 3588: -%% -%% DIAMETER_INVALID_AVP_VALUE 5004 -%% The request contained an AVP with an invalid value in its data -%% portion. A Diameter message indicating this error MUST include -%% the offending AVPs within a Failed-AVP AVP. -rc(_, Avp, _, _) -> - {5004, Avp}. - %% pack/5 pack(Arity, F, Avp, Mod, [Failed | Rec]) -> @@ -812,9 +812,9 @@ pack(Arity, F, Avp, Mod, [Failed | Rec]) -> %% set/5 -set(_, _, _, _, None) - when is_atom(None) -> - None; +set(_, _, _, _, Name) + when is_atom(Name) -> + Name; set(1, F, Value, _, Map) when is_map(Map) -> diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 2f4f20347a..c85600d0be 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,41 @@ <file>notes.xml</file> </header> - <section><title>Inets 6.4</title> + <section><title>Inets 6.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + http_uri aligned to follow RFC 3986 and not convert "+" + to space when decoding URIs.</p> + <p> + Own Id: OTP-14573</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added new option max_client_body_chunk to httpd server to + allow chunked delivery of PUT and POST data to mod_esi + callback. Note, new mod_esi callback implementation is + required.</p> + <p> + Also correct value provided by server_name environment + variable</p> + <p> + Own Id: OTP-14450</p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 6.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index c4be5abd7c..7f1ca02014 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -117,8 +117,6 @@ decode(String) when is_list(String) -> decode(String) when is_binary(String) -> do_decode_binary(String). -do_decode([$+|Rest]) -> - [$ |do_decode(Rest)]; do_decode([$%,Hex1,Hex2|Rest]) -> [hex2dec(Hex1)*16+hex2dec(Hex2)|do_decode(Rest)]; do_decode([First|Rest]) -> @@ -126,8 +124,6 @@ do_decode([First|Rest]) -> do_decode([]) -> []. -do_decode_binary(<<$+, Rest/bits>>) -> - <<$ , (do_decode_binary(Rest))/binary>>; do_decode_binary(<<$%, Hex:2/binary, Rest/bits>>) -> <<(binary_to_integer(Hex, 16)), (do_decode_binary(Rest))/binary>>; do_decode_binary(<<First:1/binary, Rest/bits>>) -> diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index f9ad8709d9..a86413147c 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,14 +18,10 @@ %% %CopyrightEnd% {"%VSN%", [ - {<<"6.2.4">>, [{load_module, httpd_request_handler, - soft_purge, soft_purge, []}]}, {<<"6\\..*">>,[{restart_application, inets}]}, {<<"5\\..*">>,[{restart_application, inets}]} ], [ - {<<"6.2.4">>, [{load_module, httpd_request_handler, - soft_purge, soft_purge, []}]}, {<<"6\\..*">>,[{restart_application, inets}]}, {<<"5\\..*">>,[{restart_application, inets}]} ] diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl index 3e7799141c..f973296af6 100644 --- a/lib/inets/test/uri_SUITE.erl +++ b/lib/inets/test/uri_SUITE.erl @@ -277,8 +277,8 @@ encode_decode(Config) when is_list(Config) -> ?assertEqual("foo%20bar", http_uri:encode("foo bar")), ?assertEqual(<<"foo%20bar">>, http_uri:encode(<<"foo bar">>)), - ?assertEqual("foo bar", http_uri:decode("foo+bar")), - ?assertEqual(<<"foo bar">>, http_uri:decode(<<"foo+bar">>)), + ?assertEqual("foo+bar", http_uri:decode("foo+bar")), + ?assertEqual(<<"foo+bar">>, http_uri:decode(<<"foo+bar">>)), ?assertEqual("foo bar", http_uri:decode("foo%20bar")), ?assertEqual(<<"foo bar">>, http_uri:decode(<<"foo%20bar">>)), ?assertEqual("foo\r\n", http_uri:decode("foo%0D%0A")), diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 96796f11c0..c4314f1ab5 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 6.4 +INETS_VSN = 6.4.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl index 64d5a71f3c..5df9c504f9 100644 --- a/lib/stdlib/src/edlin.erl +++ b/lib/stdlib/src/edlin.erl @@ -412,12 +412,12 @@ do_op(backward_word, Bef0, Aft0, Rs) -> {Bef1,Aft1,N0} = over_non_word(Bef0, Aft0, 0), {Bef,Aft,N} = over_word(Bef1, Aft1, N0), {{Bef,Aft},[{move_rel,-N}|Rs]}; -do_op(beginning_of_line, [C|Bef], Aft, Rs) -> - {{[],reverse(Bef, [C|Aft])},[{move_rel,-(cp_len(Bef)+1)}|Rs]}; +do_op(beginning_of_line, [_|_]=Bef, Aft, Rs) -> + {{[],reverse(Bef, Aft)},[{move_rel,-(cp_len(Bef))}|Rs]}; do_op(beginning_of_line, [], Aft, Rs) -> {{[],Aft},Rs}; -do_op(end_of_line, Bef, [C|Aft], Rs) -> - {{reverse(Aft, [C|Bef]),[]},[{move_rel,cp_len(Aft)+1}|Rs]}; +do_op(end_of_line, Bef, [_|_]=Aft, Rs) -> + {{reverse(Aft, Bef),[]},[{move_rel,cp_len(Aft)}|Rs]}; do_op(end_of_line, Bef, [], Rs) -> {{Bef,[]},Rs}; do_op(ctlu, Bef, Aft, Rs) -> diff --git a/otp_versions.table b/otp_versions.table index 3c6474bf4d..b6527594da 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-20.0.5 : erts-9.0.5 inets-6.4.1 # asn1-5.0.2 common_test-1.15.1 compiler-7.1.1 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.0 debugger-4.2.2 dialyzer-3.2.1 diameter-2.0 edoc-0.9 eldap-1.2.2 erl_docgen-0.7 erl_interface-3.10 et-1.6 eunit-2.3.3 hipe-3.16 ic-4.4.2 jinterface-1.8 kernel-5.3.1 megaco-3.18.2 mnesia-4.15 observer-2.4 odbc-2.12 orber-3.8.3 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12.1 sasl-3.0.4 snmp-5.2.6 ssh-4.5.1 ssl-8.2 stdlib-3.4.1 syntax_tools-2.1.2 tools-2.10.1 wx-1.8.1 xmerl-1.3.15 : OTP-20.0.4 : dialyzer-3.2.1 erts-9.0.4 # asn1-5.0.2 common_test-1.15.1 compiler-7.1.1 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.0 debugger-4.2.2 diameter-2.0 edoc-0.9 eldap-1.2.2 erl_docgen-0.7 erl_interface-3.10 et-1.6 eunit-2.3.3 hipe-3.16 ic-4.4.2 inets-6.4 jinterface-1.8 kernel-5.3.1 megaco-3.18.2 mnesia-4.15 observer-2.4 odbc-2.12 orber-3.8.3 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12.1 sasl-3.0.4 snmp-5.2.6 ssh-4.5.1 ssl-8.2 stdlib-3.4.1 syntax_tools-2.1.2 tools-2.10.1 wx-1.8.1 xmerl-1.3.15 : OTP-20.0.3 : asn1-5.0.2 compiler-7.1.1 erts-9.0.3 ssh-4.5.1 # common_test-1.15.1 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.0 debugger-4.2.2 dialyzer-3.2 diameter-2.0 edoc-0.9 eldap-1.2.2 erl_docgen-0.7 erl_interface-3.10 et-1.6 eunit-2.3.3 hipe-3.16 ic-4.4.2 inets-6.4 jinterface-1.8 kernel-5.3.1 megaco-3.18.2 mnesia-4.15 observer-2.4 odbc-2.12 orber-3.8.3 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12.1 sasl-3.0.4 snmp-5.2.6 ssl-8.2 stdlib-3.4.1 syntax_tools-2.1.2 tools-2.10.1 wx-1.8.1 xmerl-1.3.15 : OTP-20.0.2 : asn1-5.0.1 erts-9.0.2 kernel-5.3.1 # common_test-1.15.1 compiler-7.1 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.0 debugger-4.2.2 dialyzer-3.2 diameter-2.0 edoc-0.9 eldap-1.2.2 erl_docgen-0.7 erl_interface-3.10 et-1.6 eunit-2.3.3 hipe-3.16 ic-4.4.2 inets-6.4 jinterface-1.8 megaco-3.18.2 mnesia-4.15 observer-2.4 odbc-2.12 orber-3.8.3 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12.1 sasl-3.0.4 snmp-5.2.6 ssh-4.5 ssl-8.2 stdlib-3.4.1 syntax_tools-2.1.2 tools-2.10.1 wx-1.8.1 xmerl-1.3.15 : |