Fix crash in ChannelsLimitBox.

Fixes https://bugs.telegram.org/c/35214

Deleting `placeholder` in content->heightValue() resulted in `delete`
sometimes being called deep inside the layer->show() which already had
a reference to that `placeholder` saved and was accessed after -> crash.
This commit is contained in:
John Preston 2024-01-04 09:33:13 +04:00
parent c7f11eb05a
commit d2246337a2
1 changed files with 28 additions and 13 deletions

View File

@ -68,6 +68,8 @@ public:
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;
[[nodiscard]] rpl::producer<int> countValue() const;
private:
void appendRow(not_null<PeerData*> peer, TimeId date);
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
@ -75,6 +77,7 @@ private:
TimeId date) const;
const not_null<Main::Session*> _session;
rpl::variable<int> _count;
mtpRequestId _requestId = 0;
};
@ -91,12 +94,15 @@ public:
void rowClicked(not_null<PeerListRow*> row) override;
void rowRightActionClicked(not_null<PeerListRow*> row) override;
[[nodiscard]] rpl::producer<int> countValue() const;
private:
void appendRow(not_null<PeerData*> peer);
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
not_null<PeerData*> peer) const;
const not_null<Window::SessionNavigation*> _navigation;
rpl::variable<int> _count;
Fn<void()> _closeBox;
mtpRequestId _requestId = 0;
@ -210,17 +216,17 @@ void InactiveController::prepare() {
_requestId = _session->api().request(MTPchannels_GetInactiveChannels(
)).done([=](const MTPmessages_InactiveChats &result) {
_requestId = 0;
result.match([&](const MTPDmessages_inactiveChats &data) {
_session->data().processUsers(data.vusers());
const auto &list = data.vchats().v;
const auto &dates = data.vdates().v;
for (auto i = 0, count = int(list.size()); i != count; ++i) {
const auto peer = _session->data().processChat(list[i]);
const auto date = (i < dates.size()) ? dates[i].v : TimeId();
appendRow(peer, date);
}
delegate()->peerListRefreshRows();
});
const auto &data = result.data();
_session->data().processUsers(data.vusers());
const auto &list = data.vchats().v;
const auto &dates = data.vdates().v;
for (auto i = 0, count = int(list.size()); i != count; ++i) {
const auto peer = _session->data().processChat(list[i]);
const auto date = (i < dates.size()) ? dates[i].v : TimeId();
appendRow(peer, date);
}
delegate()->peerListRefreshRows();
_count = delegate()->peerListFullRowsCount();
}).send();
}
@ -228,6 +234,10 @@ void InactiveController::rowClicked(not_null<PeerListRow*> row) {
delegate()->peerListSetRowChecked(row, !row->checked());
}
rpl::producer<int> InactiveController::countValue() const {
return _count.value();
}
void InactiveController::appendRow(
not_null<PeerData*> participant,
TimeId date) {
@ -296,6 +306,10 @@ Main::Session &PublicsController::session() const {
return _navigation->session();
}
rpl::producer<int> PublicsController::countValue() const {
return _count.value();
}
void PublicsController::prepare() {
_requestId = _navigation->session().api().request(
MTPchannels_GetAdminedPublicChannels(MTP_flags(0))
@ -315,6 +329,7 @@ void PublicsController::prepare() {
}
delegate()->peerListRefreshRows();
}
_count = delegate()->peerListFullRowsCount();
}).send();
}
@ -571,7 +586,7 @@ void ChannelsLimitBox(
{});
using namespace rpl::mappers;
content->heightValue(
controller->countValue(
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
delete placeholder;
}, placeholder->lifetime());
@ -662,7 +677,7 @@ void PublicLinksLimitBox(
{});
using namespace rpl::mappers;
content->heightValue(
controller->countValue(
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
delete placeholder;
}, placeholder->lifetime());