From cc78cdd9acd6f3d77a3764ee1bc52627abfb1d9d Mon Sep 17 00:00:00 2001 From: yeshanshan Date: Thu, 30 Apr 2026 14:52:40 +0800 Subject: [PATCH] fix: prevent crash from invalid indexes in window monitoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add validity checks for model indexes and window pointers to prevent crashes when accessing data from window monitoring models. The crash occurred in treeland environment due to accessing invalid indexes or null window pointers, particularly in the `data()` methods of `AbstractWindowMonitor` and `RoleCombineModel`, and when matching windows in `TaskManager::handleWindowAdded`. Log: Fixed a crash in the dock's window monitoring system by adding null and index validity checks Influence: 1. Test dock stability under treeland by switching between multiple windows rapidly 2. Verify dock does not crash when adding/removing windows dynamically 3. Test with invalid model states (empty models, invalid indexes) 4. Verify window matching still works correctly for active apps 5. Test combination models with various role mappings fix: 修复窗口监控中无效索引导致的崩溃问题 在窗口监控模型中增加模型索引和窗口指针的有效性检查,防止因访问 无效索引或空窗口指针导致崩溃。该崩溃在 treeland 环境下偶发,主要 由 `AbstractWindowMonitor` 和 `RoleCombineModel` 的数据访问方法以及 `TaskManager::handleWindowAdded` 中的窗口匹配逻辑引起。 Log: 修复了 dock 窗口监控系统中因缺少空指针和索引有效性检查导致的崩溃 问题 Influence: 1. 在 treeland 环境下快速切换多个窗口测试 dock 稳定性 2. 验证动态添加/删除窗口时 dock 不会崩溃 3. 测试空模型和无效索引等异常状态 4. 验证活跃应用的窗口匹配功能正常 5. 测试多种角色映射的组合模型 --- panels/dock/taskmanager/abstractwindowmonitor.cpp | 11 ++++++++--- panels/dock/taskmanager/rolecombinemodel.cpp | 13 +++++++++++-- panels/dock/taskmanager/taskmanager.cpp | 7 +++++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/panels/dock/taskmanager/abstractwindowmonitor.cpp b/panels/dock/taskmanager/abstractwindowmonitor.cpp index 7f526a05a..ae07623d3 100644 --- a/panels/dock/taskmanager/abstractwindowmonitor.cpp +++ b/panels/dock/taskmanager/abstractwindowmonitor.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -76,10 +76,15 @@ void AbstractWindowMonitor::requestWindowsView(const QModelIndexList &indexes) c QVariant AbstractWindowMonitor::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return QVariant(); + auto pos = index.row(); - if (pos >= m_trackedWindows.size()) + if (pos < 0 || pos >= m_trackedWindows.size()) + return QVariant(); + auto window = m_trackedWindows.value(pos, nullptr); + if (!window) return QVariant(); - auto window = m_trackedWindows[pos]; switch (role) { case TaskManager::WinIdRole: diff --git a/panels/dock/taskmanager/rolecombinemodel.cpp b/panels/dock/taskmanager/rolecombinemodel.cpp index 23b59eebf..bb5345180 100644 --- a/panels/dock/taskmanager/rolecombinemodel.cpp +++ b/panels/dock/taskmanager/rolecombinemodel.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -342,6 +342,10 @@ int RoleCombineModel::columnCount(const QModelIndex &parent) const QVariant RoleCombineModel::data(const QModelIndex &index, int role) const { + if (!index.isValid() || !sourceModel()) { + return QVariant(); + } + if (m_minorRolesMap.contains(role)) { auto majorKey = qMakePair(index.row(), index.column()); auto mapping = m_indexMap.value(majorKey, qMakePair(-1, -1)); @@ -355,7 +359,12 @@ QVariant RoleCombineModel::data(const QModelIndex &index, int role) const return m_minor->data(m_minor->index(row, column), m_minorRolesMap[role]); } else { - return sourceModel()->data(sourceModel()->index(index.row(), index.column()), role); + auto sourceIndex = sourceModel()->index(index.row(), index.column()); + if (!sourceIndex.isValid()) { + return QVariant(); + } + + return sourceModel()->data(sourceIndex, role); } } diff --git a/panels/dock/taskmanager/taskmanager.cpp b/panels/dock/taskmanager/taskmanager.cpp index 3ad7f76b8..0c64335f5 100644 --- a/panels/dock/taskmanager/taskmanager.cpp +++ b/panels/dock/taskmanager/taskmanager.cpp @@ -327,8 +327,11 @@ void TaskManager::handleWindowAdded(QPointer window) // TODO: remove below code and use use model replaced. QModelIndexList res; - if (m_activeAppModel) { - res = m_activeAppModel->match(m_activeAppModel->index(0, 0), TaskManager::WinIdRole, window->id()); + if (m_activeAppModel && m_activeAppModel->rowCount() > 0) { + auto startIndex = m_activeAppModel->index(0, 0); + if (startIndex.isValid()) { + res = m_activeAppModel->match(startIndex, TaskManager::WinIdRole, window->id()); + } } QSharedPointer desktopfile = nullptr;