diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index 7bf1fc0f..6b38ea87 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -268,7 +268,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface { LOG(INFO) << "Add " << full_message_id << " to database"; auto dialog_id = full_message_id.get_dialog_id(); auto message_id = full_message_id.get_message_id(); - CHECK(dialog_id.is_valid()); + LOG_CHECK(dialog_id.is_valid()) << dialog_id << ' ' << message_id << ' ' << full_message_id; CHECK(message_id.is_valid()); SCOPE_EXIT { add_message_stmt_.reset(); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 15f4a910..7c01b1a1 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -19977,8 +19977,8 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI if (date <= 0) { LOG(ERROR) << "Receive " << new_message_id << " in " << dialog_id << " with wrong date " << date; } else { - LOG_CHECK(sent_message->date > 0) << old_message_id << ' ' << sent_message->message_id << ' ' << sent_message->date - << ' ' << date; + LOG_CHECK(sent_message->date > 0) << old_message_id << ' ' << sent_message->message_id << ' ' << new_message_id + << ' ' << sent_message->date << ' ' << date; sent_message->date = date; CHECK(d->last_message_id != old_message_id); } diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 2ccb3e23..8f51a45c 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -597,6 +597,13 @@ void NotificationManager::on_get_message_notifications_from_database(Notificatio notifications.pop_back(); } } + auto first_message_id = get_first_message_id(group); + if (first_message_id.is_valid()) { + while (!notifications.empty() && notifications.back().type->get_message_id().get() >= first_message_id.get()) { + // possible if notifications was added after the database request was sent + notifications.pop_back(); + } + } add_notifications_to_group_begin(std::move(group_it), std::move(notifications)); @@ -761,8 +768,7 @@ void NotificationManager::try_reuse_notification_group_id(NotificationGroupId gr auto group_it = get_group(group_id); if (group_it != groups_.end()) { - CHECK(group_it->first.last_notification_date == 0); - LOG_CHECK(group_it->second.total_count == 0) + LOG_CHECK(group_it->first.last_notification_date == 0 && group_it->second.total_count == 0) << running_get_difference_ << " " << delayed_notification_update_count_ << " " << unreceived_notification_update_count_ << " " << pending_updates_[group_id.get()].size() << " " << group_it->first << " " << group_it->second; @@ -2091,6 +2097,7 @@ void NotificationManager::remove_temporary_notifications(NotificationGroupId gro } auto removed_notification_count = narrow_cast(old_group_size - notification_pos); if (removed_notification_count == 0) { + CHECK(get_temporary_notification_total_count(group_it->second) == 0); return; } @@ -2104,7 +2111,9 @@ void NotificationManager::remove_temporary_notifications(NotificationGroupId gro vector removed_notification_ids; for (auto i = notification_pos; i < old_group_size; i++) { - CHECK(group.notifications[i].type->is_temporary()); + LOG_CHECK(group.notifications[i].type->is_temporary()) + << notification_pos << ' ' << i << ' ' << old_group_size << ' ' << removed_notification_count << ' ' + << group.notifications[i] << ' ' << group << ' ' << group_it->first; VLOG(notifications) << "Remove temporary " << group.notifications[i] << " from " << group_id; auto notification_id = group.notifications[i].notification_id; on_notification_removed(notification_id); @@ -2139,6 +2148,7 @@ void NotificationManager::remove_temporary_notifications(NotificationGroupId gro group_id, [](const td_api::object_ptr ¬ification) { return notification->get_id() == td_api::notificationTypeNewPushMessage::ID; }); + CHECK(get_temporary_notification_total_count(group_it->second) == 0); } int32 NotificationManager::get_temporary_notification_total_count(const NotificationGroup &group) { @@ -2326,7 +2336,8 @@ void NotificationManager::remove_call_notification(DialogId dialog_id, CallId ca force_flush_pending_updates(group_id, "reuse call group_id"); auto group_it = get_group(group_id); - CHECK(group_it->first.dialog_id == dialog_id); + LOG_CHECK(group_it->first.dialog_id == dialog_id) + << group_id << ' ' << dialog_id << ' ' << group_it->first << ' ' << group_it->second; CHECK(group_it->first.last_notification_date == 0); CHECK(group_it->second.total_count == 0); CHECK(group_it->second.notifications.empty()); diff --git a/td/telegram/StickersManager.hpp b/td/telegram/StickersManager.hpp index ba6dbc5c..7fc38e1f 100644 --- a/td/telegram/StickersManager.hpp +++ b/td/telegram/StickersManager.hpp @@ -54,6 +54,10 @@ void StickersManager::store_sticker(FileId file_id, bool in_sticker_set, StorerT template FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { + if (parser.get_error() != nullptr) { + return FileId(); + } + auto sticker = make_unique(); bool has_sticker_set_access_hash; bool in_sticker_set_stored; @@ -62,10 +66,18 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { PARSE_FLAG(has_sticker_set_access_hash); PARSE_FLAG(in_sticker_set_stored); END_PARSE_FLAGS(); - LOG_CHECK(in_sticker_set_stored == in_sticker_set) - << in_sticker_set << " " << in_sticker_set_stored << " " << parser.version() << " " << sticker->is_mask << " " - << has_sticker_set_access_hash << " " - << format::as_hex_dump<4>(parser.template fetch_string_raw(parser.get_left_len())); + if (in_sticker_set_stored != in_sticker_set) { + Slice data = parser.template fetch_string_raw(parser.get_left_len()); + for (auto c : data) { + if (c != '\0') { + LOG_CHECK(in_sticker_set_stored == in_sticker_set) + << in_sticker_set << " " << in_sticker_set_stored << " " << parser.version() << " " << sticker->is_mask + << " " << has_sticker_set_access_hash << " " << format::as_hex_dump<4>(data); + } + } + parser.set_error("Zero sticker set is stored in the database"); + return FileId(); + } if (!in_sticker_set) { parse(sticker->set_id, parser); if (has_sticker_set_access_hash) { @@ -215,6 +227,9 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser } for (uint32 i = 0; i < stored_sticker_count; i++) { auto sticker_id = parse_sticker(true, parser); + if (parser.get_error() != nullptr) { + return; + } sticker_set->sticker_ids.push_back(sticker_id); Sticker *sticker = get_sticker(sticker_id); diff --git a/td/telegram/WebPageBlock.cpp b/td/telegram/WebPageBlock.cpp index 8abcd3ba..f962e5e6 100644 --- a/td/telegram/WebPageBlock.cpp +++ b/td/telegram/WebPageBlock.cpp @@ -2201,8 +2201,9 @@ void WebPageBlock::call_impl(Type type, const WebPageBlock *ptr, F &&f) { return f(static_cast(ptr)); case Type::Map: return f(static_cast(ptr)); + default: + UNREACHABLE(); } - UNREACHABLE(); } template @@ -2216,6 +2217,10 @@ template unique_ptr WebPageBlock::parse(ParserT &parser) { Type type; td::parse(type, parser); + if (static_cast(type) < 0 || static_cast(type) >= static_cast(Type::Size)) { + parser.set_error(PSTRING() << "Can't parse unknown BlockType " << static_cast(type)); + return nullptr; + } unique_ptr res; call_impl(type, nullptr, [&](const auto *ptr) { using ObjT = std::decay_t; diff --git a/td/telegram/WebPageBlock.h b/td/telegram/WebPageBlock.h index bde0267e..ef28ee01 100644 --- a/td/telegram/WebPageBlock.h +++ b/td/telegram/WebPageBlock.h @@ -51,7 +51,8 @@ class WebPageBlock { Table, Details, RelatedArticles, - Map + Map, + Size }; virtual Type get_type() const = 0; diff --git a/tdutils/td/utils/Hints.cpp b/tdutils/td/utils/Hints.cpp index 0d817f35..a9180e3a 100644 --- a/tdutils/td/utils/Hints.cpp +++ b/tdutils/td/utils/Hints.cpp @@ -33,7 +33,7 @@ vector Hints::fix_words(vector words) { return words; } -vector Hints::get_words(Slice name) { +vector Hints::get_words(Slice name, bool is_search) { bool in_word = false; string word; vector words; @@ -41,7 +41,7 @@ vector Hints::get_words(Slice name) { auto end = name.uend(); while (pos != end) { uint32 code; - pos = next_utf8_unsafe(pos, &code, "get_words"); + pos = next_utf8_unsafe(pos, &code, is_search ? "get_words_search" : "get_words_add"); code = prepare_search_character(code); if (code == 0) { @@ -93,7 +93,7 @@ void Hints::add(KeyT key, Slice name) { return; } vector old_transliterations; - for (auto &old_word : get_words(it->second)) { + for (auto &old_word : get_words(it->second, false)) { delete_word(old_word, key, word_to_keys_); for (auto &w : get_word_transliterations(old_word, false)) { @@ -115,7 +115,7 @@ void Hints::add(KeyT key, Slice name) { } vector transliterations; - for (auto &word : get_words(name)) { + for (auto &word : get_words(name, false)) { add_word(word, key, word_to_keys_); for (auto &w : get_word_transliterations(word, false)) { @@ -166,7 +166,7 @@ std::pair> Hints::search(Slice query, int32 limit, b return {key_to_name_.size(), std::move(results)}; } - auto words = get_words(query); + auto words = get_words(query, true); if (return_all_for_empty_query && words.empty()) { results.reserve(key_to_name_.size()); for (auto &it : key_to_name_) { diff --git a/tdutils/td/utils/Hints.h b/tdutils/td/utils/Hints.h index a5a06671..a0af1418 100644 --- a/tdutils/td/utils/Hints.h +++ b/tdutils/td/utils/Hints.h @@ -52,7 +52,7 @@ class Hints { static vector fix_words(vector words); - static vector get_words(Slice name); + static vector get_words(Slice name, bool is_search); static void add_search_results(vector &results, const string &word, const std::map> &word_to_keys);