mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
Update SQL escaping
This commit is contained in:
parent
be2a9e35ae
commit
792f47b4bd
@ -43,6 +43,7 @@
|
|||||||
escape/1,
|
escape/1,
|
||||||
escape_like/1,
|
escape_like/1,
|
||||||
escape_like_arg/1,
|
escape_like_arg/1,
|
||||||
|
escape_like_arg_circumflex/1,
|
||||||
to_bool/1,
|
to_bool/1,
|
||||||
sqlite_db/1,
|
sqlite_db/1,
|
||||||
sqlite_file/1,
|
sqlite_file/1,
|
||||||
@ -200,6 +201,7 @@ escape_like(S) when is_binary(S) ->
|
|||||||
<< <<(escape_like(C))/binary>> || <<C>> <= S >>;
|
<< <<(escape_like(C))/binary>> || <<C>> <= S >>;
|
||||||
escape_like($%) -> <<"\\%">>;
|
escape_like($%) -> <<"\\%">>;
|
||||||
escape_like($_) -> <<"\\_">>;
|
escape_like($_) -> <<"\\_">>;
|
||||||
|
escape_like($\\) -> <<"\\\\\\\\">>;
|
||||||
escape_like(C) when is_integer(C), C >= 0, C =< 255 -> sql_queries:escape(C).
|
escape_like(C) when is_integer(C), C >= 0, C =< 255 -> sql_queries:escape(C).
|
||||||
|
|
||||||
escape_like_arg(S) when is_binary(S) ->
|
escape_like_arg(S) when is_binary(S) ->
|
||||||
@ -209,6 +211,13 @@ escape_like_arg($_) -> <<"\\_">>;
|
|||||||
escape_like_arg($\\) -> <<"\\\\">>;
|
escape_like_arg($\\) -> <<"\\\\">>;
|
||||||
escape_like_arg(C) when is_integer(C), C >= 0, C =< 255 -> <<C>>.
|
escape_like_arg(C) when is_integer(C), C >= 0, C =< 255 -> <<C>>.
|
||||||
|
|
||||||
|
escape_like_arg_circumflex(S) when is_binary(S) ->
|
||||||
|
<< <<(escape_like_arg_circumflex(C))/binary>> || <<C>> <= S >>;
|
||||||
|
escape_like_arg_circumflex($%) -> <<"^%">>;
|
||||||
|
escape_like_arg_circumflex($_) -> <<"^_">>;
|
||||||
|
escape_like_arg_circumflex($^) -> <<"^^">>;
|
||||||
|
escape_like_arg_circumflex(C) when is_integer(C), C >= 0, C =< 255 -> <<C>>.
|
||||||
|
|
||||||
to_bool(<<"t">>) -> true;
|
to_bool(<<"t">>) -> true;
|
||||||
to_bool(<<"true">>) -> true;
|
to_bool(<<"true">>) -> true;
|
||||||
to_bool(<<"1">>) -> true;
|
to_bool(<<"1">>) -> true;
|
||||||
@ -508,7 +517,7 @@ sql_query_internal(#sql_query{} = Query) ->
|
|||||||
odbc ->
|
odbc ->
|
||||||
generic_sql_query(Query);
|
generic_sql_query(Query);
|
||||||
mssql ->
|
mssql ->
|
||||||
generic_sql_query(Query);
|
mssql_sql_query(Query);
|
||||||
pgsql ->
|
pgsql ->
|
||||||
Key = {?PREPARE_KEY, Query#sql_query.hash},
|
Key = {?PREPARE_KEY, Query#sql_query.hash},
|
||||||
case get(Key) of
|
case get(Key) of
|
||||||
@ -534,7 +543,7 @@ sql_query_internal(#sql_query{} = Query) ->
|
|||||||
mysql ->
|
mysql ->
|
||||||
generic_sql_query(Query);
|
generic_sql_query(Query);
|
||||||
sqlite ->
|
sqlite ->
|
||||||
generic_sql_query(Query)
|
sqlite_sql_query(Query)
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
Class:Reason ->
|
Class:Reason ->
|
||||||
@ -623,6 +632,32 @@ generic_escape() ->
|
|||||||
end
|
end
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
sqlite_sql_query(SQLQuery) ->
|
||||||
|
sql_query_format_res(
|
||||||
|
sql_query_internal(sqlite_sql_query_format(SQLQuery)),
|
||||||
|
SQLQuery).
|
||||||
|
|
||||||
|
sqlite_sql_query_format(SQLQuery) ->
|
||||||
|
Args = (SQLQuery#sql_query.args)(sqlite_escape()),
|
||||||
|
(SQLQuery#sql_query.format_query)(Args).
|
||||||
|
|
||||||
|
sqlite_escape() ->
|
||||||
|
#sql_escape{string = fun(X) -> <<"'", (standard_escape(X))/binary, "'">> end,
|
||||||
|
integer = fun(X) -> integer_to_binary(X) end,
|
||||||
|
boolean = fun(true) -> <<"1">>;
|
||||||
|
(false) -> <<"0">>
|
||||||
|
end
|
||||||
|
}.
|
||||||
|
|
||||||
|
standard_escape(S) ->
|
||||||
|
<< <<(case Char of
|
||||||
|
$' -> << "''" >>;
|
||||||
|
_ -> << Char >>
|
||||||
|
end)/binary>> || <<Char>> <= S >>.
|
||||||
|
|
||||||
|
mssql_sql_query(SQLQuery) ->
|
||||||
|
sqlite_sql_query(SQLQuery).
|
||||||
|
|
||||||
pgsql_prepare(SQLQuery, State) ->
|
pgsql_prepare(SQLQuery, State) ->
|
||||||
Escape = #sql_escape{_ = fun(X) -> X end},
|
Escape = #sql_escape{_ = fun(X) -> X end},
|
||||||
N = length((SQLQuery#sql_query.args)(Escape)),
|
N = length((SQLQuery#sql_query.args)(Escape)),
|
||||||
|
@ -227,9 +227,11 @@ make_val(Match, Field, Val) ->
|
|||||||
Condition = case str:suffix(<<"*">>, Val) of
|
Condition = case str:suffix(<<"*">>, Val) of
|
||||||
true ->
|
true ->
|
||||||
Val1 = str:substr(Val, 1, byte_size(Val) - 1),
|
Val1 = str:substr(Val, 1, byte_size(Val) - 1),
|
||||||
SVal = <<(ejabberd_sql:escape_like(Val1))/binary,
|
SVal = <<(ejabberd_sql:escape(
|
||||||
|
ejabberd_sql:escape_like_arg_circumflex(
|
||||||
|
Val1)))/binary,
|
||||||
"%">>,
|
"%">>,
|
||||||
[Field, <<" LIKE '">>, SVal, <<"'">>];
|
[Field, <<" LIKE '">>, SVal, <<"' ESCAPE '^'">>];
|
||||||
_ ->
|
_ ->
|
||||||
SVal = ejabberd_sql:escape(Val),
|
SVal = ejabberd_sql:escape(Val),
|
||||||
[Field, <<" = '">>, SVal, <<"'">>]
|
[Field, <<" = '">>, SVal, <<"'">>]
|
||||||
|
@ -51,9 +51,11 @@
|
|||||||
get_entity_subscriptions_for_send_last/2, get_last_items/3]).
|
get_entity_subscriptions_for_send_last/2, get_last_items/3]).
|
||||||
|
|
||||||
-export([decode_jid/1, encode_jid/1,
|
-export([decode_jid/1, encode_jid/1,
|
||||||
|
encode_jid_like/1,
|
||||||
decode_affiliation/1, decode_subscriptions/1,
|
decode_affiliation/1, decode_subscriptions/1,
|
||||||
encode_affiliation/1, encode_subscriptions/1,
|
encode_affiliation/1, encode_subscriptions/1,
|
||||||
encode_host/1]).
|
encode_host/1,
|
||||||
|
encode_host_like/1]).
|
||||||
|
|
||||||
init(_Host, _ServerHost, _Opts) ->
|
init(_Host, _ServerHost, _Opts) ->
|
||||||
%%pubsub_subscription_sql:init(),
|
%%pubsub_subscription_sql:init(),
|
||||||
@ -350,11 +352,13 @@ get_entity_subscriptions(Host, Owner) ->
|
|||||||
H = encode_host(Host),
|
H = encode_host(Host),
|
||||||
SJ = encode_jid(SubKey),
|
SJ = encode_jid(SubKey),
|
||||||
GJ = encode_jid(GenKey),
|
GJ = encode_jid(GenKey),
|
||||||
|
GJLike = encode_jid_like(GenKey),
|
||||||
Query = case SubKey of
|
Query = case SubKey of
|
||||||
GenKey ->
|
GenKey ->
|
||||||
[<<"select node, type, i.nodeid, jid, subscriptions "
|
[<<"select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n "
|
"from pubsub_state i, pubsub_node n "
|
||||||
"where i.nodeid = n.nodeid and jid like '">>, GJ, <<"%' and host='">>, H, <<"';">>];
|
"where i.nodeid = n.nodeid and jid like '">>, GJLike,
|
||||||
|
<<"%' escape '^' and host='">>, H, <<"';">>];
|
||||||
_ ->
|
_ ->
|
||||||
[<<"select node, type, i.nodeid, jid, subscriptions "
|
[<<"select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n "
|
"from pubsub_state i, pubsub_node n "
|
||||||
@ -399,12 +403,14 @@ get_entity_subscriptions_for_send_last(Host, Owner) ->
|
|||||||
H = encode_host(Host),
|
H = encode_host(Host),
|
||||||
SJ = encode_jid(SubKey),
|
SJ = encode_jid(SubKey),
|
||||||
GJ = encode_jid(GenKey),
|
GJ = encode_jid(GenKey),
|
||||||
|
GJLike = encode_jid_like(GenKey),
|
||||||
Query = case SubKey of
|
Query = case SubKey of
|
||||||
GenKey ->
|
GenKey ->
|
||||||
[<<"select node, type, i.nodeid, jid, subscriptions "
|
[<<"select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n, pubsub_node_option o "
|
"from pubsub_state i, pubsub_node n, pubsub_node_option o "
|
||||||
"where i.nodeid = n.nodeid and n.nodeid = o.nodeid and name='send_last_published_item' "
|
"where i.nodeid = n.nodeid and n.nodeid = o.nodeid and name='send_last_published_item' "
|
||||||
"and val='on_sub_and_presence' and jid like '">>, GJ, <<"%' and host='">>, H, <<"';">>];
|
"and val='on_sub_and_presence' and jid like '">>, GJLike,
|
||||||
|
<<"%' escape '^' and host='">>, H, <<"';">>];
|
||||||
_ ->
|
_ ->
|
||||||
[<<"select node, type, i.nodeid, jid, subscriptions "
|
[<<"select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n, pubsub_node_option o "
|
"from pubsub_state i, pubsub_node n, pubsub_node_option o "
|
||||||
@ -568,8 +574,9 @@ get_states(Nidx) ->
|
|||||||
[<<"jid">>, <<"affiliation">>, <<"subscriptions">>], RItems} ->
|
[<<"jid">>, <<"affiliation">>, <<"subscriptions">>], RItems} ->
|
||||||
{result,
|
{result,
|
||||||
lists:map(fun ([SJID, Aff, Subs]) ->
|
lists:map(fun ([SJID, Aff, Subs]) ->
|
||||||
#pubsub_state{stateid = {decode_jid(SJID), Nidx},
|
JID = decode_jid(SJID),
|
||||||
items = itemids(Nidx, SJID),
|
#pubsub_state{stateid = {JID, Nidx},
|
||||||
|
items = itemids(Nidx, JID),
|
||||||
affiliation = decode_affiliation(Aff),
|
affiliation = decode_affiliation(Aff),
|
||||||
subscriptions = decode_subscriptions(Subs)}
|
subscriptions = decode_subscriptions(Subs)}
|
||||||
end,
|
end,
|
||||||
@ -899,13 +906,12 @@ first_in_list(Pred, [H | T]) ->
|
|||||||
_ -> first_in_list(Pred, T)
|
_ -> first_in_list(Pred, T)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
itemids(Nidx, {U, S, R}) ->
|
itemids(Nidx, {_U, _S, _R} = JID) ->
|
||||||
itemids(Nidx, encode_jid({U, S, R}));
|
SJID = encode_jid_like(JID),
|
||||||
itemids(Nidx, SJID) ->
|
|
||||||
case catch
|
case catch
|
||||||
ejabberd_sql:sql_query_t([<<"select itemid from pubsub_item where "
|
ejabberd_sql:sql_query_t([<<"select itemid from pubsub_item where "
|
||||||
"nodeid='">>, Nidx, <<"' and publisher like '">>, SJID,
|
"nodeid='">>, Nidx, <<"' and publisher like '">>, SJID,
|
||||||
<<"%' order by modification desc;">>])
|
<<"%' escape '^' order by modification desc;">>])
|
||||||
of
|
of
|
||||||
{selected, [<<"itemid">>], RItems} ->
|
{selected, [<<"itemid">>], RItems} ->
|
||||||
[ItemId || [ItemId] <- RItems];
|
[ItemId || [ItemId] <- RItems];
|
||||||
@ -1011,6 +1017,10 @@ decode_subscriptions(Subscriptions) ->
|
|||||||
encode_jid(JID) ->
|
encode_jid(JID) ->
|
||||||
ejabberd_sql:escape(jid:to_string(JID)).
|
ejabberd_sql:escape(jid:to_string(JID)).
|
||||||
|
|
||||||
|
-spec(encode_jid_like/1 :: (JID :: ljid()) -> binary()).
|
||||||
|
encode_jid_like(JID) ->
|
||||||
|
ejabberd_sql:escape(ejabberd_sql:escape_like_arg_circumflex(jid:to_string(JID))).
|
||||||
|
|
||||||
-spec(encode_host/1 ::
|
-spec(encode_host/1 ::
|
||||||
( Host :: host())
|
( Host :: host())
|
||||||
-> binary()
|
-> binary()
|
||||||
@ -1018,6 +1028,14 @@ encode_jid(JID) ->
|
|||||||
encode_host({_U, _S, _R} = LJID) -> encode_jid(LJID);
|
encode_host({_U, _S, _R} = LJID) -> encode_jid(LJID);
|
||||||
encode_host(Host) -> ejabberd_sql:escape(Host).
|
encode_host(Host) -> ejabberd_sql:escape(Host).
|
||||||
|
|
||||||
|
-spec(encode_host_like/1 ::
|
||||||
|
( Host :: host())
|
||||||
|
-> binary()
|
||||||
|
).
|
||||||
|
encode_host_like({_U, _S, _R} = LJID) -> encode_jid_like(LJID);
|
||||||
|
encode_host_like(Host) ->
|
||||||
|
ejabberd_sql:escape(ejabberd_sql:escape_like_arg_circumflex(Host)).
|
||||||
|
|
||||||
-spec(encode_affiliation/1 ::
|
-spec(encode_affiliation/1 ::
|
||||||
( Arg :: atom())
|
( Arg :: atom())
|
||||||
-> binary()
|
-> binary()
|
||||||
|
@ -114,20 +114,21 @@ set_affiliation(Nidx, Owner, Affiliation) ->
|
|||||||
get_entity_subscriptions(_Host, Owner) ->
|
get_entity_subscriptions(_Host, Owner) ->
|
||||||
SubKey = jid:tolower(Owner),
|
SubKey = jid:tolower(Owner),
|
||||||
GenKey = jid:remove_resource(SubKey),
|
GenKey = jid:remove_resource(SubKey),
|
||||||
Host = node_flat_sql:encode_host(element(2, SubKey)),
|
HostLike = node_flat_sql:encode_host_like(element(2, SubKey)),
|
||||||
SJ = node_flat_sql:encode_jid(SubKey),
|
SJ = node_flat_sql:encode_jid(SubKey),
|
||||||
GJ = node_flat_sql:encode_jid(GenKey),
|
GJ = node_flat_sql:encode_jid(GenKey),
|
||||||
|
GJLike = node_flat_sql:encode_jid_like(GenKey),
|
||||||
Query = case SubKey of
|
Query = case SubKey of
|
||||||
GenKey ->
|
GenKey ->
|
||||||
[<<"select host, node, type, i.nodeid, jid, "
|
[<<"select host, node, type, i.nodeid, jid, "
|
||||||
"subscriptions from pubsub_state i, pubsub_node n "
|
"subscriptions from pubsub_state i, pubsub_node n "
|
||||||
"where i.nodeid = n.nodeid and jid "
|
"where i.nodeid = n.nodeid and jid "
|
||||||
"like '">>, GJ, <<"%' and host like '%@">>, Host, <<"';">>];
|
"like '">>, GJLike, <<"%' escape '^' and host like '%@">>, HostLike, <<"' escape '^';">>];
|
||||||
_ ->
|
_ ->
|
||||||
[<<"select host, node, type, i.nodeid, jid, "
|
[<<"select host, node, type, i.nodeid, jid, "
|
||||||
"subscriptions from pubsub_state i, pubsub_node n "
|
"subscriptions from pubsub_state i, pubsub_node n "
|
||||||
"where i.nodeid = n.nodeid and jid "
|
"where i.nodeid = n.nodeid and jid "
|
||||||
"in ('">>, SJ, <<"', '">>, GJ, <<"') and host like '%@">>, Host, <<"';">>]
|
"in ('">>, SJ, <<"', '">>, GJ, <<"') and host like '%@">>, HostLike, <<"' escape '^';">>]
|
||||||
end,
|
end,
|
||||||
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
||||||
{selected,
|
{selected,
|
||||||
@ -149,9 +150,10 @@ get_entity_subscriptions(_Host, Owner) ->
|
|||||||
get_entity_subscriptions_for_send_last(_Host, Owner) ->
|
get_entity_subscriptions_for_send_last(_Host, Owner) ->
|
||||||
SubKey = jid:tolower(Owner),
|
SubKey = jid:tolower(Owner),
|
||||||
GenKey = jid:remove_resource(SubKey),
|
GenKey = jid:remove_resource(SubKey),
|
||||||
Host = node_flat_sql:encode_host(element(2, SubKey)),
|
HostLike = node_flat_sql:encode_host_like(element(2, SubKey)),
|
||||||
SJ = node_flat_sql:encode_jid(SubKey),
|
SJ = node_flat_sql:encode_jid(SubKey),
|
||||||
GJ = node_flat_sql:encode_jid(GenKey),
|
GJ = node_flat_sql:encode_jid(GenKey),
|
||||||
|
GJLike = node_flat_sql:encode_jid_like(GenKey),
|
||||||
Query = case SubKey of
|
Query = case SubKey of
|
||||||
GenKey ->
|
GenKey ->
|
||||||
[<<"select host, node, type, i.nodeid, jid, "
|
[<<"select host, node, type, i.nodeid, jid, "
|
||||||
@ -159,14 +161,14 @@ get_entity_subscriptions_for_send_last(_Host, Owner) ->
|
|||||||
"pubsub_node_option o where i.nodeid = n.nodeid "
|
"pubsub_node_option o where i.nodeid = n.nodeid "
|
||||||
"and n.nodeid = o.nodeid and name='send_last_published_item' and "
|
"and n.nodeid = o.nodeid and name='send_last_published_item' and "
|
||||||
"val='on_sub_and_presence' and jid like '">>,
|
"val='on_sub_and_presence' and jid like '">>,
|
||||||
GJ, <<"%' and host like '%@">>, Host, <<"';">>];
|
GJLike, <<"%' escape '^' and host like '%@">>, HostLike, <<"' escape '^';">>];
|
||||||
_ ->
|
_ ->
|
||||||
[<<"select host, node, type, i.nodeid, jid, "
|
[<<"select host, node, type, i.nodeid, jid, "
|
||||||
"subscriptions from pubsub_state i, pubsub_node n, "
|
"subscriptions from pubsub_state i, pubsub_node n, "
|
||||||
"pubsub_node_option o where i.nodeid = n.nodeid "
|
"pubsub_node_option o where i.nodeid = n.nodeid "
|
||||||
"and n.nodeid = o.nodeid and name='send_last_published_item' and "
|
"and n.nodeid = o.nodeid and name='send_last_published_item' and "
|
||||||
"val='on_sub_and_presence' and jid in ",
|
"val='on_sub_and_presence' and jid in ",
|
||||||
"('">>, SJ, <<"', '">>, GJ, <<"') and host like '%@">>, Host, <<"';">>]
|
"('">>, SJ, <<"', '">>, GJ, <<"') and host like '%@">>, HostLike, <<"' escape '^';">>]
|
||||||
end,
|
end,
|
||||||
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
||||||
{selected,
|
{selected,
|
||||||
|
@ -196,11 +196,11 @@ get_subnodes_tree(Host, Node, _From) ->
|
|||||||
|
|
||||||
get_subnodes_tree(Host, Node) ->
|
get_subnodes_tree(Host, Node) ->
|
||||||
H = node_flat_sql:encode_host(Host),
|
H = node_flat_sql:encode_host(Host),
|
||||||
N = ejabberd_sql:escape(Node),
|
N = ejabberd_sql:escape(ejabberd_sql:escape_like_arg_circumflex(Node)),
|
||||||
case catch
|
case catch
|
||||||
ejabberd_sql:sql_query_t([<<"select node, parent, type, nodeid from "
|
ejabberd_sql:sql_query_t([<<"select node, parent, type, nodeid from "
|
||||||
"pubsub_node where host='">>,
|
"pubsub_node where host='">>,
|
||||||
H, <<"' and node like '">>, N, <<"%';">>])
|
H, <<"' and node like '">>, N, <<"%' escape '^';">>])
|
||||||
of
|
of
|
||||||
{selected,
|
{selected,
|
||||||
[<<"node">>, <<"parent">>, <<"type">>, <<"nodeid">>], RItems} ->
|
[<<"node">>, <<"parent">>, <<"type">>, <<"nodeid">>], RItems} ->
|
||||||
@ -256,10 +256,10 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
|||||||
|
|
||||||
delete_node(Host, Node) ->
|
delete_node(Host, Node) ->
|
||||||
H = node_flat_sql:encode_host(Host),
|
H = node_flat_sql:encode_host(Host),
|
||||||
N = ejabberd_sql:escape(Node),
|
N = ejabberd_sql:escape(ejabberd_sql:escape_like_arg_circumflex(Node)),
|
||||||
Removed = get_subnodes_tree(Host, Node),
|
Removed = get_subnodes_tree(Host, Node),
|
||||||
catch ejabberd_sql:sql_query_t([<<"delete from pubsub_node where host='">>,
|
catch ejabberd_sql:sql_query_t([<<"delete from pubsub_node where host='">>,
|
||||||
H, <<"' and node like '">>, N, <<"%';">>]),
|
H, <<"' and node like '">>, N, <<"%' escape '^';">>]),
|
||||||
Removed.
|
Removed.
|
||||||
|
|
||||||
%% helpers
|
%% helpers
|
||||||
|
@ -231,12 +231,12 @@ list_users(LServer,
|
|||||||
[{prefix, Prefix}, {limit, Limit}, {offset, Offset}])
|
[{prefix, Prefix}, {limit, Limit}, {offset, Offset}])
|
||||||
when is_binary(Prefix) and is_integer(Limit) and
|
when is_binary(Prefix) and is_integer(Limit) and
|
||||||
is_integer(Offset) ->
|
is_integer(Offset) ->
|
||||||
SPrefix = ejabberd_sql:escape_like_arg(Prefix),
|
SPrefix = ejabberd_sql:escape_like_arg_circumflex(Prefix),
|
||||||
SPrefix2 = <<SPrefix/binary, $%>>,
|
SPrefix2 = <<SPrefix/binary, $%>>,
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query(
|
||||||
LServer,
|
LServer,
|
||||||
?SQL("select @(username)s from users "
|
?SQL("select @(username)s from users "
|
||||||
"where username like %(SPrefix2)s "
|
"where username like %(SPrefix2)s escape '^' "
|
||||||
"order by username "
|
"order by username "
|
||||||
"limit %(Limit)d offset %(Offset)d")).
|
"limit %(Limit)d offset %(Offset)d")).
|
||||||
|
|
||||||
@ -264,12 +264,12 @@ users_number(LServer) ->
|
|||||||
|
|
||||||
users_number(LServer, [{prefix, Prefix}])
|
users_number(LServer, [{prefix, Prefix}])
|
||||||
when is_binary(Prefix) ->
|
when is_binary(Prefix) ->
|
||||||
SPrefix = ejabberd_sql:escape_like_arg(Prefix),
|
SPrefix = ejabberd_sql:escape_like_arg_circumflex(Prefix),
|
||||||
SPrefix2 = <<SPrefix/binary, $%>>,
|
SPrefix2 = <<SPrefix/binary, $%>>,
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query(
|
||||||
LServer,
|
LServer,
|
||||||
?SQL("select @(count(*))d from users "
|
?SQL("select @(count(*))d from users "
|
||||||
"where username like %(SPrefix2)s"));
|
"where username like %(SPrefix2)s escape '^'"));
|
||||||
users_number(LServer, []) ->
|
users_number(LServer, []) ->
|
||||||
users_number(LServer).
|
users_number(LServer).
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ init_config(Config) ->
|
|||||||
{resource, <<"resource">>},
|
{resource, <<"resource">>},
|
||||||
{master_resource, <<"master_resource">>},
|
{master_resource, <<"master_resource">>},
|
||||||
{slave_resource, <<"slave_resource">>},
|
{slave_resource, <<"slave_resource">>},
|
||||||
{password, <<"password">>},
|
{password, <<"password!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>}
|
||||||
{backends, get_config_backends()}
|
{backends, get_config_backends()}
|
||||||
|Config].
|
|Config].
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user