From 12a24dd473fffc48263bd786ace5d6f7e06a8968 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 1 May 2024 15:02:35 +0400 Subject: [PATCH] Fix possible crash in common groups list. Currently Data::Session::processChat() may change adminRights(), that may change Data::CanSendAnyOf(peer, ...), that may lead to Window::SessionController::updateThirdColumnToCurrentChat() call, that destroys current third column to replace it with another one. If common groups list was opened in the third column this will crash. Fixes #27640. --- .../info_common_groups_inner_widget.cpp | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp b/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp index 720f47eba..37defed0d 100644 --- a/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp +++ b/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/common_groups/info_common_groups_inner_widget.h" +#include "base/weak_ptr.h" #include "info/common_groups/info_common_groups_widget.h" #include "info/info_controller.h" #include "lang/lang_keys.h" @@ -27,7 +28,9 @@ namespace { constexpr auto kCommonGroupsPerPage = 40; constexpr auto kCommonGroupsSearchAfter = 20; -class ListController final : public PeerListController { +class ListController final + : public PeerListController + , public base::has_weak_ptr { public: ListController( not_null controller, @@ -108,16 +111,30 @@ void ListController::loadMoreRows() { return data.vchats().v; }); if (!chats.empty()) { + auto add = std::vector>(); + auto allLoaded = _allLoaded; + auto preloadGroupId = _preloadGroupId; + const auto owner = &_user->owner(); + const auto weak = base::make_weak(this); for (const auto &chat : chats) { - if (const auto peer = _user->owner().processChat(chat)) { + if (const auto peer = owner->processChat(chat)) { if (!peer->migrateTo()) { - delegate()->peerListAppendRow( - createRow(peer)); + add.push_back(peer); } - _preloadGroupId = peer->id; - _allLoaded = false; + preloadGroupId = peer->id; + allLoaded = false; } } + if (!weak) { + return; + } + for (const auto &peer : add) { + if (!delegate()->peerListFindRow(peer->id.value)) { + delegate()->peerListAppendRow(createRow(peer)); + } + } + _preloadGroupId = preloadGroupId; + _allLoaded = allLoaded; delegate()->peerListRefreshRows(); } auto fullCount = delegate()->peerListFullRowsCount();