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);
CHECK(old_animation != nullptr);
auto &new_animation = animations_[new_id];
CHECK(!new_animation);
CHECK(new_animation == nullptr);
new_animation = make_unique<Animation>(*old_animation);
new_animation->file_id = new_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);
CHECK(old_audio != nullptr);
auto &new_audio = audios_[new_id];
CHECK(!new_audio);
CHECK(new_audio == nullptr);
new_audio = make_unique<Audio>(*old_audio);
new_audio->file_id = new_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();
LOG(INFO) << "Receive file " << file_id << " for input background";
CHECK(file_id.is_valid());
auto it = file_id_to_background_id_.find(file_id);
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_)) {
td_->file_manager_->add_file_source(file_id, result->file_source_id);
}
}
file_id_to_background_id_.emplace(result->file_id, result->id);
}
} else {
// 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
@ -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) {
if (!background_id.is_valid()) {
return FileSourceId();
}
Background *background = get_background_ref(background_id);
if (background != nullptr) {
if (!background->file_source_id.is_valid()) {

View File

@ -62,7 +62,6 @@
#include "td/utils/tl_parsers.h"
#include "td/utils/UInt.h"
#include "td/utils/FlatHashMap.h"
#include <functional>
#include <memory>
#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_);
for (auto &success_value : success_values) {
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 frame_start = -1;
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,
Promise<Unit> &&promise, const char *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 =
PromiseCreator::lambda([td = td_, input_user = std::move(input_user)](Result<Promise<Unit>> &&promise) mutable {
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) {
if (!user_id.is_valid()) {
return FileSourceId();
}
auto u = get_user(user_id);
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;
@ -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) {
if (!chat_id.is_valid()) {
return FileSourceId();
}
if (get_chat_full(chat_id) != nullptr) {
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
@ -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) {
if (!channel_id.is_valid()) {
return FileSourceId();
}
if (get_channel_full(channel_id) != nullptr) {
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
@ -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) {
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) {
if (promise.is_ok() && !G()->close_flag()) {
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) {
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,
PromiseCreator::lambda([actor_id = actor_id(this), language_code,
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) {
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,
PromiseCreator::lambda([actor_id = actor_id(this), phone_number_prefix, language_code,
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);
CHECK(old_document != nullptr);
auto &new_document = documents_[new_id];
CHECK(!new_document);
CHECK(new_document == nullptr);
new_document = make_unique<GeneralDocument>(*old_document);
new_document->file_id = new_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) {
CHECK(node_id.is_valid());
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;
return is_added;
}
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);
if (is_removed) {
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;
}
CHECK(to_node_id.is_valid());
auto &to = nodes_[to_node_id];
auto &from = from_it->second;
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) {
CHECK(node_id.is_valid());
Node &node = nodes_[node_id];
if (!node.query) {
return;
@ -231,6 +235,7 @@ void FileReferenceManager::run_node(NodeId node_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 "
<< dest.generation << " from " << file_source_id;
CHECK(dest.node_id.is_valid());
auto &node = nodes_[dest.node_id];
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
<< " with generation " << dest.generation << " from " << file_source_id << ": " << status << " "
<< sub;
CHECK(dest.node_id.is_valid());
auto &node = nodes_[dest.node_id];
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();
VLOG(file_references) << "Repair file reference for file " << node_id << "/" << main_file_id;
node_id = main_file_id;
CHECK(node_id.is_valid());
auto &node = nodes_[node_id];
if (!node.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);
key += static_cast<int64>(f * std::cos(longitude) * 128) * 256;
key += static_cast<int64>(f * std::sin(longitude) * 128);
if (key == 0) {
key = 1;
}
return key;
}

View File

@ -1329,6 +1329,9 @@ void GroupCallManager::reload_group_call(InputGroupCallId input_group_call_id,
if (td_->auth_manager_->is_bot()) {
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];
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,
tl_object_ptr<telegram_api::BotInlineMessage> &&inline_message, int32 allowed_media_content_id, bool allow_invoice,
Photo *photo, Game *game) {
CHECK(query_id != 0);
if (result_id.empty()) {
return false;
}
InlineMessageContent content =
create_inline_message_content(td_, file_id, std::move(inline_message), allowed_media_content_id, photo, game);
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 &= 0x7FFFFFFFFFFFFFFF;
if (query_hash == 0) {
query_hash = 1;
}
auto it = inline_query_results_.find(query_hash);
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,
tl_object_ptr<telegram_api::messages_botResults> &&results) {
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);
return;
}

View File

@ -572,6 +572,10 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
auto all_infos = full_split(lang.second, '\x00');
if (all_infos.size() % 11 == 0) {
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;
info.name_ = std::move(all_infos[i + 1]);
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_);
if (language_pack_info->base_language_pack_id_ != language->base_language_code_) {
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_;
was_updated_base_language_code = true;
}
@ -1367,6 +1371,10 @@ void LanguagePackManager::on_get_language_pack_strings(
switch (result->get_id()) {
case telegram_api::langPackString::ID: {
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_);
if (it == language->ordinary_strings_.end()) {
key_count_delta++;
@ -1384,6 +1392,10 @@ void LanguagePackManager::on_get_language_pack_strings(
}
case telegram_api::langPackStringPluralized::ID: {
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_),
std::move(str->two_value_), std::move(str->few_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: {
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->pluralized_strings_.erase(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(
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";
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) {
auto id = ids[i];
auto date = ids[i + 1];
if (date < min_date) {
if (date < min_date || id == 0) {
is_changed = true;
continue;
}
@ -2249,6 +2249,9 @@ NotificationGroupId NotificationManager::get_call_notification_group_id(DialogId
if (it != dialog_id_to_call_notification_group_id_.end()) {
return it->second;
}
if (!dialog_id.is_valid()) {
return {};
}
if (available_call_notification_group_ids_.empty()) {
// 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 (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"));
if (announcement_id == 0) {
return Status::Error(200, "Receive unsupported announcement ID");
}
auto &date = announcement_id_date_[announcement_id];
auto now = G()->unix_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) {
return nullptr;
}
if (loaded_from_database_polls_.count(poll_id)) {
if (!poll_id.is_valid() || loaded_from_database_polls_.count(poll_id)) {
return nullptr;
}
@ -443,7 +443,7 @@ vector<int32> PollManager::get_vote_percentage(const vector<int32> &voter_counts
};
FlatHashMap<int32, Option> options;
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) {
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);
affected_option_ids[index]++;
affected_option_ids[index + 1]++;
}
for (size_t option_index = 0; option_index < poll->options.size(); option_index++) {
if (poll->options[option_index].is_chosen) {
if (poll->is_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) {
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,
uint64 log_event_id, Promise<Unit> &&promise) {
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];
if (!pending_answer.promises_.empty() && pending_answer.options_ == options) {
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) {
LOG(INFO) << "Add query " << query_id << " with" << (promise ? "" : "out") << " promise";
CHECK(query_id != 0);
auto &query = queries_[query_id];
if (promise) {
query.promises.push_back(std::move(promise));

View File

@ -25,6 +25,7 @@
#include "td/utils/Slice.h"
#include "td/utils/SliceBuilder.h"
#include <limits>
#include <memory>
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,
Promise<TdApiAuthorizationForm> promise) {
refcnt_++;
CHECK(max_authorization_form_id_ < std::numeric_limits<int32>::max());
auto authorization_form_id = ++max_authorization_form_id_;
auto &form = authorization_forms_[authorization_form_id];
form.bot_user_id = bot_user_id;

View File

@ -46,7 +46,6 @@
#include "td/utils/algorithm.h"
#include "td/utils/base64.h"
#include "td/utils/emoji.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h"
#include "td/utils/JsonBuilder.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);
CHECK(old_sticker != nullptr);
auto &new_sticker = stickers_[new_id];
CHECK(!new_sticker);
CHECK(new_sticker == nullptr);
new_sticker = make_unique<Sticker>(*old_sticker);
new_sticker->file_id = new_id;
// 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();
for (auto &document_ptr : documents) {
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;
}
@ -3187,8 +3186,16 @@ void StickersManager::load_reactions() {
auto status = log_event_parse(reactions_, reactions);
if (status.is_error()) {
LOG(ERROR) << "Can't load available reactions: " << status;
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";
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;
reaction.center_animation_ =
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() ||
!reaction.effect_animation_.is_valid()) {
if (!reaction.is_valid()) {
LOG(ERROR) << "Receive invalid reaction " << reaction.reaction_;
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_);
for (const auto &click : clicks) {
auto index = click.first;
if (index <= 0) {
return;
}
auto sticker_id = sticker_ids[index];
if (!sticker_id.is_valid()) {
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 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>
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);
CHECK(old_video_note != nullptr);
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->file_id = new_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);
CHECK(old_video != nullptr);
auto &new_video = videos_[new_id];
CHECK(!new_video);
CHECK(new_video == nullptr);
new_video = make_unique<Video>(*old_video);
new_video->file_id = new_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);
CHECK(old_voice_note != nullptr);
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->file_id = new_id;
return new_id;

View File

@ -36,6 +36,7 @@
#include "td/utils/tl_helpers.h"
#include <type_traits>
#include <unordered_map>
namespace td {
@ -47,7 +48,7 @@ struct GetWebPageBlockObjectContext {
bool is_first_pass_ = true;
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(

View File

@ -102,6 +102,10 @@ class GetWebPageQuery final : public Td::ResultHandler {
}
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;
url_ = url;
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);
}
if (!page->url.empty()) {
on_get_web_page_by_url(page->url, web_page_id, from_database);
}
if (is_changed && !from_database) {
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) {
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);
if (it != url_to_web_page_id_.end()) {
if (it->second == WebPageId()) {
@ -997,6 +1006,7 @@ void WebPagesManager::update_web_page_instant_view_load_requests(WebPageId web_p
}
return;
}
CHECK(new_web_page_id.is_valid());
if (web_page_instant_view->is_loaded) {
if (web_page_instant_view->is_full) {
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) {
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);
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) {
if (url.empty()) {
return promise.set_value(WebPageId());
}
if (!G()->parameters().use_message_db) {
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_id = document->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);
}
}
@ -1446,7 +1462,12 @@ void WebPagesManager::on_get_web_page_instant_view(WebPage *web_page, tl_object_
auto add_document = [&](const Document &document) {
auto file_view = td_->file_manager_->get_file_view(document.file_id);
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 {
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();
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";
auto web_page = std::move(log_event.web_page_out);
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) {
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());
return;
}
@ -1644,7 +1670,7 @@ const WebPagesManager::WebPage *WebPagesManager::get_web_page_force(WebPageId we
if (!G()->parameters().use_message_db) {
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;
}
@ -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) {
if (url.empty()) {
return FileSourceId();
}
auto web_page_id = get_web_page_by_url(url);
if (web_page_id.is_valid()) {
const WebPage *web_page = get_web_page(web_page_id);

View File

@ -247,8 +247,10 @@ class CliClient final : public Actor {
new_user.first_name = user.first_name_;
new_user.last_name = user.last_name_;
new_user.username = user.username_;
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) {
const User *user = &users_[user_id];
@ -1681,8 +1683,10 @@ class CliClient final : public Actor {
td_api::make_object<td_api::messageSendOptions>(disable_notification, from_background, true,
as_message_scheduling_state(schedule_date_)),
nullptr, std::move(input_message_content)));
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 {
return td_api::make_object<td_api::messageSendOptions>(false, false, false,

View File

@ -10,11 +10,11 @@
#include "td/telegram/files/FileType.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/StringBuilder.h"
#include "td/utils/tl_helpers.h"
#include <array>
#include <unordered_map>
namespace td {
@ -73,7 +73,7 @@ class FileStats {
using StatByType = std::array<FileTypeStat, MAX_FILE_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_;
void add_impl(const FullFileInfo &info);

View File

@ -19,7 +19,6 @@
#include "td/db/SqliteKeyValue.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
@ -32,6 +31,7 @@
#include "td/utils/tl_parsers.h"
#include <functional>
#include <unordered_map>
#include <unordered_set>
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());
}
FlatHashMap<size_t, size_t> hash_to_pos;
std::unordered_map<size_t, size_t> hash_to_pos;
size_t pos = 0;
for (auto &full_info : full_infos) {
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) {
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"));
}
auto &proxy = proxies_[proxy_id];
auto &proxy = it->second;
string url = G()->shared_config().get_option_string("t_me_url", "https://t.me/");
bool is_socks = false;
switch (proxy.type()) {
@ -1132,11 +1133,13 @@ void ConnectionCreator::start_up() {
if (begins_with(info.first, "_used")) {
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();
CHECK(proxy_id > 0);
proxy_last_used_date_[proxy_id] = last_used;
proxy_last_used_saved_date_[proxy_id] = last_used;
} else {
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();
CHECK(proxy_id > 0);
CHECK(proxies_.count(proxy_id) == 0);
log_event_parse(proxies_[proxy_id], info.second).ensure();
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) {
CHECK(container_id != 0);
td::remove_if(msg_ids, [&](uint64 msg_id) {
auto it = sent_queries_.find(msg_id);
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);
if (cit != sent_containers_.end()) {
auto container_info = std::move(cit->second);
sent_containers_.erase(cit);
for (auto message_id : container_info.message_ids) {
on_message_ack_impl_inner(message_id, type, true);
}
sent_containers_.erase(cit);
return;
}
@ -902,10 +905,11 @@ void Session::on_message_failed(uint64 id, Status status) {
auto cit = sent_containers_.find(id);
if (cit != sent_containers_.end()) {
auto container_info = std::move(cit->second);
sent_containers_.erase(cit);
for (auto message_id : container_info.message_ids) {
on_message_failed_inner(message_id, true);
}
sent_containers_.erase(cit);
return;
}

View File

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

View File

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

View File

@ -51,6 +51,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
if (it != buffer_.end()) {
it->second = std::move(value);
} else {
CHECK(!key.empty());
buffer_.emplace(std::move(key), std::move(value));
}
if (promise) {
@ -71,6 +72,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
if (it != buffer_.end()) {
it->second = optional<string>();
} else {
CHECK(!key.empty());
buffer_.emplace(std::move(key), optional<string>());
}
if (promise) {
@ -109,7 +111,7 @@ class SqliteKeyValueAsync final : public SqliteKeyValueAsyncInterface {
static constexpr double MAX_PENDING_QUERIES_DELAY = 0.01;
static constexpr size_t MAX_PENDING_QUERIES_COUNT = 100;
FlatHashMap<string, optional<string>> buffer_;
std::vector<Promise<Unit>> buffer_promises_;
vector<Promise<Unit>> buffer_promises_;
size_t cnt_ = 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 {
CHECK(raw_event.event_id.is_valid());
// 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;
}
auto &q = queues_[queue_id];
@ -139,6 +139,9 @@ class TQueueImpl final : public TQueue {
if (data.size() > MAX_EVENT_LENGTH) {
return Status::Error("Data is too big");
}
if (queue_id == 0) {
return Status::Error("Queue identifier is invalid");
}
auto &q = queues_[queue_id];
if (q.events.size() >= MAX_QUEUE_EVENTS) {

View File

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