Add more checks for server StoryId.

This commit is contained in:
levlam 2023-08-10 20:22:12 +03:00
parent 7d06883668
commit b12ade01f6
7 changed files with 74 additions and 26 deletions

View File

@ -13643,6 +13643,14 @@ void ContactsManager::on_update_user_story_ids_impl(User *u, UserId user_id, Sto
if (td_->auth_manager_->is_bot()) {
return;
}
if (max_active_story_id != StoryId() && !max_active_story_id.is_server()) {
LOG(ERROR) << "Receive max active " << max_active_story_id << " for " << user_id;
return;
}
if (max_read_story_id != StoryId() && !max_read_story_id.is_server()) {
LOG(ERROR) << "Receive max read " << max_read_story_id << " for " << user_id;
return;
}
auto has_unread_stories = get_has_unread_stories(u, user_id);
if (u->max_active_story_id != max_active_story_id) {

View File

@ -1867,7 +1867,7 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
PARSE_FLAG(m->via_mention);
END_PARSE_FLAGS();
parse(m->story_full_id, parser);
if (!m->story_full_id.is_valid()) {
if (!m->story_full_id.is_server()) {
is_bad = true;
}
content = std::move(m);
@ -2295,6 +2295,9 @@ static Result<InputMessageContent> create_input_message_content(
story_sender_dialog_id.get_type() != DialogType::User) {
return Status::Error(400, "Story not found");
}
if (!story_id.is_server()) {
return Status::Error(400, "Story can't be forwarded");
}
if (td->contacts_manager_->get_input_user(story_sender_dialog_id.get_user_id()).is_error()) {
return Status::Error(400, "Can't access the user");
}
@ -5031,7 +5034,7 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
auto dialog_id = DialogId(UserId(media->user_id_));
auto story_id = StoryId(media->id_);
auto story_full_id = StoryFullId(dialog_id, story_id);
if (!story_full_id.is_valid()) {
if (!story_full_id.is_server()) {
LOG(ERROR) << "Receive " << to_string(media);
break;
}

View File

@ -24216,7 +24216,7 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
"messageReplyToMessage"),
m->reply_to_message_id.get());
}
if (m->reply_to_story_full_id.get_story_id() != StoryId()) {
if (m->reply_to_story_full_id.is_valid()) {
return td_api::make_object<td_api::messageReplyToStory>(
get_chat_id_object(m->reply_to_story_full_id.get_dialog_id(), "messageReplyToStory"),
m->reply_to_story_full_id.get_story_id().get());

View File

@ -127,10 +127,9 @@ class StoryDbImpl final : public StoryDbSyncInterface {
void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, BufferSlice data) final {
LOG(INFO) << "Add " << story_full_id << " to database";
CHECK(story_full_id.is_server());
auto dialog_id = story_full_id.get_dialog_id();
auto story_id = story_full_id.get_story_id();
LOG_CHECK(dialog_id.is_valid()) << dialog_id << ' ' << story_id << ' ' << story_full_id;
CHECK(story_id.is_valid());
SCOPE_EXIT {
add_story_stmt_.reset();
};
@ -154,10 +153,9 @@ class StoryDbImpl final : public StoryDbSyncInterface {
void delete_story(StoryFullId story_full_id) final {
LOG(INFO) << "Delete " << story_full_id << " from database";
CHECK(story_full_id.is_valid());
auto dialog_id = story_full_id.get_dialog_id();
auto story_id = story_full_id.get_story_id();
CHECK(dialog_id.is_valid());
CHECK(story_id.is_valid());
SCOPE_EXIT {
delete_story_stmt_.reset();
};
@ -167,10 +165,9 @@ class StoryDbImpl final : public StoryDbSyncInterface {
}
Result<BufferSlice> get_story(StoryFullId story_full_id) final {
CHECK(story_full_id.is_server());
auto dialog_id = story_full_id.get_dialog_id();
auto story_id = story_full_id.get_story_id();
CHECK(dialog_id.is_valid());
CHECK(story_id.is_valid());
SCOPE_EXIT {
get_story_stmt_.reset();
};

View File

@ -47,6 +47,10 @@ struct StoryFullId {
return dialog_id.is_valid() && story_id.is_valid();
}
bool is_server() const {
return dialog_id.is_valid() && story_id.is_server();
}
template <class StorerT>
void store(StorerT &storer) const {
dialog_id.store(storer);

View File

@ -1004,7 +1004,7 @@ template <class StorerT>
void StoryManager::SavedActiveStories::store(StorerT &storer) const {
using td::store;
CHECK(!story_infos_.empty());
bool has_max_read_story_id = max_read_story_id_ != StoryId();
bool has_max_read_story_id = max_read_story_id_.is_valid();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_max_read_story_id);
END_STORE_FLAGS();
@ -1311,7 +1311,8 @@ StoryManager::Story *StoryManager::get_story_force(StoryFullId story_full_id, co
}
if (!G()->use_message_database() || failed_to_load_story_full_ids_.count(story_full_id) > 0 ||
is_inaccessible_story(story_full_id) || deleted_story_full_ids_.count(story_full_id) > 0) {
is_inaccessible_story(story_full_id) || deleted_story_full_ids_.count(story_full_id) > 0 ||
!story_full_id.get_story_id().is_server()) {
return nullptr;
}
@ -1340,6 +1341,11 @@ unique_ptr<StoryManager::Story> StoryManager::parse_story(StoryFullId story_full
delete_story_from_database(story_full_id);
return nullptr;
}
if (!story_full_id.get_story_id().is_server()) {
LOG(ERROR) << "Receive " << story_full_id << " from database";
delete_story_from_database(story_full_id);
return nullptr;
}
auto owner_dialog_id = story_full_id.get_dialog_id();
if (is_active_story(story.get())) {
@ -2193,6 +2199,9 @@ void StoryManager::set_story_reaction(StoryFullId story_full_id, ReactionType re
if (!story_full_id.get_story_id().is_valid()) {
return promise.set_error(Status::Error(400, "Invalid story identifier specified"));
}
if (!story_full_id.get_story_id().is_server()) {
return promise.set_error(Status::Error(400, "Can't react to the story"));
}
Story *story = get_story_force(story_full_id, "set_story_reaction");
if (story == nullptr) {
@ -2330,6 +2339,7 @@ uint64 StoryManager::save_read_stories_on_server_log_event(DialogId dialog_id, S
}
void StoryManager::read_stories_on_server(DialogId owner_dialog_id, StoryId story_id, uint64 log_event_id) {
CHECK(story_id.is_server());
if (log_event_id == 0 && G()->use_message_database()) {
log_event_id = save_read_stories_on_server_log_event(owner_dialog_id, story_id);
}
@ -2435,6 +2445,9 @@ void StoryManager::report_story(StoryFullId story_full_id, ReportReason &&reason
if (!have_story_force(story_full_id)) {
return promise.set_error(Status::Error(400, "Story not found"));
}
if (!story_full_id.is_server()) {
return promise.set_error(Status::Error(400, "Story can't be reported"));
}
td_->create_handler<ReportStoryQuery>(std::move(promise))->send(story_full_id, std::move(reason));
}
@ -2474,7 +2487,7 @@ void StoryManager::register_story(StoryFullId story_full_id, FullMessageId full_
if (td_->auth_manager_->is_bot()) {
return;
}
CHECK(story_full_id.is_valid());
CHECK(story_full_id.is_server());
LOG(INFO) << "Register " << story_full_id << " from " << full_message_id << " from " << source;
story_messages_[story_full_id].insert(full_message_id);
@ -2484,7 +2497,7 @@ void StoryManager::unregister_story(StoryFullId story_full_id, FullMessageId ful
if (td_->auth_manager_->is_bot()) {
return;
}
CHECK(story_full_id.is_valid());
CHECK(story_full_id.is_server());
LOG(INFO) << "Unregister " << story_full_id << " from " << full_message_id << " from " << source;
auto &message_ids = story_messages_[story_full_id];
auto is_deleted = message_ids.erase(full_message_id) > 0;
@ -2496,11 +2509,12 @@ void StoryManager::unregister_story(StoryFullId story_full_id, FullMessageId ful
StoryManager::StoryInfo StoryManager::get_story_info(StoryFullId story_full_id) const {
const auto *story = get_story(story_full_id);
if (story == nullptr || !is_active_story(story)) {
auto story_id = story_full_id.get_story_id();
if (story == nullptr || (story_id.is_server() && !is_active_story(story))) {
return {};
}
StoryInfo story_info;
story_info.story_id_ = story_full_id.get_story_id();
story_info.story_id_ = story_id;
story_info.date_ = story->date_;
story_info.expire_date_ = story->expire_date_;
story_info.is_for_close_friends_ = story->is_for_close_friends_;
@ -2980,15 +2994,19 @@ void StoryManager::delete_story_from_database(StoryFullId story_full_id) {
void StoryManager::on_story_changed(StoryFullId story_full_id, const Story *story, bool is_changed,
bool need_save_to_database, bool from_database) {
if (!story_full_id.get_story_id().is_server()) {
return;
}
if (is_active_story(story)) {
CHECK(story->global_id_ > 0);
story_expire_timeout_.set_timeout_in(story->global_id_, story->expire_date_ - G()->unix_time());
}
if (can_get_story_viewers(story_full_id, story, true).is_ok()) {
CHECK(story->global_id_ > 0);
story_can_get_viewers_timeout_.set_timeout_in(story->global_id_,
get_story_viewers_expire_date(story) - G()->unix_time() + 2);
}
if (story->content_ == nullptr || !story_full_id.get_story_id().is_valid()) {
if (story->content_ == nullptr) {
return;
}
if (is_changed || need_save_to_database) {
@ -3026,6 +3044,7 @@ void StoryManager::on_story_changed(StoryFullId story_full_id, const Story *stor
}
void StoryManager::register_story_global_id(StoryFullId story_full_id, Story *story) {
CHECK(story_full_id.is_server());
CHECK(story->global_id_ == 0);
story->global_id_ = ++max_story_global_id_;
stories_by_global_id_[story->global_id_] = story_full_id;
@ -3159,6 +3178,8 @@ void StoryManager::on_update_active_stories(DialogId owner_dialog_id, StoryId ma
}
if (story_ids.empty() || max_read_story_id.get() < story_ids[0].get()) {
max_read_story_id = StoryId();
} else if (max_read_story_id != StoryId()) {
CHECK(max_read_story_id.is_server());
}
LOG(INFO) << "Update active stories in " << owner_dialog_id << " to " << story_ids << " with max read "
@ -3367,6 +3388,10 @@ bool StoryManager::on_update_read_stories(DialogId owner_dialog_id, StoryId max_
if (!td_->messages_manager_->have_dialog_info_force(owner_dialog_id)) {
return false;
}
if (max_read_story_id != StoryId() && !max_read_story_id.is_server()) {
LOG(ERROR) << "Receive max read " << max_read_story_id;
return false;
}
auto active_stories = get_active_stories_force(owner_dialog_id, "on_update_read_stories");
if (active_stories == nullptr) {
LOG(INFO) << "Can't find active stories in " << owner_dialog_id;
@ -3570,7 +3595,7 @@ FileSourceId StoryManager::get_story_file_source_id(StoryFullId story_full_id) {
return FileSourceId();
}
if (!story_full_id.is_valid()) {
if (!story_full_id.is_server()) {
return FileSourceId();
}
@ -3641,12 +3666,9 @@ void StoryManager::get_story(DialogId owner_dialog_id, StoryId story_id, bool on
if (!td_->messages_manager_->have_input_peer(owner_dialog_id, AccessRights::Read)) {
return promise.set_error(Status::Error(400, "Can't access the story sender"));
}
if (!story_id.is_server()) {
if (!story_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid story identifier specified"));
}
if (owner_dialog_id.get_type() != DialogType::User) {
return promise.set_value(nullptr);
}
StoryFullId story_full_id{owner_dialog_id, story_id};
const Story *story = get_story_force(story_full_id, "get_story");
@ -3656,7 +3678,7 @@ void StoryManager::get_story(DialogId owner_dialog_id, StoryId story_id, bool on
}
return promise.set_value(get_story_object(story_full_id, story));
}
if (only_local) {
if (only_local || owner_dialog_id.get_type() != DialogType::User || !story_id.is_server()) {
return promise.set_value(nullptr);
}
@ -4117,6 +4139,9 @@ void StoryManager::set_story_privacy_settings(StoryId story_id,
if (story == nullptr || story->content_ == nullptr) {
return promise.set_error(Status::Error(400, "Story not found"));
}
if (!story_id.is_server()) {
return promise.set_error(Status::Error(400, "Story privacy settings can't be edited"));
}
TRY_RESULT_PROMISE(promise, privacy_rules,
UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(settings)));
td_->create_handler<EditStoryPrivacyQuery>(std::move(promise))->send(dialog_id, story_id, std::move(privacy_rules));
@ -4128,6 +4153,9 @@ void StoryManager::toggle_story_is_pinned(StoryId story_id, bool is_pinned, Prom
if (story == nullptr || story->content_ == nullptr) {
return promise.set_error(Status::Error(400, "Story not found"));
}
if (!story_id.is_server()) {
return promise.set_error(Status::Error(400, "Story can't be pinned/unpinned"));
}
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), story_id, is_pinned, promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) {
@ -4157,9 +4185,13 @@ void StoryManager::delete_story(StoryId story_id, Promise<Unit> &&promise) {
if (story == nullptr) {
return promise.set_error(Status::Error(400, "Story not found"));
}
if (!story_id.is_server()) {
if (!story_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid story identifier"));
}
if (!story_id.is_server()) {
// TODO
return promise.set_error(Status::Error(400, "Story deletion isn't supported"));
}
delete_story_on_server(story_full_id, 0, std::move(promise));
}
@ -4187,7 +4219,7 @@ uint64 StoryManager::save_delete_story_on_server_log_event(StoryFullId story_ful
void StoryManager::delete_story_on_server(StoryFullId story_full_id, uint64 log_event_id, Promise<Unit> &&promise) {
LOG(INFO) << "Delete " << story_full_id << " from server";
CHECK(story_full_id.is_valid());
CHECK(story_full_id.is_server());
if (log_event_id == 0) {
log_event_id = save_delete_story_on_server_log_event(story_full_id);
@ -4217,6 +4249,10 @@ telegram_api::object_ptr<telegram_api::InputMedia> StoryManager::get_input_media
void StoryManager::remove_story_notifications_by_story_ids(DialogId dialog_id, const vector<StoryId> &story_ids) {
VLOG(notifications) << "Trying to remove notification about " << story_ids << " in " << dialog_id;
for (auto story_id : story_ids) {
if (!story_id.is_server()) {
LOG(ERROR) << "Tried to delete " << story_id << " in " << dialog_id;
continue;
}
StoryFullId story_full_id{dialog_id, story_id};
if (!have_story_force(story_full_id)) {
LOG(INFO) << "Can't delete " << story_full_id << " because it is not found";

View File

@ -396,7 +396,7 @@ class WebPagesManager::WebPage {
}
if (has_story_full_ids) {
parse(story_full_ids, parser);
td::remove_if(story_full_ids, [](StoryFullId story_full_id) { return !story_full_id.is_valid(); });
td::remove_if(story_full_ids, [](StoryFullId story_full_id) { return !story_full_id.is_server(); });
}
if (has_instant_view) {
@ -547,7 +547,7 @@ WebPageId WebPagesManager::on_get_web_page(tl_object_ptr<telegram_api::WebPage>
auto dialog_id = DialogId(UserId(attribute->user_id_));
auto story_id = StoryId(attribute->id_);
auto story_full_id = StoryFullId(dialog_id, story_id);
if (!story_full_id.is_valid()) {
if (!story_full_id.is_server()) {
LOG(ERROR) << "Receive " << to_string(attribute);
break;
}