Don't do double utf-8 conversion on translated strings in str:format

This caused garbled text in some places in webadmin when using language
that used characters > 128.

Thanks to chengshq for noticing this and providing preliminary patch.
This commit is contained in:
Paweł Chmielowski 2020-11-09 12:20:23 +01:00
parent 9ed2ca5079
commit 81e872c110
7 changed files with 24 additions and 18 deletions

View File

@ -930,7 +930,7 @@ user_info(User, Server, Query, Lang) ->
end;
_ -> translate:translate(Lang, ?T("Online"))
end,
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("User ~ts")),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("User ~ts"),
[us_to_list(US)])))]
++
case Res of
@ -1087,7 +1087,7 @@ get_node(global, Node, [], Query, Lang) ->
Base = get_base_path(global, Node, 2),
MenuItems2 = make_menu_items(global, Node, Base, Lang),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))]
(str:translate_and_format(Lang, ?T("Node ~p"), [Node])))]
++
case Res of
ok -> [?XREST(?T("Submitted"))];
@ -1109,7 +1109,7 @@ get_node(global, Node, [], Query, Lang) ->
get_node(Host, Node, [], _Query, Lang) ->
Base = get_base_path(Host, Node, 4),
MenuItems2 = make_menu_items(Host, Node, Base, Lang),
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Node ~p"), [Node]))),
?XE(<<"ul">>, MenuItems2)];
get_node(global, Node, [<<"db">>], Query, Lang) ->
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
@ -1165,7 +1165,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
end,
STables),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Database Tables at ~p")),
(str:translate_and_format(Lang, ?T("Database Tables at ~p"),
[Node]))
)]
++
@ -1203,7 +1203,7 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
[?XRES(<<(translate:translate(Lang, ?T("Error")))/binary, ": ",
((str:format("~p", [Error])))/binary>>)]
end,
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Backup of ~p")), [Node])))]
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Backup of ~p"), [Node])))]
++
ResS ++
[?XCT(<<"p">>,
@ -1357,7 +1357,7 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info,
[transaction_log_writes]),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Statistics of ~p")), [Node]))),
(str:translate_and_format(Lang, ?T("Statistics of ~p"), [Node]))),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
[?XE(<<"tr">>,
@ -1425,7 +1425,7 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
FmtLowLevelScript = (?XC(<<"pre">>,
(str:format("~p", [LowLevelScript])))),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Update ~p")), [Node])))]
(str:translate_and_format(Lang, ?T("Update ~p"), [Node])))]
++
case Res of
ok -> [?XREST(?T("Submitted"))];

View File

@ -663,7 +663,7 @@ get_outgoing_s2s(Host, Lang) ->
Host == FH orelse str:suffix(DotHost, FH)],
lists:map(
fun (T) ->
Name = str:format(tr(Lang, ?T("To ~ts")),[T]),
Name = str:translate_and_format(Lang, ?T("To ~ts"),[T]),
#disco_item{jid = jid:make(Host),
node = <<"outgoing s2s/", T/binary>>,
name = Name}
@ -675,7 +675,7 @@ get_outgoing_s2s(Host, Lang, To) ->
lists:map(
fun ({F, _T}) ->
Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
Name = str:format(tr(Lang, ?T("From ~ts")), [F]),
Name = str:translate_and_format(Lang, ?T("From ~ts"), [F]),
#disco_item{jid = jid:make(Host), node = Node, name = Name}
end,
lists:keysort(

View File

@ -1444,7 +1444,8 @@ get_error_text(#stanza_error{text = Txt}) ->
make_reason(Packet, From, StateData, Reason1) ->
#user{nick = FromNick} = maps:get(jid:tolower(From), StateData#state.users),
Condition = get_error_condition(xmpp:get_error(Packet)),
str:format(Reason1, [FromNick, Condition]).
Reason2 = unicode:characters_to_list(Reason1),
str:format(Reason2, [FromNick, Condition]).
-spec expulse_participant(stanza(), jid(), state(), binary()) ->
state().
@ -3493,8 +3494,8 @@ get_config(Lang, StateData, From) ->
DefaultRoomMaxUsers = get_default_room_maxusers(StateData),
Config = StateData#state.config,
MaxUsersRoom = get_max_users(StateData),
Title = str:format(
translate:translate(Lang, ?T("Configuration of room ~s")),
Title = str:translate_and_format(
Lang, ?T("Configuration of room ~s"),
[jid:encode(StateData#state.jid)]),
Fs = [{roomname, Config#config.title},
{roomdesc, Config#config.description},

View File

@ -988,7 +988,7 @@ user_queue(User, Server, Query, Lang) ->
end,
Hdrs = get_messages_subset(User, Server, HdrsAll),
FMsgs = format_user_queue(Hdrs),
PageTitle = str:format(translate:translate(Lang, ?T("~ts's Offline Messages Queue")), [us_to_list(US)]),
PageTitle = str:translate_and_format(Lang, ?T("~ts's Offline Messages Queue"), [us_to_list(US)]),
(?H1GL(PageTitle, <<"modules/#mod-offline">>, <<"mod_offline">>))
++ [?XREST(?T("Submitted"))] ++
[?XAE(<<"form">>,

View File

@ -222,8 +222,7 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ,
"with this server")),
URL = mod_register_opt:redirect_url(Server),
if (URL /= undefined) and not IsRegistered ->
Txt = translate:translate(Lang, ?T("To register, visit ~s")),
Desc = str:format(Txt, [URL]),
Desc = str:translate_and_format(Lang, ?T("To register, visit ~s"), [URL]),
xmpp:make_iq_result(
IQ, #register{instructions = Desc,
sub_els = [#oob_x{url = URL}]});

View File

@ -1053,7 +1053,7 @@ user_roster(User, Server, Query, Lang) ->
end,
SItems)))])]
end,
PageTitle = str:format(translate:translate(Lang, ?T("Roster of ~ts")), [us_to_list(US)]),
PageTitle = str:translate_and_format(Lang, ?T("Roster of ~ts"), [us_to_list(US)]),
(?H1GL(PageTitle, <<"modules/#mod-roster">>, <<"mod_roster">>))
++
case Res of

View File

@ -64,10 +64,11 @@
to_float/1,
prefix/2,
suffix/2,
format/2,
format/2,
to_integer/1,
sha/1,
to_hexlist/1]).
to_hexlist/1,
translate_and_format/3]).
%%%===================================================================
%%% API
@ -288,6 +289,11 @@ suffix(B1, B2) ->
format(Format, Args) ->
unicode:characters_to_binary(io_lib:format(Format, Args)).
-spec translate_and_format(binary(), binary(), list()) -> binary().
translate_and_format(Lang, Format, Args) ->
format(unicode:characters_to_list(translate:translate(Lang, Format)), Args).
-spec sha(iodata()) -> binary().