diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index f1a2a2b93..9fd06732a 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -1174,7 +1174,10 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que } if (username == "telegrampassport") { // resolve?domain=telegrampassport&bot_id=...&scope=...&public_key=...&nonce=...&callback_url=... - return get_internal_link_passport(query, url_query.args_); + auto passport_link = get_internal_link_passport(query, url_query.args_, false); + if (passport_link != nullptr) { + return std::move(passport_link); + } } // resolve?domain= return td::make_unique(std::move(username)); @@ -1208,7 +1211,7 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que return td::make_unique(); } else if (path.size() == 1 && path[0] == "passport") { // passport?bot_id=...&scope=...&public_key=...&nonce=...&callback_url=... - return get_internal_link_passport(query, url_query.args_); + return get_internal_link_passport(query, url_query.args_, true); } else if (path.size() == 1 && path[0] == "premium_offer") { // premium_offer?ref= return td::make_unique(get_arg("ref")); @@ -1291,9 +1294,10 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que if (has_arg("server") && has_arg("port")) { // proxy?server=&port=&secret= auto port = to_integer(get_arg("port")); - if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) { - return td::make_unique(get_arg("server"), port, - td_api::make_object(get_arg("secret"))); + auto r_secret = mtproto::ProxySecret::from_link(get_arg("secret")); + if (0 < port && port < 65536 && r_secret.is_ok()) { + return td::make_unique( + get_arg("server"), port, td_api::make_object(r_secret.ok().get_encoded_secret())); } else { return td::make_unique(); } @@ -1445,9 +1449,10 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q if (has_arg("server") && has_arg("port")) { // /proxy?server=&port=&secret= auto port = to_integer(get_arg("port")); - if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) { - return td::make_unique(get_arg("server"), port, - td_api::make_object(get_arg("secret"))); + auto r_secret = mtproto::ProxySecret::from_link(get_arg("secret")); + if (0 < port && port < 65536 && r_secret.is_ok()) { + return td::make_unique( + get_arg("server"), port, td_api::make_object(r_secret.ok().get_encoded_secret())); } else { return td::make_unique(); } @@ -1459,6 +1464,9 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /bg/~~~ // /bg/?mode=blur+motion // /bg/?intensity=...&bg_color=...&mode=blur+motion + if (BackgroundType::is_background_name_local(path[1])) { + return td::make_unique(PSTRING() << url_encode(path[1]) << copy_arg("rotation")); + } return td::make_unique(PSTRING() << url_encode(path[1]) << copy_arg("mode") << copy_arg("intensity") << copy_arg("bg_color") << copy_arg("rotation")); @@ -1591,7 +1599,7 @@ unique_ptr LinkManager::get_internal_link_message_dra } unique_ptr LinkManager::get_internal_link_passport( - Slice query, const vector> &args) { + Slice query, const vector> &args, bool allow_unknown) { auto get_arg = [&args](Slice key) { for (auto &arg : args) { if (arg.first == key) { @@ -1611,6 +1619,9 @@ unique_ptr LinkManager::get_internal_link_passport( auto callback_url = get_arg("callback_url"); if (!bot_user_id.is_valid() || scope.empty() || public_key.empty() || nonce.empty()) { + if (!allow_unknown) { + return nullptr; + } return td::make_unique(PSTRING() << "tg://" << query); } return td::make_unique(bot_user_id, scope.str(), public_key.str(), nonce.str(), @@ -2072,7 +2083,7 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } auto name = link->is_live_stream_ ? Slice("livestream") : Slice("videochat"); if (is_internal) { - return PSTRING() << "tg://resolve?domain=" << link->chat_username_ << '?' << name << invite_hash; + return PSTRING() << "tg://resolve?domain=" << link->chat_username_ << '&' << name << invite_hash; } else { return PSTRING() << get_t_me_url() << link->chat_username_ << '?' << name << invite_hash; } @@ -2090,7 +2101,7 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } string start_parameter; if (!link->start_parameter_.empty()) { - start_parameter = PSTRING() << (is_internal ? '&' : '?') << "startapp=" << url_encode(start_parameter); + start_parameter = PSTRING() << (is_internal ? '&' : '?') << "startapp=" << url_encode(link->start_parameter_); } if (is_internal) { return PSTRING() << "tg://resolve?domain=" << link->bot_username_ << "&appname=" << link->web_app_short_name_ diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 501622736..2f821231e 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -161,8 +161,8 @@ class LinkManager final : public Actor { static unique_ptr parse_t_me_link_query(Slice query, bool is_trusted); - static unique_ptr get_internal_link_passport(Slice query, - const vector> &args); + static unique_ptr get_internal_link_passport(Slice query, const vector> &args, + bool allow_unknown); static unique_ptr get_internal_link_message_draft(Slice url, Slice text); diff --git a/test/link.cpp b/test/link.cpp index 6032b9a81..7ee7b2174 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -81,13 +81,19 @@ TEST(Link, check_link) { check_link("https://.", ""); } +static td::td_api::object_ptr get_internal_link_type_object( + const td::unique_ptr &link) { + auto object = link->get_internal_link_type_object(); + if (object->get_id() == td::td_api::internalLinkTypeMessageDraft::ID) { + static_cast(object.get())->text_->entities_.clear(); + } + return object; +} + static void parse_internal_link(const td::string &url, td::td_api::object_ptr expected) { auto result = td::LinkManager::parse_internal_link(url); if (result != nullptr) { - auto object = result->get_internal_link_type_object(); - if (object->get_id() == td::td_api::internalLinkTypeMessageDraft::ID) { - static_cast(object.get())->text_->entities_.clear(); - } + auto object = get_internal_link_type_object(result); ASSERT_STREQ(url + ' ' + to_string(expected), url + ' ' + to_string(object)); for (auto is_internal : {true, false}) { @@ -117,7 +123,23 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptrget_internal_link_type_object(); + auto new_object = get_internal_link_type_object(new_result); + + auto new_object_str = to_string(new_object); + auto expected_str = to_string(expected); + if (expected->get_id() == td::td_api::internalLinkTypeBackground::ID) { + for (auto &c : expected_str) { + if (c == '~') { + // getInternalLink always use '-' + c = '-'; + } + } + if (new_object_str != expected_str && td::ends_with(expected_str, "\"\n}\n")) { + // getInternalLink always adds rotation parameter, because default value differs between apps + expected_str = expected_str.substr(0, expected_str.size() - 4) + "?rotation=0\"\n}\n"; + } + } + ASSERT_EQ(new_object_str, expected_str); r_link = td::LinkManager::get_internal_link(new_object, is_internal); ASSERT_TRUE(r_link.is_ok()); @@ -125,7 +147,7 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptrget_internal_link_type_object())); + ASSERT_STREQ(to_string(new_object), to_string(get_internal_link_type_object(new_result))); } } else { LOG_IF(ERROR, expected != nullptr) << url; @@ -452,16 +474,16 @@ TEST(Link, parse_internal_link) { background("111111-222222%20?rotation=180%20")); parse_internal_link("tg:bg?gradient=111111~222222", background("111111~222222")); parse_internal_link("tg:bg?gradient=abacaba", background("abacaba")); - parse_internal_link("tg:bg?slug=111111~222222#asdasd", background("111111~222222")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12&text=1", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12&mode=1", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=test&mode=12&rotation=4&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3&rotation=4")); - parse_internal_link("tg:bg?mode=12&&slug=test&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3")); - parse_internal_link("tg:bg?mode=12&intensity=2&bg_color=3", - unknown_deep_link("tg://bg?mode=12&intensity=2&bg_color=3")); + parse_internal_link("tg:bg?slug=test#asdasd", background("test")); + parse_internal_link("tg:bg?slug=test&mode=blur", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&text=1", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&mode=1", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&rotation=4&intensity=2&bg_color=3", + background("test?mode=blur&intensity=2&bg_color=3&rotation=4")); + parse_internal_link("tg:bg?mode=blur&&slug=test&intensity=2&bg_color=3", + background("test?mode=blur&intensity=2&bg_color=3")); + parse_internal_link("tg:bg?mode=blur&intensity=2&bg_color=3", + unknown_deep_link("tg://bg?mode=blur&intensity=2&bg_color=3")); parse_internal_link("tg:bg?color=111111#asdasd", background("111111")); parse_internal_link("tg:bg?color=11111%31", background("111111")); @@ -469,18 +491,18 @@ TEST(Link, parse_internal_link) { parse_internal_link("tg:bg?gradient=111111-222222", background("111111-222222")); parse_internal_link("tg:bg?rotation=180%20&gradient=111111-222222%20", background("111111-222222%20?rotation=180%20")); - parse_internal_link("tg:bg?gradient=111111~222222", background("111111~222222")); + parse_internal_link("tg:bg?gradient=111111~222222&mode=blur", background("111111~222222")); parse_internal_link("tg:bg?gradient=abacaba", background("abacaba")); - parse_internal_link("tg:bg?slug=111111~222222#asdasd", background("111111~222222")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12&text=1", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=111111~222222&mode=12&mode=1", background("111111~222222?mode=12")); - parse_internal_link("tg:bg?slug=test&mode=12&rotation=4&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3&rotation=4")); - parse_internal_link("tg:bg?mode=12&&slug=test&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3")); - parse_internal_link("tg:bg?mode=12&intensity=2&bg_color=3", - unknown_deep_link("tg://bg?mode=12&intensity=2&bg_color=3")); + parse_internal_link("tg:bg?slug=test#asdasd", background("test")); + parse_internal_link("tg:bg?slug=test&mode=blur", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&text=1", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&mode=1", background("test?mode=blur")); + parse_internal_link("tg:bg?slug=test&mode=blur&rotation=4&intensity=2&bg_color=3", + background("test?mode=blur&intensity=2&bg_color=3&rotation=4")); + parse_internal_link("tg:bg?mode=blur&&slug=test&intensity=2&bg_color=3", + background("test?mode=blur&intensity=2&bg_color=3")); + parse_internal_link("tg:bg?mode=blur&intensity=2&bg_color=3", + unknown_deep_link("tg://bg?mode=blur&intensity=2&bg_color=3")); parse_internal_link("%54.me/bg/111111#asdasd", background("111111")); parse_internal_link("t.me/bg/11111%31", background("111111")); @@ -491,13 +513,13 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/bg/abacaba", background("abacaba")); parse_internal_link("t.me/Bg/abacaba", web_app("Bg", "abacaba", "")); parse_internal_link("t.me/bg/111111~222222#asdasd", background("111111~222222")); - parse_internal_link("t.me/bg/111111~222222?mode=12", background("111111~222222?mode=12")); - parse_internal_link("t.me/bg/111111~222222?mode=12&text=1", background("111111~222222?mode=12")); - parse_internal_link("t.me/bg/111111~222222?mode=12&mode=1", background("111111~222222?mode=12")); - parse_internal_link("t.me/bg/test?mode=12&rotation=4&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3&rotation=4")); - parse_internal_link("t.me/%62g/test/?mode=12&&&intensity=2&bg_color=3", - background("test?mode=12&intensity=2&bg_color=3")); + parse_internal_link("t.me/bg/111111~222222?mode=blur", background("111111~222222")); + parse_internal_link("t.me/bg/111111~222222?mode=blur&text=1", background("111111~222222")); + parse_internal_link("t.me/bg/111111~222222?mode=blur&mode=1", background("111111~222222")); + parse_internal_link("t.me/bg/testteststststststststststststs?mode=blur&rotation=4&intensity=2&bg_color=3&mode=1", + background("testteststststststststststststs?mode=blur&intensity=2&bg_color=3&rotation=4")); + parse_internal_link("t.me/%62g/testteststststststststststststs/?mode=blur+motion&&&intensity=2&bg_color=3", + background("testteststststststststststststs?mode=blur%20motion&intensity=2&bg_color=3")); parse_internal_link("t.me/bg//", nullptr); parse_internal_link("t.me/bg/%20/", background("%20")); parse_internal_link("t.me/bg/", nullptr); @@ -758,9 +780,9 @@ TEST(Link, parse_internal_link) { parse_internal_link("tg://addtheme?slug=", unknown_deep_link("tg://addtheme?slug=")); parse_internal_link("t.me/proxy?server=1.2.3.4&port=80&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("t.me/proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("t.me/proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", unsupported_proxy()); parse_internal_link("t.me/proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", @@ -768,9 +790,9 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=", unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=12", unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("google.com", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF", - proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890abcdef")); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF", @@ -778,25 +800,25 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF0", unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF%30%30", - proxy_mtproto("google.com", 80, "ee1234567890abcdef1234567890ABCDEF00")); + proxy_mtproto("google.com", 80, "7hI0VniQq83vEjRWeJCrze8A")); parse_internal_link( "t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF010101010101010101", - proxy_mtproto("google.com", 80, "ee1234567890abcdef1234567890ABCDEF010101010101010101")); + proxy_mtproto("google.com", 80, "7hI0VniQq83vEjRWeJCrze8BAQEBAQEBAQE")); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=7tAAAAAAAAAAAAAAAAAAAAAAAAcuZ29vZ2xlLmNvbQ", proxy_mtproto("google.com", 80, "7tAAAAAAAAAAAAAAAAAAAAAAAAcuZ29vZ2xlLmNvbQ")); parse_internal_link("tg:proxy?server=1.2.3.4&port=80&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("tg:proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("tg:proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", unsupported_proxy()); parse_internal_link("tg:proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", unsupported_proxy()); parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF", - proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("google.com", 80, "1234567890abcdef1234567890abcdef")); parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF", - proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF")); + proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890abcdef")); parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", unsupported_proxy());