From a14dbffb65a502af09ff86bb16ce5320a57c7d68 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 18 Sep 2023 10:57:43 +0400 Subject: [PATCH] Fix possible crash in pinned message deletion. --- .../SourceFiles/history/history_widget.cpp | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 6a0f06df8..4e5661a63 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6607,12 +6607,21 @@ void HistoryWidget::checkPinnedBarState() { std::move(pinnedRefreshed), std::move(markupRefreshed) ) | rpl::map([=](Ui::MessageBarContent &&content, bool, HistoryItem*) { - if (!content.title.isEmpty() || !content.text.empty()) { - _list->setShownPinned( - session().data().message( - _pinnedTracker->currentMessageId().message)); - } else { - _list->setShownPinned(nullptr); + const auto id = (!content.title.isEmpty() || !content.text.empty()) + ? _pinnedTracker->currentMessageId().message + : FullMsgId(); + if (const auto list = _list.data()) { + // Sometimes we get here with non-empty content and id of + // message that is being deleted right now. We get here in + // the moment when _itemRemoved was already fired (so in + // the _list the _pinnedItem is already cleared) and the + // MessageUpdate::Flag::Destroyed being fired right now, + // so the message is still in Data::Session. So we need to + // call data().message() async, otherwise we get a nearly- + // destroyed message from it and save the pointer in _list. + crl::on_main(list, [=] { + list->setShownPinned(session().data().message(id)); + }); } return std::move(content); }));