From da0161231562873a3d100651d9b9daddd833535a Mon Sep 17 00:00:00 2001 From: Slavasil Date: Tue, 15 Oct 2024 14:37:49 +0000 Subject: [PATCH] add basic URL validation for all modes --- CMakeLists.txt | 2 +- commands.cpp | 90 ++++++++++++++++++++++++++++---------------------- util.cpp | 7 ++++ util.h | 6 ++++ 4 files changed, 64 insertions(+), 41 deletions(-) create mode 100644 util.cpp create mode 100644 util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b2dba8..76ca83b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) project(shortener_bot LANGUAGES C CXX) -add_executable(bot main.cpp telegram_client.cpp commands.cpp) +add_executable(bot main.cpp telegram_client.cpp commands.cpp util.cpp) set_property(TARGET bot PROPERTY CXX_STANDARD 20) set_property(TARGET bot PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/commands.cpp b/commands.cpp index 473d7b3..c174a36 100644 --- a/commands.cpp +++ b/commands.cpp @@ -4,6 +4,7 @@ #include "curl/easy.h" #include "td/telegram/td_api.h" #include "td/tl/TlObject.h" +#include "util.h" #include #include #include @@ -14,6 +15,8 @@ #include #include +void send_help_msg(context *ctx, td_api::message &msg); + void cmd::handle_regular_message(context *ctx, td_api::message &msg) { if (msg.content_->get_id() == td_api::messageText::ID) { std::string text = static_cast(*msg.content_).text_->text_; @@ -24,7 +27,11 @@ void cmd::handle_regular_message(context *ctx, td_api::message &msg) { param.remove_suffix(param.size() - nextSpace); spdlog::info("Command /shorten received with parameter '{}'", param); - // TODO check URL validity + std::string paramStr(param); + if (!url::is_url_valid(paramStr)) { + send_help_msg(ctx, msg); + return; + } bool result = shorten_link(std::string(param), ctx, [tg = ctx->tg, chat_id = msg.chat_id_, thread_id = msg.message_thread_id_](std::string url){ tg->send_query(td_api::make_object( @@ -49,53 +56,49 @@ void cmd::handle_regular_message(context *ctx, td_api::message &msg) { ), {}); } } else if (std::strncmp(text.c_str(), "/shorten", 8) == 0) { - std::string textRaw("usage: /shorten "); - std::vector> empty; - auto text = static_cast>(td_api::make_object(td_api::make_object(textRaw, std::move(empty)), nullptr, false)); - ctx->tg->send_query(td_api::make_object(msg.chat_id_, msg.message_thread_id_, nullptr, nullptr, nullptr, std::move(text)), {}); + send_help_msg(ctx, msg); } } } void cmd::handle_inline_query(context *ctx, td_api::updateNewInlineQuery &query) { - // TODO check URL validity - - uint64_t pendingQueryId = new_pending_query_id(); - ctx->inlineQueries.insert(std::pair(pendingQueryId, {query.query_, std::chrono::steady_clock::now() + std::chrono::hours(5)})); - std::vector> results; - results.reserve(1); - auto messageButton = td_api::make_object( - "press to shorten", - static_cast>(td_api::make_object(std::to_string(pendingQueryId))) - ); + if (url::is_url_valid(query.query_)) { + uint64_t pendingQueryId = new_pending_query_id(); + ctx->inlineQueries.insert(std::pair(pendingQueryId, {query.query_, std::chrono::steady_clock::now() + std::chrono::hours(5)})); - std::vector messageButtonRow; - messageButtonRow.push_back(std::move(messageButton)); + auto messageButton = td_api::make_object( + "press to shorten", + static_cast>(td_api::make_object(std::to_string(pendingQueryId))) + ); - std::vector messageButtonRows; - messageButtonRows.push_back(std::move(messageButtonRow)); + std::vector messageButtonRow; + messageButtonRow.push_back(std::move(messageButton)); - results.push_back(static_cast>(td_api::make_object( - "shorten", - "", - true, // hide_url - "Shorten!", - "...", - "https://slavasil.ru/favicon.ico", - 48, 48, - static_cast>(td_api::make_object( - std::move(messageButtonRows) - )), - static_cast>(td_api::make_object( - td_api::make_object( - query.query_, - std::move(std::vector>()) - ), - td_api::make_object(true, "", false, false, false), - false // clear_draft - )) - ))); + std::vector messageButtonRows; + messageButtonRows.push_back(std::move(messageButtonRow)); + + results.push_back(static_cast>(td_api::make_object( + "shorten", + "", + true, // hide_url + "Shorten!", + "...", + "https://slavasil.ru/favicon.ico", + 48, 48, + static_cast>(td_api::make_object( + std::move(messageButtonRows) + )), + static_cast>(td_api::make_object( + td_api::make_object( + query.query_, + std::move(std::vector>()) + ), + td_api::make_object(true, "", false, false, false), + false // clear_draft + )) + ))); + } ctx->tg->send_query(td_api::make_object( query.id_, false, // is_personal @@ -185,8 +188,15 @@ bool cmd::shorten_link(std::string link, context *ctx, std::function"); + std::vector> empty; + auto text = static_cast>(td_api::make_object(td_api::make_object(textRaw, std::move(empty)), nullptr, false)); + ctx->tg->send_query(td_api::make_object(msg.chat_id_, msg.message_thread_id_, nullptr, nullptr, nullptr, std::move(text)), {}); +} + uint64_t cmd::new_pending_query_id() { static std::mt19937 rng; static std::uniform_int_distribution dist(0, 0xFFFFFFFFFFFFFFFFULL); return dist(rng); -} \ No newline at end of file +} diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000..acf7838 --- /dev/null +++ b/util.cpp @@ -0,0 +1,7 @@ +#include "util.h" +#include + +bool url::is_url_valid(std::string &url) { static std::regex r("https?:\\/\\/[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)"); + std::cmatch m; + return std::regex_match(url.c_str(), m, r); +} diff --git a/util.h b/util.h new file mode 100644 index 0000000..bef544b --- /dev/null +++ b/util.h @@ -0,0 +1,6 @@ +#pragma once +#include + +namespace url { + bool is_url_valid(std::string &url); +}