Improve internal link test and fix some link parsing issues.

This commit is contained in:
levlam 2023-03-02 18:03:24 +03:00
parent 2c86bc719b
commit 1fecd55d03
3 changed files with 90 additions and 57 deletions

View File

@ -1174,7 +1174,10 @@ unique_ptr<LinkManager::InternalLink> 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=<username>
return td::make_unique<InternalLinkPublicDialog>(std::move(username));
@ -1208,7 +1211,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
return td::make_unique<InternalLinkRestorePurchases>();
} 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=<referrer>
return td::make_unique<InternalLinkPremiumFeatures>(get_arg("ref"));
@ -1291,9 +1294,10 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
if (has_arg("server") && has_arg("port")) {
// proxy?server=<server>&port=<port>&secret=<secret>
auto port = to_integer<int32>(get_arg("port"));
if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) {
return td::make_unique<InternalLinkProxy>(get_arg("server"), port,
td_api::make_object<td_api::proxyTypeMtproto>(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<InternalLinkProxy>(
get_arg("server"), port, td_api::make_object<td_api::proxyTypeMtproto>(r_secret.ok().get_encoded_secret()));
} else {
return td::make_unique<InternalLinkUnsupportedProxy>();
}
@ -1445,9 +1449,10 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
if (has_arg("server") && has_arg("port")) {
// /proxy?server=<server>&port=<port>&secret=<secret>
auto port = to_integer<int32>(get_arg("port"));
if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) {
return td::make_unique<InternalLinkProxy>(get_arg("server"), port,
td_api::make_object<td_api::proxyTypeMtproto>(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<InternalLinkProxy>(
get_arg("server"), port, td_api::make_object<td_api::proxyTypeMtproto>(r_secret.ok().get_encoded_secret()));
} else {
return td::make_unique<InternalLinkUnsupportedProxy>();
}
@ -1459,6 +1464,9 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
// /bg/<hex_color>~<hex_color>~<hex_color>~<hex_color>
// /bg/<background_name>?mode=blur+motion
// /bg/<pattern_name>?intensity=...&bg_color=...&mode=blur+motion
if (BackgroundType::is_background_name_local(path[1])) {
return td::make_unique<InternalLinkBackground>(PSTRING() << url_encode(path[1]) << copy_arg("rotation"));
}
return td::make_unique<InternalLinkBackground>(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::InternalLink> LinkManager::get_internal_link_message_dra
}
unique_ptr<LinkManager::InternalLink> LinkManager::get_internal_link_passport(
Slice query, const vector<std::pair<string, string>> &args) {
Slice query, const vector<std::pair<string, string>> &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::InternalLink> 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<InternalLinkUnknownDeepLink>(PSTRING() << "tg://" << query);
}
return td::make_unique<InternalLinkPassportDataRequest>(bot_user_id, scope.str(), public_key.str(), nonce.str(),
@ -2072,7 +2083,7 @@ Result<string> 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<string> 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_

View File

@ -161,8 +161,8 @@ class LinkManager final : public Actor {
static unique_ptr<InternalLink> parse_t_me_link_query(Slice query, bool is_trusted);
static unique_ptr<InternalLink> get_internal_link_passport(Slice query,
const vector<std::pair<string, string>> &args);
static unique_ptr<InternalLink> get_internal_link_passport(Slice query, const vector<std::pair<string, string>> &args,
bool allow_unknown);
static unique_ptr<InternalLink> get_internal_link_message_draft(Slice url, Slice text);

View File

@ -81,13 +81,19 @@ TEST(Link, check_link) {
check_link("https://.", "");
}
static td::td_api::object_ptr<td::td_api::InternalLinkType> get_internal_link_type_object(
const td::unique_ptr<td::LinkManager::InternalLink> &link) {
auto object = link->get_internal_link_type_object();
if (object->get_id() == td::td_api::internalLinkTypeMessageDraft::ID) {
static_cast<td::td_api::internalLinkTypeMessageDraft *>(object.get())->text_->entities_.clear();
}
return object;
}
static void parse_internal_link(const td::string &url, td::td_api::object_ptr<td::td_api::InternalLinkType> 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<td::td_api::internalLinkTypeMessageDraft *>(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_ptr<td
}
auto new_result = td::LinkManager::parse_internal_link(r_link.ok());
ASSERT_TRUE(new_result != nullptr);
auto new_object = new_result->get_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_ptr<td
ASSERT_TRUE(new_result != nullptr);
// the object must be the same after 2 round of conversion
ASSERT_STREQ(to_string(new_object), to_string(new_result->get_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());