From 02ae56ae8a209755134efdf1c6c41d1769991e61 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 14 Sep 2021 17:09:40 +0300 Subject: [PATCH] Improve validness checks for UserId/ChatId/ChannelId. --- td/telegram/ChannelId.h | 5 +++- td/telegram/ChatId.h | 4 ++- td/telegram/ContactsManager.h | 3 ++- td/telegram/DialogId.cpp | 45 ++++++++++++++------------------- td/telegram/DialogId.h | 11 +++----- td/telegram/MessagesManager.cpp | 1 + td/telegram/UserId.h | 4 ++- 7 files changed, 35 insertions(+), 38 deletions(-) diff --git a/td/telegram/ChannelId.h b/td/telegram/ChannelId.h index 353aa35c9..b981482b0 100644 --- a/td/telegram/ChannelId.h +++ b/td/telegram/ChannelId.h @@ -20,6 +20,9 @@ class ChannelId { int64 id = 0; public: + // the last (1 << 31) - 1 identifiers will be used for secret chat dialog identifiers + static constexpr int64 MAX_CHANNEL_ID = 1000000000000ll - (1ll << 31); + ChannelId() = default; explicit ChannelId(int64 channel_id) : id(channel_id) { @@ -28,7 +31,7 @@ class ChannelId { ChannelId(T channel_id) = delete; bool is_valid() const { - return id > 0; // TODO better is_valid + return 0 < id && id < MAX_CHANNEL_ID; } int64 get() const { diff --git a/td/telegram/ChatId.h b/td/telegram/ChatId.h index 33eda7299..67d7177f0 100644 --- a/td/telegram/ChatId.h +++ b/td/telegram/ChatId.h @@ -20,6 +20,8 @@ class ChatId { int64 id = 0; public: + static constexpr int64 MAX_CHAT_ID = 999999999999ll; + ChatId() = default; explicit ChatId(int64 chat_id) : id(chat_id) { @@ -28,7 +30,7 @@ class ChatId { ChatId(T chat_id) = delete; bool is_valid() const { - return id > 0; + return 0 < id && id <= MAX_CHAT_ID; } int64 get() const { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index e0f24fff7..a3f768ed5 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -1467,7 +1467,8 @@ class ContactsManager final : public Actor { static tl_object_ptr get_secret_chat_state_object(SecretChatState state); - static td_api::object_ptr get_update_unknown_secret_chat_object(SecretChatId user_id); + static td_api::object_ptr get_update_unknown_secret_chat_object( + SecretChatId secret_chat_id); tl_object_ptr get_secret_chat_object(SecretChatId secret_chat_id, const SecretChat *secret_chat); diff --git a/td/telegram/DialogId.cpp b/td/telegram/DialogId.cpp index ae445938e..1d8da1528 100644 --- a/td/telegram/DialogId.cpp +++ b/td/telegram/DialogId.cpp @@ -10,38 +10,31 @@ #include "td/utils/logging.h" +#include + namespace td { bool DialogId::is_valid() const { - switch (get_type()) { - case DialogType::User: - return get_user_id().is_valid(); - case DialogType::Chat: - return get_chat_id().is_valid(); - case DialogType::Channel: - return get_channel_id().is_valid(); - case DialogType::SecretChat: - return get_secret_chat_id().is_valid(); - case DialogType::None: - return false; - default: - UNREACHABLE(); - return false; - } + return get_type() != DialogType::None; } DialogType DialogId::get_type() const { + // check that valid ranges are continuous + static_assert(ZERO_CHANNEL_ID + 1 == -ChatId::MAX_CHAT_ID, ""); + static_assert( + ZERO_SECRET_CHAT_ID + std::numeric_limits::max() + 1 == ZERO_CHANNEL_ID - ChannelId::MAX_CHANNEL_ID, ""); + if (id < 0) { - if (MIN_CHAT_ID <= id) { + if (-ChatId::MAX_CHAT_ID <= id) { return DialogType::Chat; } - if (MIN_CHANNEL_ID <= id && id < MAX_CHANNEL_ID) { + if (ZERO_CHANNEL_ID - ChannelId::MAX_CHANNEL_ID <= id && id != ZERO_CHANNEL_ID) { return DialogType::Channel; } - if (MIN_SECRET_ID <= id && id < MAX_SECRET_ID) { + if (ZERO_SECRET_CHAT_ID + std::numeric_limits::min() <= id && id != ZERO_SECRET_CHAT_ID) { return DialogType::SecretChat; } - } else if (0 < id && id <= MAX_USER_ID) { + } else if (0 < id && id <= UserId::MAX_USER_ID) { return DialogType::User; } return DialogType::None; @@ -59,12 +52,12 @@ ChatId DialogId::get_chat_id() const { ChannelId DialogId::get_channel_id() const { CHECK(get_type() == DialogType::Channel); - return ChannelId(MAX_CHANNEL_ID - id); + return ChannelId(ZERO_CHANNEL_ID - id); } SecretChatId DialogId::get_secret_chat_id() const { CHECK(get_type() == DialogType::SecretChat); - return SecretChatId(static_cast(id - ZERO_SECRET_ID)); + return SecretChatId(static_cast(id - ZERO_SECRET_CHAT_ID)); } DialogId::DialogId(UserId user_id) { @@ -85,15 +78,15 @@ DialogId::DialogId(ChatId chat_id) { DialogId::DialogId(ChannelId channel_id) { if (channel_id.is_valid()) { - id = MAX_CHANNEL_ID - channel_id.get(); + id = ZERO_CHANNEL_ID - channel_id.get(); } else { id = 0; } } -DialogId::DialogId(SecretChatId chat_id) { - if (chat_id.is_valid()) { - id = ZERO_SECRET_ID + static_cast(chat_id.get()); +DialogId::DialogId(SecretChatId secret_chat_id) { + if (secret_chat_id.is_valid()) { + id = ZERO_SECRET_CHAT_ID + static_cast(secret_chat_id.get()); } else { id = 0; } @@ -150,7 +143,7 @@ int64 DialogId::get_peer_id(const tl_object_ptr &peer) { return 0; } - return MAX_CHANNEL_ID - channel_id.get(); + return ZERO_CHANNEL_ID - channel_id.get(); } default: UNREACHABLE(); diff --git a/td/telegram/DialogId.h b/td/telegram/DialogId.h index 71746785d..64f3cbfc5 100644 --- a/td/telegram/DialogId.h +++ b/td/telegram/DialogId.h @@ -24,13 +24,8 @@ namespace td { enum class DialogType : int32 { None, User, Chat, Channel, SecretChat }; class DialogId { - static constexpr int64 MIN_SECRET_ID = -2002147483648ll; - static constexpr int64 ZERO_SECRET_ID = -2000000000000ll; - static constexpr int64 MAX_SECRET_ID = -1997852516353ll; - static constexpr int64 MIN_CHANNEL_ID = -1997852516352ll; - static constexpr int64 MAX_CHANNEL_ID = -1000000000000ll; - static constexpr int64 MIN_CHAT_ID = -999999999999ll; - static constexpr int64 MAX_USER_ID = 999999999999ll; + static constexpr int64 ZERO_SECRET_CHAT_ID = -2000000000000ll; + static constexpr int64 ZERO_CHANNEL_ID = -1000000000000ll; int64 id = 0; @@ -49,7 +44,7 @@ class DialogId { explicit DialogId(UserId user_id); explicit DialogId(ChatId chat_id); explicit DialogId(ChannelId channel_id); - explicit DialogId(SecretChatId chat_id); + explicit DialogId(SecretChatId secret_chat_id); int64 get() const { return id; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 73a7032a3..ca501867d 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -34177,6 +34177,7 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source MessagesManager::Dialog *MessagesManager::add_dialog(DialogId dialog_id, const char *source) { LOG(DEBUG) << "Creating " << dialog_id << " from " << source; CHECK(!have_dialog(dialog_id)); + LOG_CHECK(dialog_id.is_valid()) << source; if (G()->parameters().use_message_db) { // TODO preload dialog asynchronously, remove loading from this function diff --git a/td/telegram/UserId.h b/td/telegram/UserId.h index 20b7068a1..b373c98bd 100644 --- a/td/telegram/UserId.h +++ b/td/telegram/UserId.h @@ -20,6 +20,8 @@ class UserId { int64 id = 0; public: + static constexpr int64 MAX_USER_ID = (1ll << 40) - 1; + UserId() = default; explicit UserId(int64 user_id) : id(user_id) { @@ -46,7 +48,7 @@ class UserId { } bool is_valid() const { - return id > 0; + return 0 < id && id <= MAX_USER_ID; } int64 get() const {