From ccb162cfed3d635d4db72d46aaa80ad5bfd99c85 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 25 Apr 2025 20:00:13 -0400 Subject: [PATCH] Set CppOwnership for managed QObjects returned by Q_INVOKABLES I'm 99% sure of the recent crashes we've been seeing are double-frees, the QCache one me and Duha encountered must be one. The QCache is in charge of the one in ContentProvider, so it will sometimes try to delete or access something already destroyed by the QML engine. While I'm at it, I also made sure to check every other Q_INVOKABLE to ensure we don't hit this elsewhere. CCBUG: 502747 --- src/libneochat/models/roomlistmodel.cpp | 5 ++++- src/timeline/contentprovider.cpp | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libneochat/models/roomlistmodel.cpp b/src/libneochat/models/roomlistmodel.cpp index 25e1c9c78..e9084c4ab 100644 --- a/src/libneochat/models/roomlistmodel.cpp +++ b/src/libneochat/models/roomlistmodel.cpp @@ -96,7 +96,9 @@ void RoomListModel::doResetModel() NeoChatRoom *RoomListModel::roomAt(int row) const { - return m_rooms.at(row); + auto room = m_rooms.at(row); + QQmlEngine::setObjectOwnership(room, QQmlEngine::CppOwnership); + return room; } void RoomListModel::doAddRoom(Room *r) @@ -309,6 +311,7 @@ NeoChatRoom *RoomListModel::roomByAliasOrId(const QString &aliasOrId) { for (const auto &room : std::as_const(m_rooms)) { if (room->aliases().contains(aliasOrId) || room->id() == aliasOrId) { + QQmlEngine::setObjectOwnership(room, QQmlEngine::CppOwnership); return room; } } diff --git a/src/timeline/contentprovider.cpp b/src/timeline/contentprovider.cpp index 51f0ff292..824dc4399 100644 --- a/src/timeline/contentprovider.cpp +++ b/src/timeline/contentprovider.cpp @@ -21,7 +21,9 @@ MessageContentModel *ContentProvider::contentModelForEvent(NeoChatRoom *room, co } if (!m_eventContentModels.contains(evtOrTxnId)) { - m_eventContentModels.insert(evtOrTxnId, new MessageContentModel(room, evtOrTxnId, isReply)); + auto model = new MessageContentModel(room, evtOrTxnId, isReply); + QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership); + m_eventContentModels.insert(evtOrTxnId, model); } return m_eventContentModels.object(evtOrTxnId); @@ -80,7 +82,9 @@ ThreadModel *ContentProvider::modelForThread(NeoChatRoom *room, const QString &t } if (!m_threadModels.contains(threadRootId)) { - m_threadModels.insert(threadRootId, new ThreadModel(threadRootId, room)); + auto model = new ThreadModel(threadRootId, room); + QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership); + m_threadModels.insert(threadRootId, model); } return m_threadModels.object(threadRootId); @@ -100,7 +104,9 @@ PollHandler *ContentProvider::handlerForPoll(NeoChatRoom *room, const QString &e } if (!m_pollHandlers.contains(eventId)) { - m_pollHandlers.insert(eventId, new PollHandler(room, eventId)); + auto pollHandler = new PollHandler(room, eventId); + QQmlEngine::setObjectOwnership(pollHandler, QQmlEngine::CppOwnership); + m_pollHandlers.insert(eventId, pollHandler); } return m_pollHandlers.object(eventId);