Check and fix half of FlatHashMap usages.

This commit is contained in:
levlam 2022-02-10 00:59:52 +03:00
parent 129d12566d
commit 2b1314295d
33 changed files with 194 additions and 49 deletions

View File

@ -261,7 +261,7 @@ FileId AnimationsManager::dup_animation(FileId new_id, FileId old_id) {
const Animation *old_animation = get_animation(old_id); const Animation *old_animation = get_animation(old_id);
CHECK(old_animation != nullptr); CHECK(old_animation != nullptr);
auto &new_animation = animations_[new_id]; auto &new_animation = animations_[new_id];
CHECK(!new_animation); CHECK(new_animation == nullptr);
new_animation = make_unique<Animation>(*old_animation); new_animation = make_unique<Animation>(*old_animation);
new_animation->file_id = new_id; new_animation->file_id = new_id;
new_animation->thumbnail.file_id = td_->file_manager_->dup_file_id(new_animation->thumbnail.file_id); new_animation->thumbnail.file_id = td_->file_manager_->dup_file_id(new_animation->thumbnail.file_id);

View File

@ -97,7 +97,7 @@ FileId AudiosManager::dup_audio(FileId new_id, FileId old_id) {
const Audio *old_audio = get_audio(old_id); const Audio *old_audio = get_audio(old_id);
CHECK(old_audio != nullptr); CHECK(old_audio != nullptr);
auto &new_audio = audios_[new_id]; auto &new_audio = audios_[new_id];
CHECK(!new_audio); CHECK(new_audio == nullptr);
new_audio = make_unique<Audio>(*old_audio); new_audio = make_unique<Audio>(*old_audio);
new_audio->file_id = new_id; new_audio->file_id = new_id;
new_audio->thumbnail.file_id = td_->file_manager_->dup_file_id(new_audio->thumbnail.file_id); new_audio->thumbnail.file_id = td_->file_manager_->dup_file_id(new_audio->thumbnail.file_id);

View File

@ -675,6 +675,7 @@ BackgroundId BackgroundManager::set_background(const td_api::InputBackground *in
} }
auto file_id = r_file_id.move_as_ok(); auto file_id = r_file_id.move_as_ok();
LOG(INFO) << "Receive file " << file_id << " for input background"; LOG(INFO) << "Receive file " << file_id << " for input background";
CHECK(file_id.is_valid());
auto it = file_id_to_background_id_.find(file_id); auto it = file_id_to_background_id_.find(file_id);
if (it != file_id_to_background_id_.end()) { if (it != file_id_to_background_id_.end()) {
@ -1039,9 +1040,9 @@ void BackgroundManager::add_background(const Background &background, bool replac
for (auto file_id : Document(Document::Type::General, result->file_id).get_file_ids(td_)) { for (auto file_id : Document(Document::Type::General, result->file_id).get_file_ids(td_)) {
td_->file_manager_->add_file_source(file_id, result->file_source_id); td_->file_manager_->add_file_source(file_id, result->file_source_id);
} }
}
file_id_to_background_id_.emplace(result->file_id, result->id); file_id_to_background_id_.emplace(result->file_id, result->id);
}
} else { } else {
// if file_source_id is valid, then this is a new background with result->file_id == FileId() // if file_source_id is valid, then this is a new background with result->file_id == FileId()
// then background.file_id == FileId(), then this is a fill background, which can't have file_source_id // then background.file_id == FileId(), then this is a fill background, which can't have file_source_id
@ -1261,6 +1262,10 @@ td_api::object_ptr<td_api::backgrounds> BackgroundManager::get_backgrounds_objec
} }
FileSourceId BackgroundManager::get_background_file_source_id(BackgroundId background_id, int64 access_hash) { FileSourceId BackgroundManager::get_background_file_source_id(BackgroundId background_id, int64 access_hash) {
if (!background_id.is_valid()) {
return FileSourceId();
}
Background *background = get_background_ref(background_id); Background *background = get_background_ref(background_id);
if (background != nullptr) { if (background != nullptr) {
if (!background->file_source_id.is_valid()) { if (!background->file_source_id.is_valid()) {

View File

@ -62,7 +62,6 @@
#include "td/utils/tl_parsers.h" #include "td/utils/tl_parsers.h"
#include "td/utils/UInt.h" #include "td/utils/UInt.h"
#include "td/utils/FlatHashMap.h"
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <utility> #include <utility>
@ -1561,7 +1560,7 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
auto success_values = std::move(static_cast<telegram_api::jsonObject *>(value)->value_); auto success_values = std::move(static_cast<telegram_api::jsonObject *>(value)->value_);
for (auto &success_value : success_values) { for (auto &success_value : success_values) {
CHECK(success_value != nullptr); CHECK(success_value != nullptr);
if (success_value->value_->get_id() == telegram_api::jsonObject::ID) { if (!success_value->key_.empty() && success_value->value_->get_id() == telegram_api::jsonObject::ID) {
int32 dice_value = -1; int32 dice_value = -1;
int32 frame_start = -1; int32 frame_start = -1;
for (auto &dice_key_value : for (auto &dice_key_value :

View File

@ -14104,6 +14104,9 @@ void ContactsManager::reload_user_full(UserId user_id) {
void ContactsManager::send_get_user_full_query(UserId user_id, tl_object_ptr<telegram_api::InputUser> &&input_user, void ContactsManager::send_get_user_full_query(UserId user_id, tl_object_ptr<telegram_api::InputUser> &&input_user,
Promise<Unit> &&promise, const char *source) { Promise<Unit> &&promise, const char *source) {
LOG(INFO) << "Get full " << user_id << " from " << source; LOG(INFO) << "Get full " << user_id << " from " << source;
if (!user_id.is_valid()) {
return promise.set_error(Status::Error(500, "Invalid user_id"));
}
auto send_query = auto send_query =
PromiseCreator::lambda([td = td_, input_user = std::move(input_user)](Result<Promise<Unit>> &&promise) mutable { PromiseCreator::lambda([td = td_, input_user = std::move(input_user)](Result<Promise<Unit>> &&promise) mutable {
if (promise.is_ok() && !G()->close_flag()) { if (promise.is_ok() && !G()->close_flag()) {
@ -14201,6 +14204,10 @@ void ContactsManager::reload_user_profile_photo(UserId user_id, int64 photo_id,
} }
FileSourceId ContactsManager::get_user_profile_photo_file_source_id(UserId user_id, int64 photo_id) { FileSourceId ContactsManager::get_user_profile_photo_file_source_id(UserId user_id, int64 photo_id) {
if (!user_id.is_valid()) {
return FileSourceId();
}
auto u = get_user(user_id); auto u = get_user(user_id);
if (u != nullptr && u->photo_ids.count(photo_id) != 0) { if (u != nullptr && u->photo_ids.count(photo_id) != 0) {
VLOG(file_references) << "Don't need to create file source for photo " << photo_id << " of " << user_id; VLOG(file_references) << "Don't need to create file source for photo " << photo_id << " of " << user_id;
@ -14217,6 +14224,10 @@ FileSourceId ContactsManager::get_user_profile_photo_file_source_id(UserId user_
} }
FileSourceId ContactsManager::get_chat_full_file_source_id(ChatId chat_id) { FileSourceId ContactsManager::get_chat_full_file_source_id(ChatId chat_id) {
if (!chat_id.is_valid()) {
return FileSourceId();
}
if (get_chat_full(chat_id) != nullptr) { if (get_chat_full(chat_id) != nullptr) {
VLOG(file_references) << "Don't need to create file source for full " << chat_id; VLOG(file_references) << "Don't need to create file source for full " << chat_id;
// chat full was already added, source ID was registered and shouldn't be needed // chat full was already added, source ID was registered and shouldn't be needed
@ -14232,6 +14243,10 @@ FileSourceId ContactsManager::get_chat_full_file_source_id(ChatId chat_id) {
} }
FileSourceId ContactsManager::get_channel_full_file_source_id(ChannelId channel_id) { FileSourceId ContactsManager::get_channel_full_file_source_id(ChannelId channel_id) {
if (!channel_id.is_valid()) {
return FileSourceId();
}
if (get_channel_full(channel_id) != nullptr) { if (get_channel_full(channel_id) != nullptr) {
VLOG(file_references) << "Don't need to create file source for full " << channel_id; VLOG(file_references) << "Don't need to create file source for full " << channel_id;
// channel full was already added, source ID was registered and shouldn't be needed // channel full was already added, source ID was registered and shouldn't be needed
@ -14391,6 +14406,9 @@ void ContactsManager::reload_chat_full(ChatId chat_id, Promise<Unit> &&promise)
void ContactsManager::send_get_chat_full_query(ChatId chat_id, Promise<Unit> &&promise, const char *source) { void ContactsManager::send_get_chat_full_query(ChatId chat_id, Promise<Unit> &&promise, const char *source) {
LOG(INFO) << "Get full " << chat_id << " from " << source; LOG(INFO) << "Get full " << chat_id << " from " << source;
if (!chat_id.is_valid()) {
return promise.set_error(Status::Error(500, "Invalid chat_id"));
}
auto send_query = PromiseCreator::lambda([td = td_, chat_id](Result<Promise<Unit>> &&promise) { auto send_query = PromiseCreator::lambda([td = td_, chat_id](Result<Promise<Unit>> &&promise) {
if (promise.is_ok() && !G()->close_flag()) { if (promise.is_ok() && !G()->close_flag()) {
td->create_handler<GetFullChatQuery>(promise.move_as_ok())->send(chat_id); td->create_handler<GetFullChatQuery>(promise.move_as_ok())->send(chat_id);

View File

@ -163,6 +163,9 @@ void CountryInfoManager::do_get_countries(string language_code, bool is_recursiv
if (is_recursive) { if (is_recursive) {
return promise.set_error(Status::Error(500, "Requested data is inaccessible")); return promise.set_error(Status::Error(500, "Requested data is inaccessible"));
} }
if (language_code.empty()) {
return promise.set_error(Status::Error(400, "Invalid language code specified"));
}
load_country_list(language_code, 0, load_country_list(language_code, 0,
PromiseCreator::lambda([actor_id = actor_id(this), language_code, PromiseCreator::lambda([actor_id = actor_id(this), language_code,
promise = std::move(promise)](Result<Unit> &&result) mutable { promise = std::move(promise)](Result<Unit> &&result) mutable {
@ -203,6 +206,9 @@ void CountryInfoManager::do_get_phone_number_info(string phone_number_prefix, st
if (is_recursive) { if (is_recursive) {
return promise.set_error(Status::Error(500, "Requested data is inaccessible")); return promise.set_error(Status::Error(500, "Requested data is inaccessible"));
} }
if (language_code.empty()) {
return promise.set_error(Status::Error(400, "Invalid language code specified"));
}
load_country_list(language_code, 0, load_country_list(language_code, 0,
PromiseCreator::lambda([actor_id = actor_id(this), phone_number_prefix, language_code, PromiseCreator::lambda([actor_id = actor_id(this), phone_number_prefix, language_code,
promise = std::move(promise)](Result<Unit> &&result) mutable { promise = std::move(promise)](Result<Unit> &&result) mutable {

View File

@ -661,7 +661,7 @@ FileId DocumentsManager::dup_document(FileId new_id, FileId old_id) {
const GeneralDocument *old_document = get_document(old_id); const GeneralDocument *old_document = get_document(old_id);
CHECK(old_document != nullptr); CHECK(old_document != nullptr);
auto &new_document = documents_[new_id]; auto &new_document = documents_[new_id];
CHECK(!new_document); CHECK(new_document == nullptr);
new_document = make_unique<GeneralDocument>(*old_document); new_document = make_unique<GeneralDocument>(*old_document);
new_document->file_id = new_id; new_document->file_id = new_id;
new_document->thumbnail.file_id = td_->file_manager_->dup_file_id(new_document->thumbnail.file_id); new_document->thumbnail.file_id = td_->file_manager_->dup_file_id(new_document->thumbnail.file_id);

View File

@ -125,12 +125,14 @@ FileSourceId FileReferenceManager::create_app_config_file_source() {
} }
bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_source_id) { bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_source_id) {
CHECK(node_id.is_valid());
bool is_added = nodes_[node_id].file_source_ids.add(file_source_id); bool is_added = nodes_[node_id].file_source_ids.add(file_source_id);
VLOG(file_references) << "Add " << (is_added ? "new" : "old") << ' ' << file_source_id << " for file " << node_id; VLOG(file_references) << "Add " << (is_added ? "new" : "old") << ' ' << file_source_id << " for file " << node_id;
return is_added; return is_added;
} }
bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) { bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) {
CHECK(node_id.is_valid());
bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id); bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id);
if (is_removed) { if (is_removed) {
VLOG(file_references) << "Remove " << file_source_id << " from file " << node_id; VLOG(file_references) << "Remove " << file_source_id << " from file " << node_id;
@ -169,6 +171,7 @@ void FileReferenceManager::merge(NodeId to_node_id, NodeId from_node_id) {
return; return;
} }
CHECK(to_node_id.is_valid());
auto &to = nodes_[to_node_id]; auto &to = nodes_[to_node_id];
auto &from = from_it->second; auto &from = from_it->second;
VLOG(file_references) << "Merge " << to.file_source_ids.size() << " and " << from.file_source_ids.size() VLOG(file_references) << "Merge " << to.file_source_ids.size() << " and " << from.file_source_ids.size()
@ -192,6 +195,7 @@ void FileReferenceManager::merge(NodeId to_node_id, NodeId from_node_id) {
} }
void FileReferenceManager::run_node(NodeId node_id) { void FileReferenceManager::run_node(NodeId node_id) {
CHECK(node_id.is_valid());
Node &node = nodes_[node_id]; Node &node = nodes_[node_id];
if (!node.query) { if (!node.query) {
return; return;
@ -231,6 +235,7 @@ void FileReferenceManager::run_node(NodeId node_id) {
void FileReferenceManager::send_query(Destination dest, FileSourceId file_source_id) { void FileReferenceManager::send_query(Destination dest, FileSourceId file_source_id) {
VLOG(file_references) << "Send file reference repair query for file " << dest.node_id << " with generation " VLOG(file_references) << "Send file reference repair query for file " << dest.node_id << " with generation "
<< dest.generation << " from " << file_source_id; << dest.generation << " from " << file_source_id;
CHECK(dest.node_id.is_valid());
auto &node = nodes_[dest.node_id]; auto &node = nodes_[dest.node_id];
node.query->active_queries++; node.query->active_queries++;
@ -313,6 +318,7 @@ FileReferenceManager::Destination FileReferenceManager::on_query_result(Destinat
VLOG(file_references) << "Receive result of file reference repair query for file " << dest.node_id VLOG(file_references) << "Receive result of file reference repair query for file " << dest.node_id
<< " with generation " << dest.generation << " from " << file_source_id << ": " << status << " " << " with generation " << dest.generation << " from " << file_source_id << ": " << status << " "
<< sub; << sub;
CHECK(dest.node_id.is_valid());
auto &node = nodes_[dest.node_id]; auto &node = nodes_[dest.node_id];
auto query = node.query.get(); auto query = node.query.get();
@ -350,6 +356,7 @@ void FileReferenceManager::repair_file_reference(NodeId node_id, Promise<> promi
auto main_file_id = G()->td().get_actor_unsafe()->file_manager_->get_file_view(node_id).file_id(); auto main_file_id = G()->td().get_actor_unsafe()->file_manager_->get_file_view(node_id).file_id();
VLOG(file_references) << "Repair file reference for file " << node_id << "/" << main_file_id; VLOG(file_references) << "Repair file reference for file " << node_id << "/" << main_file_id;
node_id = main_file_id; node_id = main_file_id;
CHECK(node_id.is_valid());
auto &node = nodes_[node_id]; auto &node = nodes_[node_id];
if (!node.query) { if (!node.query) {
node.query = make_unique<Query>(); node.query = make_unique<Query>();

View File

@ -248,6 +248,9 @@ int64 Global::get_location_key(double latitude, double longitude) {
double f = std::tan(PI / 4 - latitude / 2); double f = std::tan(PI / 4 - latitude / 2);
key += static_cast<int64>(f * std::cos(longitude) * 128) * 256; key += static_cast<int64>(f * std::cos(longitude) * 128) * 256;
key += static_cast<int64>(f * std::sin(longitude) * 128); key += static_cast<int64>(f * std::sin(longitude) * 128);
if (key == 0) {
key = 1;
}
return key; return key;
} }

View File

@ -1329,6 +1329,9 @@ void GroupCallManager::reload_group_call(InputGroupCallId input_group_call_id,
if (td_->auth_manager_->is_bot()) { if (td_->auth_manager_->is_bot()) {
return promise.set_error(Status::Error(400, "Bots can't get group call info")); return promise.set_error(Status::Error(400, "Bots can't get group call info"));
} }
if (!input_group_call_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid group call identifier specified"));
}
auto &queries = load_group_call_queries_[input_group_call_id]; auto &queries = load_group_call_queries_[input_group_call_id];
queries.push_back(std::move(promise)); queries.push_back(std::move(promise));

View File

@ -320,6 +320,11 @@ bool InlineQueriesManager::register_inline_message_content(
int64 query_id, const string &result_id, FileId file_id, int64 query_id, const string &result_id, FileId file_id,
tl_object_ptr<telegram_api::BotInlineMessage> &&inline_message, int32 allowed_media_content_id, bool allow_invoice, tl_object_ptr<telegram_api::BotInlineMessage> &&inline_message, int32 allowed_media_content_id, bool allow_invoice,
Photo *photo, Game *game) { Photo *photo, Game *game) {
CHECK(query_id != 0);
if (result_id.empty()) {
return false;
}
InlineMessageContent content = InlineMessageContent content =
create_inline_message_content(td_, file_id, std::move(inline_message), allowed_media_content_id, photo, game); create_inline_message_content(td_, file_id, std::move(inline_message), allowed_media_content_id, photo, game);
if (content.message_content != nullptr) { if (content.message_content != nullptr) {
@ -841,6 +846,9 @@ uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dial
query_hash = query_hash * 2023654985u + static_cast<uint64>(user_location.get_longitude() * 1e4); query_hash = query_hash * 2023654985u + static_cast<uint64>(user_location.get_longitude() * 1e4);
} }
query_hash &= 0x7FFFFFFFFFFFFFFF; query_hash &= 0x7FFFFFFFFFFFFFFF;
if (query_hash == 0) {
query_hash = 1;
}
auto it = inline_query_results_.find(query_hash); auto it = inline_query_results_.find(query_hash);
if (it != inline_query_results_.end()) { if (it != inline_query_results_.end()) {
@ -1288,7 +1296,7 @@ string InlineQueriesManager::get_web_document_content_type(
void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserId bot_user_id, uint64 query_hash, void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserId bot_user_id, uint64 query_hash,
tl_object_ptr<telegram_api::messages_botResults> &&results) { tl_object_ptr<telegram_api::messages_botResults> &&results) {
LOG(INFO) << "Receive results for inline query " << query_hash; LOG(INFO) << "Receive results for inline query " << query_hash;
if (results == nullptr) { if (results == nullptr || results->query_id_ == 0) {
decrease_pending_request_count(query_hash); decrease_pending_request_count(query_hash);
return; return;
} }

View File

@ -572,6 +572,10 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
auto all_infos = full_split(lang.second, '\x00'); auto all_infos = full_split(lang.second, '\x00');
if (all_infos.size() % 11 == 0) { if (all_infos.size() % 11 == 0) {
for (size_t i = 0; i < all_infos.size(); i += 11) { for (size_t i = 0; i < all_infos.size(); i += 11) {
if (all_infos[i].empty()) {
LOG(ERROR) << "Have empty info about a language pack";
continue;
}
LanguageInfo info; LanguageInfo info;
info.name_ = std::move(all_infos[i + 1]); info.name_ = std::move(all_infos[i + 1]);
info.native_name_ = std::move(all_infos[i + 2]); info.native_name_ = std::move(all_infos[i + 2]);
@ -921,7 +925,7 @@ void LanguagePackManager::on_get_language_info(const string &language_pack,
std::lock_guard<std::mutex> lock(language->mutex_); std::lock_guard<std::mutex> lock(language->mutex_);
if (language_pack_info->base_language_pack_id_ != language->base_language_code_) { if (language_pack_info->base_language_pack_id_ != language->base_language_code_) {
language->base_language_code_ = language_pack_info->base_language_pack_id_; language->base_language_code_ = language_pack_info->base_language_pack_id_;
if (language_pack_info->id_ == language_code_) { if (language_pack == language_pack_ && language_pack_info->id_ == language_code_) {
base_language_code_ = language->base_language_code_; base_language_code_ = language->base_language_code_;
was_updated_base_language_code = true; was_updated_base_language_code = true;
} }
@ -1367,6 +1371,10 @@ void LanguagePackManager::on_get_language_pack_strings(
switch (result->get_id()) { switch (result->get_id()) {
case telegram_api::langPackString::ID: { case telegram_api::langPackString::ID: {
auto str = telegram_api::move_object_as<telegram_api::langPackString>(result); auto str = telegram_api::move_object_as<telegram_api::langPackString>(result);
if (!is_valid_key(str->key_)) {
LOG(ERROR) << "Receive invalid key \"" << str->key_ << '"';
break;
}
auto it = language->ordinary_strings_.find(str->key_); auto it = language->ordinary_strings_.find(str->key_);
if (it == language->ordinary_strings_.end()) { if (it == language->ordinary_strings_.end()) {
key_count_delta++; key_count_delta++;
@ -1384,6 +1392,10 @@ void LanguagePackManager::on_get_language_pack_strings(
} }
case telegram_api::langPackStringPluralized::ID: { case telegram_api::langPackStringPluralized::ID: {
auto str = telegram_api::move_object_as<telegram_api::langPackStringPluralized>(result); auto str = telegram_api::move_object_as<telegram_api::langPackStringPluralized>(result);
if (!is_valid_key(str->key_)) {
LOG(ERROR) << "Receive invalid key \"" << str->key_ << '"';
break;
}
PluralizedString value{std::move(str->zero_value_), std::move(str->one_value_), PluralizedString value{std::move(str->zero_value_), std::move(str->one_value_),
std::move(str->two_value_), std::move(str->few_value_), std::move(str->two_value_), std::move(str->few_value_),
std::move(str->many_value_), std::move(str->other_value_)}; std::move(str->many_value_), std::move(str->other_value_)};
@ -1408,6 +1420,10 @@ void LanguagePackManager::on_get_language_pack_strings(
} }
case telegram_api::langPackStringDeleted::ID: { case telegram_api::langPackStringDeleted::ID: {
auto str = telegram_api::move_object_as<telegram_api::langPackStringDeleted>(result); auto str = telegram_api::move_object_as<telegram_api::langPackStringDeleted>(result);
if (!is_valid_key(str->key_)) {
LOG(ERROR) << "Receive invalid key \"" << str->key_ << '"';
break;
}
key_count_delta -= static_cast<int32>(language->ordinary_strings_.erase(str->key_)); key_count_delta -= static_cast<int32>(language->ordinary_strings_.erase(str->key_));
key_count_delta -= static_cast<int32>(language->pluralized_strings_.erase(str->key_)); key_count_delta -= static_cast<int32>(language->pluralized_strings_.erase(str->key_));
language->deleted_strings_.insert(str->key_); language->deleted_strings_.insert(str->key_);
@ -1590,7 +1606,7 @@ Result<tl_object_ptr<telegram_api::LangPackString>> LanguagePackManager::convert
Result<LanguagePackManager::LanguageInfo> LanguagePackManager::get_language_info( Result<LanguagePackManager::LanguageInfo> LanguagePackManager::get_language_info(
telegram_api::langPackLanguage *language) { telegram_api::langPackLanguage *language) {
if (!check_language_code_name(language->lang_code_)) { if (!check_language_code_name(language->lang_code_) || language->lang_code_.empty()) {
LOG(ERROR) << "Receive unsupported language pack ID " << language->lang_code_ << " from server"; LOG(ERROR) << "Receive unsupported language pack ID " << language->lang_code_ << " from server";
return Status::Error(500, "Unsupported language pack ID"); return Status::Error(500, "Unsupported language pack ID");
} }

View File

@ -277,7 +277,7 @@ void NotificationManager::init() {
for (size_t i = 0; i < ids.size(); i += 2) { for (size_t i = 0; i < ids.size(); i += 2) {
auto id = ids[i]; auto id = ids[i];
auto date = ids[i + 1]; auto date = ids[i + 1];
if (date < min_date) { if (date < min_date || id == 0) {
is_changed = true; is_changed = true;
continue; continue;
} }
@ -2249,6 +2249,9 @@ NotificationGroupId NotificationManager::get_call_notification_group_id(DialogId
if (it != dialog_id_to_call_notification_group_id_.end()) { if (it != dialog_id_to_call_notification_group_id_.end()) {
return it->second; return it->second;
} }
if (!dialog_id.is_valid()) {
return {};
}
if (available_call_notification_group_ids_.empty()) { if (available_call_notification_group_ids_.empty()) {
// need to reserve new group_id for calls // need to reserve new group_id for calls
@ -2999,9 +3002,12 @@ Status NotificationManager::process_push_notification_payload(string payload, bo
if (loc_key == "MESSAGE_ANNOUNCEMENT") { if (loc_key == "MESSAGE_ANNOUNCEMENT") {
if (announcement_message_text.empty()) { if (announcement_message_text.empty()) {
return Status::Error("Have empty announcement message text"); return Status::Error("Receive empty announcement message text");
} }
TRY_RESULT(announcement_id, get_json_object_int_field(custom, "announcement")); TRY_RESULT(announcement_id, get_json_object_int_field(custom, "announcement"));
if (announcement_id == 0) {
return Status::Error(200, "Receive unsupported announcement ID");
}
auto &date = announcement_id_date_[announcement_id]; auto &date = announcement_id_date_[announcement_id];
auto now = G()->unix_time(); auto now = G()->unix_time();
if (date >= now - ANNOUNCEMENT_ID_CACHE_TIME) { if (date >= now - ANNOUNCEMENT_ID_CACHE_TIME) {

View File

@ -377,7 +377,7 @@ PollManager::Poll *PollManager::get_poll_force(PollId poll_id) {
if (!G()->parameters().use_message_db) { if (!G()->parameters().use_message_db) {
return nullptr; return nullptr;
} }
if (loaded_from_database_polls_.count(poll_id)) { if (!poll_id.is_valid() || loaded_from_database_polls_.count(poll_id)) {
return nullptr; return nullptr;
} }
@ -443,7 +443,7 @@ vector<int32> PollManager::get_vote_percentage(const vector<int32> &voter_counts
}; };
FlatHashMap<int32, Option> options; FlatHashMap<int32, Option> options;
for (size_t i = 0; i < result.size(); i++) { for (size_t i = 0; i < result.size(); i++) {
auto &option = options[voter_counts[i]]; auto &option = options[voter_counts[i] + 1];
if (option.pos == -1) { if (option.pos == -1) {
option.pos = narrow_cast<int32>(i); option.pos = narrow_cast<int32>(i);
} }
@ -712,19 +712,19 @@ void PollManager::set_poll_answer(PollId poll_id, FullMessageId full_message_id,
} }
options.push_back(poll->options[index].data); options.push_back(poll->options[index].data);
affected_option_ids[index]++; affected_option_ids[index + 1]++;
} }
for (size_t option_index = 0; option_index < poll->options.size(); option_index++) { for (size_t option_index = 0; option_index < poll->options.size(); option_index++) {
if (poll->options[option_index].is_chosen) { if (poll->options[option_index].is_chosen) {
if (poll->is_quiz) { if (poll->is_quiz) {
return promise.set_error(Status::Error(400, "Can't revote in a quiz")); return promise.set_error(Status::Error(400, "Can't revote in a quiz"));
} }
affected_option_ids[option_index]++; affected_option_ids[option_index + 1]++;
} }
} }
for (const auto &it : affected_option_ids) { for (const auto &it : affected_option_ids) {
if (it.second == 1) { if (it.second == 1) {
invalidate_poll_option_voters(poll, poll_id, it.first); invalidate_poll_option_voters(poll, poll_id, it.first - 1);
} }
} }
@ -755,6 +755,14 @@ class PollManager::SetPollAnswerLogEvent {
void PollManager::do_set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector<string> &&options, void PollManager::do_set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector<string> &&options,
uint64 log_event_id, Promise<Unit> &&promise) { uint64 log_event_id, Promise<Unit> &&promise) {
LOG(INFO) << "Set answer in " << poll_id << " from " << full_message_id; LOG(INFO) << "Set answer in " << poll_id << " from " << full_message_id;
if (!poll_id.is_valid() || !full_message_id.get_dialog_id().is_valid() ||
!full_message_id.get_message_id().is_valid()) {
CHECK(log_event_id != 0);
LOG(ERROR) << "Invalid SetPollAnswer log event";
binlog_erase(G()->td_db()->get_binlog(), log_event_id);
return;
}
auto &pending_answer = pending_answers_[poll_id]; auto &pending_answer = pending_answers_[poll_id];
if (!pending_answer.promises_.empty() && pending_answer.options_ == options) { if (!pending_answer.promises_.empty() && pending_answer.options_ == options) {
pending_answer.promises_.push_back(std::move(promise)); pending_answer.promises_.push_back(std::move(promise));

View File

@ -19,6 +19,7 @@ QueryCombiner::QueryCombiner(Slice name, double min_delay) : next_query_time_(Ti
void QueryCombiner::add_query(int64 query_id, Promise<Promise<Unit>> &&send_query, Promise<Unit> &&promise) { void QueryCombiner::add_query(int64 query_id, Promise<Promise<Unit>> &&send_query, Promise<Unit> &&promise) {
LOG(INFO) << "Add query " << query_id << " with" << (promise ? "" : "out") << " promise"; LOG(INFO) << "Add query " << query_id << " with" << (promise ? "" : "out") << " promise";
CHECK(query_id != 0);
auto &query = queries_[query_id]; auto &query = queries_[query_id];
if (promise) { if (promise) {
query.promises.push_back(std::move(promise)); query.promises.push_back(std::move(promise));

View File

@ -25,6 +25,7 @@
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include "td/utils/SliceBuilder.h" #include "td/utils/SliceBuilder.h"
#include <limits>
#include <memory> #include <memory>
namespace td { namespace td {
@ -954,6 +955,7 @@ void SecureManager::set_secure_value_errors(Td *td, tl_object_ptr<telegram_api::
void SecureManager::get_passport_authorization_form(UserId bot_user_id, string scope, string public_key, string nonce, void SecureManager::get_passport_authorization_form(UserId bot_user_id, string scope, string public_key, string nonce,
Promise<TdApiAuthorizationForm> promise) { Promise<TdApiAuthorizationForm> promise) {
refcnt_++; refcnt_++;
CHECK(max_authorization_form_id_ < std::numeric_limits<int32>::max());
auto authorization_form_id = ++max_authorization_form_id_; auto authorization_form_id = ++max_authorization_form_id_;
auto &form = authorization_forms_[authorization_form_id]; auto &form = authorization_forms_[authorization_form_id];
form.bot_user_id = bot_user_id; form.bot_user_id = bot_user_id;

View File

@ -46,7 +46,6 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/base64.h" #include "td/utils/base64.h"
#include "td/utils/emoji.h" #include "td/utils/emoji.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/JsonBuilder.h" #include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
@ -2429,7 +2428,7 @@ FileId StickersManager::dup_sticker(FileId new_id, FileId old_id) {
const Sticker *old_sticker = get_sticker(old_id); const Sticker *old_sticker = get_sticker(old_id);
CHECK(old_sticker != nullptr); CHECK(old_sticker != nullptr);
auto &new_sticker = stickers_[new_id]; auto &new_sticker = stickers_[new_id];
CHECK(!new_sticker); CHECK(new_sticker == nullptr);
new_sticker = make_unique<Sticker>(*old_sticker); new_sticker = make_unique<Sticker>(*old_sticker);
new_sticker->file_id = new_id; new_sticker->file_id = new_id;
// there is no reason to dup m_thumbnail // there is no reason to dup m_thumbnail
@ -3032,7 +3031,7 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s
bool is_bot = td_->auth_manager_->is_bot(); bool is_bot = td_->auth_manager_->is_bot();
for (auto &document_ptr : documents) { for (auto &document_ptr : documents) {
auto sticker_id = on_get_sticker_document(std::move(document_ptr), s->sticker_format); auto sticker_id = on_get_sticker_document(std::move(document_ptr), s->sticker_format);
if (!sticker_id.second.is_valid()) { if (!sticker_id.second.is_valid() || sticker_id.first == 0) {
continue; continue;
} }
@ -3187,8 +3186,16 @@ void StickersManager::load_reactions() {
auto status = log_event_parse(reactions_, reactions); auto status = log_event_parse(reactions_, reactions);
if (status.is_error()) { if (status.is_error()) {
LOG(ERROR) << "Can't load available reactions: " << status; LOG(ERROR) << "Can't load available reactions: " << status;
reactions_ = {};
return reload_reactions(); return reload_reactions();
} }
for (auto &reaction : reactions_.reactions_) {
if (!reaction.is_valid()) {
LOG(ERROR) << "Loaded invalid reaction";
reactions_ = {};
return reload_reactions();
}
}
LOG(INFO) << "Successfully loaded " << reactions_.reactions_.size() << " available reactions"; LOG(INFO) << "Successfully loaded " << reactions_.reactions_.size() << " available reactions";
send_closure(G()->td(), &Td::send_update, get_update_reactions_object()); send_closure(G()->td(), &Td::send_update, get_update_reactions_object());
@ -3244,9 +3251,8 @@ void StickersManager::on_get_available_reactions(
on_get_sticker_document(std::move(available_reaction->around_animation_), StickerFormat::Tgs).second; on_get_sticker_document(std::move(available_reaction->around_animation_), StickerFormat::Tgs).second;
reaction.center_animation_ = reaction.center_animation_ =
on_get_sticker_document(std::move(available_reaction->center_icon_), StickerFormat::Tgs).second; on_get_sticker_document(std::move(available_reaction->center_icon_), StickerFormat::Tgs).second;
if (!reaction.static_icon_.is_valid() || !reaction.appear_animation_.is_valid() ||
!reaction.select_animation_.is_valid() || !reaction.activate_animation_.is_valid() || if (!reaction.is_valid()) {
!reaction.effect_animation_.is_valid()) {
LOG(ERROR) << "Receive invalid reaction " << reaction.reaction_; LOG(ERROR) << "Receive invalid reaction " << reaction.reaction_;
continue; continue;
} }
@ -4868,6 +4874,9 @@ void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *s
auto start_time = max(now, next_update_animated_emoji_clicked_time_); auto start_time = max(now, next_update_animated_emoji_clicked_time_);
for (const auto &click : clicks) { for (const auto &click : clicks) {
auto index = click.first; auto index = click.first;
if (index <= 0) {
return;
}
auto sticker_id = sticker_ids[index]; auto sticker_id = sticker_ids[index];
if (!sticker_id.is_valid()) { if (!sticker_id.is_valid()) {
LOG(INFO) << "Failed to find sticker for " << emoji << " with index " << index; LOG(INFO) << "Failed to find sticker for " << emoji << " with index " << index;

View File

@ -451,6 +451,11 @@ class StickersManager final : public Actor {
FileId around_animation_; FileId around_animation_;
FileId center_animation_; FileId center_animation_;
bool is_valid() const {
return static_icon_.is_valid() && appear_animation_.is_valid() && select_animation_.is_valid() &&
activate_animation_.is_valid() && effect_animation_.is_valid() && !reaction_.empty();
}
template <class StorerT> template <class StorerT>
void store(StorerT &storer) const; void store(StorerT &storer) const;

View File

@ -98,7 +98,7 @@ FileId VideoNotesManager::dup_video_note(FileId new_id, FileId old_id) {
const VideoNote *old_video_note = get_video_note(old_id); const VideoNote *old_video_note = get_video_note(old_id);
CHECK(old_video_note != nullptr); CHECK(old_video_note != nullptr);
auto &new_video_note = video_notes_[new_id]; auto &new_video_note = video_notes_[new_id];
CHECK(!new_video_note); CHECK(new_video_note == nullptr);
new_video_note = make_unique<VideoNote>(*old_video_note); new_video_note = make_unique<VideoNote>(*old_video_note);
new_video_note->file_id = new_id; new_video_note->file_id = new_id;
new_video_note->thumbnail.file_id = td_->file_manager_->dup_file_id(new_video_note->thumbnail.file_id); new_video_note->thumbnail.file_id = td_->file_manager_->dup_file_id(new_video_note->thumbnail.file_id);

View File

@ -134,7 +134,7 @@ FileId VideosManager::dup_video(FileId new_id, FileId old_id) {
const Video *old_video = get_video(old_id); const Video *old_video = get_video(old_id);
CHECK(old_video != nullptr); CHECK(old_video != nullptr);
auto &new_video = videos_[new_id]; auto &new_video = videos_[new_id];
CHECK(!new_video); CHECK(new_video == nullptr);
new_video = make_unique<Video>(*old_video); new_video = make_unique<Video>(*old_video);
new_video->file_id = new_id; new_video->file_id = new_id;
new_video->thumbnail.file_id = td_->file_manager_->dup_file_id(new_video->thumbnail.file_id); new_video->thumbnail.file_id = td_->file_manager_->dup_file_id(new_video->thumbnail.file_id);

View File

@ -78,7 +78,7 @@ FileId VoiceNotesManager::dup_voice_note(FileId new_id, FileId old_id) {
const VoiceNote *old_voice_note = get_voice_note(old_id); const VoiceNote *old_voice_note = get_voice_note(old_id);
CHECK(old_voice_note != nullptr); CHECK(old_voice_note != nullptr);
auto &new_voice_note = voice_notes_[new_id]; auto &new_voice_note = voice_notes_[new_id];
CHECK(!new_voice_note); CHECK(new_voice_note == nullptr);
new_voice_note = make_unique<VoiceNote>(*old_voice_note); new_voice_note = make_unique<VoiceNote>(*old_voice_note);
new_voice_note->file_id = new_id; new_voice_note->file_id = new_id;
return new_id; return new_id;

View File

@ -36,6 +36,7 @@
#include "td/utils/tl_helpers.h" #include "td/utils/tl_helpers.h"
#include <type_traits> #include <type_traits>
#include <unordered_map>
namespace td { namespace td {
@ -47,7 +48,7 @@ struct GetWebPageBlockObjectContext {
bool is_first_pass_ = true; bool is_first_pass_ = true;
bool has_anchor_urls_ = false; bool has_anchor_urls_ = false;
FlatHashMap<Slice, const RichText *, SliceHash> anchors_; // anchor -> text std::unordered_map<Slice, const RichText *, SliceHash> anchors_; // anchor -> text
}; };
static vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects( static vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects(

View File

@ -102,6 +102,10 @@ class GetWebPageQuery final : public Td::ResultHandler {
} }
void send(WebPageId web_page_id, const string &url, int32 hash) { void send(WebPageId web_page_id, const string &url, int32 hash) {
if (url.empty()) {
return promise_.set_value(WebPageId());
}
web_page_id_ = web_page_id; web_page_id_ = web_page_id;
url_ = url; url_ = url;
send_query(G()->net_query_creator().create(telegram_api::messages_getWebPage(url, hash))); send_query(G()->net_query_creator().create(telegram_api::messages_getWebPage(url, hash)));
@ -571,7 +575,9 @@ void WebPagesManager::update_web_page(unique_ptr<WebPage> web_page, WebPageId we
td_->file_manager_->change_files_source(get_web_page_file_source_id(page.get()), old_file_ids, new_file_ids); td_->file_manager_->change_files_source(get_web_page_file_source_id(page.get()), old_file_ids, new_file_ids);
} }
on_get_web_page_by_url(page->url, web_page_id, from_database); if (!page->url.empty()) {
on_get_web_page_by_url(page->url, web_page_id, from_database);
}
if (is_changed && !from_database) { if (is_changed && !from_database) {
on_web_page_changed(web_page_id, true); on_web_page_changed(web_page_id, true);
@ -833,6 +839,9 @@ tl_object_ptr<td_api::webPage> WebPagesManager::get_web_page_preview_result(int6
void WebPagesManager::get_web_page_instant_view(const string &url, bool force_full, Promise<WebPageId> &&promise) { void WebPagesManager::get_web_page_instant_view(const string &url, bool force_full, Promise<WebPageId> &&promise) {
LOG(INFO) << "Trying to get web page instant view for the url \"" << url << '"'; LOG(INFO) << "Trying to get web page instant view for the url \"" << url << '"';
if (url.empty()) {
return promise.set_value(WebPageId());
}
auto it = url_to_web_page_id_.find(url); auto it = url_to_web_page_id_.find(url);
if (it != url_to_web_page_id_.end()) { if (it != url_to_web_page_id_.end()) {
if (it->second == WebPageId()) { if (it->second == WebPageId()) {
@ -997,6 +1006,7 @@ void WebPagesManager::update_web_page_instant_view_load_requests(WebPageId web_p
} }
return; return;
} }
CHECK(new_web_page_id.is_valid());
if (web_page_instant_view->is_loaded) { if (web_page_instant_view->is_loaded) {
if (web_page_instant_view->is_full) { if (web_page_instant_view->is_full) {
combine(promises[0], std::move(promises[1])); combine(promises[0], std::move(promises[1]));
@ -1045,6 +1055,9 @@ WebPageId WebPagesManager::get_web_page_by_url(const string &url) const {
void WebPagesManager::get_web_page_by_url(const string &url, Promise<WebPageId> &&promise) { void WebPagesManager::get_web_page_by_url(const string &url, Promise<WebPageId> &&promise) {
LOG(INFO) << "Trying to get web page identifier for the url \"" << url << '"'; LOG(INFO) << "Trying to get web page identifier for the url \"" << url << '"';
if (url.empty()) {
return promise.set_value(WebPageId());
}
auto it = url_to_web_page_id_.find(url); auto it = url_to_web_page_id_.find(url);
if (it != url_to_web_page_id_.end()) { if (it != url_to_web_page_id_.end()) {
@ -1055,6 +1068,9 @@ void WebPagesManager::get_web_page_by_url(const string &url, Promise<WebPageId>
} }
void WebPagesManager::load_web_page_by_url(string url, Promise<WebPageId> &&promise) { void WebPagesManager::load_web_page_by_url(string url, Promise<WebPageId> &&promise) {
if (url.empty()) {
return promise.set_value(WebPageId());
}
if (!G()->parameters().use_message_db) { if (!G()->parameters().use_message_db) {
return reload_web_page_by_url(url, std::move(promise)); return reload_web_page_by_url(url, std::move(promise));
} }
@ -1433,7 +1449,7 @@ void WebPagesManager::on_get_web_page_instant_view(WebPage *web_page, tl_object_
auto document = move_tl_object_as<telegram_api::document>(document_ptr); auto document = move_tl_object_as<telegram_api::document>(document_ptr);
auto document_id = document->id_; auto document_id = document->id_;
auto parsed_document = td_->documents_manager_->on_get_document(std::move(document), owner_dialog_id); auto parsed_document = td_->documents_manager_->on_get_document(std::move(document), owner_dialog_id);
if (!parsed_document.empty()) { if (!parsed_document.empty() && document_id != 0) {
get_map(parsed_document.type)->emplace(document_id, parsed_document.file_id); get_map(parsed_document.type)->emplace(document_id, parsed_document.file_id);
} }
} }
@ -1446,7 +1462,12 @@ void WebPagesManager::on_get_web_page_instant_view(WebPage *web_page, tl_object_
auto add_document = [&](const Document &document) { auto add_document = [&](const Document &document) {
auto file_view = td_->file_manager_->get_file_view(document.file_id); auto file_view = td_->file_manager_->get_file_view(document.file_id);
if (file_view.has_remote_location()) { if (file_view.has_remote_location()) {
get_map(document.type)->emplace(file_view.remote_location().get_id(), document.file_id); auto document_id = file_view.remote_location().get_id();
if (document_id != 0) {
get_map(document.type)->emplace(document_id, document.file_id);
} else {
LOG(ERROR) << document.type << " has zero ID";
}
} else { } else {
LOG(ERROR) << document.type << " has no remote location"; LOG(ERROR) << document.type << " has no remote location";
} }
@ -1538,6 +1559,10 @@ void WebPagesManager::on_binlog_web_page_event(BinlogEvent &&event) {
log_event_parse(log_event, event.data_).ensure(); log_event_parse(log_event, event.data_).ensure();
auto web_page_id = log_event.web_page_id; auto web_page_id = log_event.web_page_id;
if (!web_page_id.is_valid()) {
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
}
LOG(INFO) << "Add " << web_page_id << " from binlog"; LOG(INFO) << "Add " << web_page_id << " from binlog";
auto web_page = std::move(log_event.web_page_out); auto web_page = std::move(log_event.web_page_out);
CHECK(web_page != nullptr); CHECK(web_page != nullptr);
@ -1575,7 +1600,8 @@ void WebPagesManager::on_save_web_page_to_database(WebPageId web_page_id, bool s
} }
void WebPagesManager::load_web_page_from_database(WebPageId web_page_id, Promise<Unit> promise) { void WebPagesManager::load_web_page_from_database(WebPageId web_page_id, Promise<Unit> promise) {
if (!G()->parameters().use_message_db || loaded_from_database_web_pages_.count(web_page_id)) { if (!G()->parameters().use_message_db || loaded_from_database_web_pages_.count(web_page_id) ||
!web_page_id.is_valid()) {
promise.set_value(Unit()); promise.set_value(Unit());
return; return;
} }
@ -1644,7 +1670,7 @@ const WebPagesManager::WebPage *WebPagesManager::get_web_page_force(WebPageId we
if (!G()->parameters().use_message_db) { if (!G()->parameters().use_message_db) {
return nullptr; return nullptr;
} }
if (loaded_from_database_web_pages_.count(web_page_id)) { if (!web_page_id.is_valid() || loaded_from_database_web_pages_.count(web_page_id)) {
return nullptr; return nullptr;
} }
@ -1662,6 +1688,10 @@ FileSourceId WebPagesManager::get_web_page_file_source_id(WebPage *web_page) {
} }
FileSourceId WebPagesManager::get_url_file_source_id(const string &url) { FileSourceId WebPagesManager::get_url_file_source_id(const string &url) {
if (url.empty()) {
return FileSourceId();
}
auto web_page_id = get_web_page_by_url(url); auto web_page_id = get_web_page_by_url(url);
if (web_page_id.is_valid()) { if (web_page_id.is_valid()) {
const WebPage *web_page = get_web_page(web_page_id); const WebPage *web_page = get_web_page(web_page_id);

View File

@ -247,7 +247,9 @@ class CliClient final : public Actor {
new_user.first_name = user.first_name_; new_user.first_name = user.first_name_;
new_user.last_name = user.last_name_; new_user.last_name = user.last_name_;
new_user.username = user.username_; new_user.username = user.username_;
username_to_user_id_[to_lower(new_user.username)] = user.id_; if (!new_user.username.empty()) {
username_to_user_id_[to_lower(new_user.username)] = user.id_;
}
} }
void print_user(Logger &log, int64 user_id, bool full = false) { void print_user(Logger &log, int64 user_id, bool full = false) {
@ -1681,7 +1683,9 @@ class CliClient final : public Actor {
td_api::make_object<td_api::messageSendOptions>(disable_notification, from_background, true, td_api::make_object<td_api::messageSendOptions>(disable_notification, from_background, true,
as_message_scheduling_state(schedule_date_)), as_message_scheduling_state(schedule_date_)),
nullptr, std::move(input_message_content))); nullptr, std::move(input_message_content)));
query_id_to_send_message_info_[id].start_time = Time::now(); if (id != 0) {
query_id_to_send_message_info_[id].start_time = Time::now();
}
} }
td_api::object_ptr<td_api::messageSendOptions> default_message_send_options() const { td_api::object_ptr<td_api::messageSendOptions> default_message_send_options() const {

View File

@ -10,11 +10,11 @@
#include "td/telegram/files/FileType.h" #include "td/telegram/files/FileType.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include "td/utils/tl_helpers.h" #include "td/utils/tl_helpers.h"
#include <array> #include <array>
#include <unordered_map>
namespace td { namespace td {
@ -73,7 +73,7 @@ class FileStats {
using StatByType = std::array<FileTypeStat, MAX_FILE_TYPE>; using StatByType = std::array<FileTypeStat, MAX_FILE_TYPE>;
StatByType stat_by_type_; StatByType stat_by_type_;
FlatHashMap<DialogId, StatByType, DialogIdHash> stat_by_owner_dialog_id_; std::unordered_map<DialogId, StatByType, DialogIdHash> stat_by_owner_dialog_id_;
vector<FullFileInfo> all_files_; vector<FullFileInfo> all_files_;
void add_impl(const FullFileInfo &info); void add_impl(const FullFileInfo &info);

View File

@ -19,7 +19,6 @@
#include "td/db/SqliteKeyValue.h" #include "td/db/SqliteKeyValue.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
@ -32,6 +31,7 @@
#include "td/utils/tl_parsers.h" #include "td/utils/tl_parsers.h"
#include <functional> #include <functional>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
namespace td { namespace td {
@ -184,7 +184,7 @@ void FileStatsWorker::get_stats(bool need_all_files, bool split_by_owner_dialog_
return promise.set_error(Global::request_aborted_error()); return promise.set_error(Global::request_aborted_error());
} }
FlatHashMap<size_t, size_t> hash_to_pos; std::unordered_map<size_t, size_t> hash_to_pos;
size_t pos = 0; size_t pos = 0;
for (auto &full_info : full_infos) { for (auto &full_info : full_infos) {
hash_to_pos[std::hash<std::string>()(full_info.path)] = pos; hash_to_pos[std::hash<std::string>()(full_info.path)] = pos;

View File

@ -228,11 +228,12 @@ void ConnectionCreator::get_proxies(Promise<td_api::object_ptr<td_api::proxies>>
} }
void ConnectionCreator::get_proxy_link(int32 proxy_id, Promise<string> promise) { void ConnectionCreator::get_proxy_link(int32 proxy_id, Promise<string> promise) {
if (proxies_.count(proxy_id) == 0) { auto it = proxies_.find(proxy_id);
if (it == proxies_.end()) {
return promise.set_error(Status::Error(400, "Unknown proxy identifier")); return promise.set_error(Status::Error(400, "Unknown proxy identifier"));
} }
auto &proxy = proxies_[proxy_id]; auto &proxy = it->second;
string url = G()->shared_config().get_option_string("t_me_url", "https://t.me/"); string url = G()->shared_config().get_option_string("t_me_url", "https://t.me/");
bool is_socks = false; bool is_socks = false;
switch (proxy.type()) { switch (proxy.type()) {
@ -1132,11 +1133,13 @@ void ConnectionCreator::start_up() {
if (begins_with(info.first, "_used")) { if (begins_with(info.first, "_used")) {
auto proxy_id = to_integer_safe<int32>(Slice(info.first).substr(5)).move_as_ok(); auto proxy_id = to_integer_safe<int32>(Slice(info.first).substr(5)).move_as_ok();
auto last_used = to_integer_safe<int32>(info.second).move_as_ok(); auto last_used = to_integer_safe<int32>(info.second).move_as_ok();
CHECK(proxy_id > 0);
proxy_last_used_date_[proxy_id] = last_used; proxy_last_used_date_[proxy_id] = last_used;
proxy_last_used_saved_date_[proxy_id] = last_used; proxy_last_used_saved_date_[proxy_id] = last_used;
} else { } else {
LOG_CHECK(!ends_with(info.first, "_max_id")) << info.first; LOG_CHECK(!ends_with(info.first, "_max_id")) << info.first;
auto proxy_id = info.first.empty() ? static_cast<int32>(1) : to_integer_safe<int32>(info.first).move_as_ok(); auto proxy_id = info.first.empty() ? static_cast<int32>(1) : to_integer_safe<int32>(info.first).move_as_ok();
CHECK(proxy_id > 0);
CHECK(proxies_.count(proxy_id) == 0); CHECK(proxies_.count(proxy_id) == 0);
log_event_parse(proxies_[proxy_id], info.second).ensure(); log_event_parse(proxies_[proxy_id], info.second).ensure();
if (proxies_[proxy_id].type() == Proxy::Type::None) { if (proxies_[proxy_id].type() == Proxy::Type::None) {

View File

@ -619,6 +619,8 @@ void Session::on_session_failed(Status status) {
} }
void Session::on_container_sent(uint64 container_id, vector<uint64> msg_ids) { void Session::on_container_sent(uint64 container_id, vector<uint64> msg_ids) {
CHECK(container_id != 0);
td::remove_if(msg_ids, [&](uint64 msg_id) { td::remove_if(msg_ids, [&](uint64 msg_id) {
auto it = sent_queries_.find(msg_id); auto it = sent_queries_.find(msg_id);
if (it == sent_queries_.end()) { if (it == sent_queries_.end()) {
@ -642,10 +644,11 @@ void Session::on_message_ack_impl(uint64 id, int32 type) {
auto cit = sent_containers_.find(id); auto cit = sent_containers_.find(id);
if (cit != sent_containers_.end()) { if (cit != sent_containers_.end()) {
auto container_info = std::move(cit->second); auto container_info = std::move(cit->second);
sent_containers_.erase(cit);
for (auto message_id : container_info.message_ids) { for (auto message_id : container_info.message_ids) {
on_message_ack_impl_inner(message_id, type, true); on_message_ack_impl_inner(message_id, type, true);
} }
sent_containers_.erase(cit);
return; return;
} }
@ -902,10 +905,11 @@ void Session::on_message_failed(uint64 id, Status status) {
auto cit = sent_containers_.find(id); auto cit = sent_containers_.find(id);
if (cit != sent_containers_.end()) { if (cit != sent_containers_.end()) {
auto container_info = std::move(cit->second); auto container_info = std::move(cit->second);
sent_containers_.erase(cit);
for (auto message_id : container_info.message_ids) { for (auto message_id : container_info.message_ids) {
on_message_failed_inner(message_id, true); on_message_failed_inner(message_id, true);
} }
sent_containers_.erase(cit);
return; return;
} }

View File

@ -6,9 +6,10 @@
// //
#pragma once #pragma once
#include "td/utils/FlatHashMap.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include <unordered_map>
namespace td { namespace td {
class SeqKeyValue { class SeqKeyValue {
@ -61,12 +62,12 @@ class SeqKeyValue {
return map_.size(); return map_.size();
} }
FlatHashMap<string, string> get_all() const { std::unordered_map<string, string> get_all() const {
return map_; return map_;
} }
private: private:
FlatHashMap<string, string> map_; std::unordered_map<string, string> map_;
SeqNo current_id_ = 0; SeqNo current_id_ = 0;
SeqNo next_seq_no() { SeqNo next_seq_no() {
return ++current_id_; return ++current_id_;

View File

@ -63,6 +63,7 @@ class SqliteKeyValue {
FlatHashMap<string, string> get_all() { FlatHashMap<string, string> get_all() {
FlatHashMap<string, string> res; FlatHashMap<string, string> res;
get_by_prefix("", [&](Slice key, Slice value) { get_by_prefix("", [&](Slice key, Slice value) {
CHECK(!key.empty());
res.emplace(key.str(), value.str()); res.emplace(key.str(), value.str());
return true; return true;
}); });

View File

@ -51,6 +51,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
if (it != buffer_.end()) { if (it != buffer_.end()) {
it->second = std::move(value); it->second = std::move(value);
} else { } else {
CHECK(!key.empty());
buffer_.emplace(std::move(key), std::move(value)); buffer_.emplace(std::move(key), std::move(value));
} }
if (promise) { if (promise) {
@ -71,6 +72,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
if (it != buffer_.end()) { if (it != buffer_.end()) {
it->second = optional<string>(); it->second = optional<string>();
} else { } else {
CHECK(!key.empty());
buffer_.emplace(std::move(key), optional<string>()); buffer_.emplace(std::move(key), optional<string>());
} }
if (promise) { if (promise) {
@ -109,7 +111,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
static constexpr double MAX_PENDING_QUERIES_DELAY = 0.01; static constexpr double MAX_PENDING_QUERIES_DELAY = 0.01;
static constexpr size_t MAX_PENDING_QUERIES_COUNT = 100; static constexpr size_t MAX_PENDING_QUERIES_COUNT = 100;
FlatHashMap<string, optional<string>> buffer_; FlatHashMap<string, optional<string>> buffer_;
std::vector<Promise<Unit>> buffer_promises_; vector<Promise<Unit>> buffer_promises_;
size_t cnt_ = 0; size_t cnt_ = 0;
double wakeup_at_ = 0; double wakeup_at_ = 0;

View File

@ -96,7 +96,7 @@ class TQueueImpl final : public TQueue {
bool do_push(QueueId queue_id, RawEvent &&raw_event) final { bool do_push(QueueId queue_id, RawEvent &&raw_event) final {
CHECK(raw_event.event_id.is_valid()); CHECK(raw_event.event_id.is_valid());
// raw_event.data can be empty when replaying binlog // raw_event.data can be empty when replaying binlog
if (raw_event.data.size() > MAX_EVENT_LENGTH) { if (raw_event.data.size() > MAX_EVENT_LENGTH || queue_id == 0) {
return false; return false;
} }
auto &q = queues_[queue_id]; auto &q = queues_[queue_id];
@ -139,6 +139,9 @@ class TQueueImpl final : public TQueue {
if (data.size() > MAX_EVENT_LENGTH) { if (data.size() > MAX_EVENT_LENGTH) {
return Status::Error("Data is too big"); return Status::Error("Data is too big");
} }
if (queue_id == 0) {
return Status::Error("Queue identifier is invalid");
}
auto &q = queues_[queue_id]; auto &q = queues_[queue_id];
if (q.events.size() >= MAX_QUEUE_EVENTS) { if (q.events.size() >= MAX_QUEUE_EVENTS) {

View File

@ -8,10 +8,10 @@
#include "td/db/SeqKeyValue.h" #include "td/db/SeqKeyValue.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/port/RwMutex.h" #include "td/utils/port/RwMutex.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include <unordered_map>
#include <utility> #include <utility>
namespace td { namespace td {
@ -52,7 +52,7 @@ class TsSeqKeyValue {
size_t size() const { size_t size() const {
return kv_.size(); return kv_.size();
} }
FlatHashMap<string, string> get_all() { std::unordered_map<string, string> get_all() {
auto lock = rw_mutex_.lock_write().move_as_ok(); auto lock = rw_mutex_.lock_write().move_as_ok();
return kv_.get_all(); return kv_.get_all();
} }