Files
neochat/src/timeline/models/pinnedmessagemodel.cpp
Veres Károly 4371c3f7e5 Null check pinned messages after decryption when filling PinnedMessageModel.
`room()->decryptMessage()` returns null if the message fails to decode. Since elements of `m_pinnedEvents`
get directly dereferenced in getEventForIndex, storing null values leads to a segfault.
In this case we should retain the EncryptedEvent to let the UI report the error.

(cherry picked from commit b684fb451d)
2026-01-13 17:55:04 -05:00

73 lines
2.0 KiB
C++

// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "pinnedmessagemodel.h"
#include "enums/delegatetype.h"
#include "eventhandler.h"
#include "neochatroom.h"
#include <QGuiApplication>
#include <KLocalizedString>
using namespace Quotient;
PinnedMessageModel::PinnedMessageModel(QObject *parent)
: MessageModel(parent)
{
connect(this, &MessageModel::roomChanged, this, &PinnedMessageModel::fill);
}
bool PinnedMessageModel::loading() const
{
return m_loading;
}
int PinnedMessageModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_pinnedEvents.size();
}
std::optional<std::reference_wrapper<const Quotient::RoomEvent>> PinnedMessageModel::getEventForIndex(const QModelIndex index) const
{
if (static_cast<size_t>(index.row()) >= m_pinnedEvents.size() || index.row() < 0) {
return std::nullopt;
}
return std::reference_wrapper{*m_pinnedEvents[index.row()].get()};
}
void PinnedMessageModel::setLoading(bool loading)
{
m_loading = loading;
Q_EMIT loadingChanged();
}
void PinnedMessageModel::fill()
{
if (!m_room) {
return;
}
const auto events = m_room->pinnedEventIds();
for (const auto &event : std::as_const(events)) {
m_room->connection()->callApi<GetOneRoomEventJob>(m_room->id(), event).then([this](const auto &job) {
beginInsertRows({}, m_pinnedEvents.size(), m_pinnedEvents.size());
auto ev = fromJson<event_ptr_tt<RoomEvent>>(job->jsonData());
if (auto encEv = eventCast<EncryptedEvent>(ev.get())) {
auto decryptedEvent = room()->decryptMessage(*encEv);
if (decryptedEvent) {
ev = std::move(decryptedEvent);
}
}
m_pinnedEvents.push_back(std::move(ev));
Q_EMIT newEventAdded(m_pinnedEvents.back().get());
endInsertRows();
});
}
}
#include "moc_pinnedmessagemodel.cpp"