diff options
author | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2022-01-06 13:29:23 +0200 |
---|---|---|
committer | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2022-01-11 10:50:19 +0000 |
commit | 74883726deeebea14faca65663339271f1c2c547 (patch) | |
tree | d085f28f47c86d6dae2adff7786b159a87a75755 /src/libs/installer | |
parent | 7ae530a1e013463cd24e13b2b3c5eb86528c7cb7 (diff) |
Fix segfaults when failing to fetch compressed repositories
The ComponentModel object was not always reset in case we already got
to the point of clearing the source data (deleted components owned by
PackageManagerCore from previous fetch) and failed after that, leaving
the model with dangling pointers to the deleted component objects.
If we were already on ComponentSelectionPage, this would cause
segmentation faults when the component tree view using the model would
be shown again after fetch.
Task-number: QTIFW-2441
Change-Id: Ie779de5ca0a3c4ae895ea507e6be4a2f7343501e
Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs/installer')
-rw-r--r-- | src/libs/installer/componentmodel.cpp | 6 | ||||
-rw-r--r-- | src/libs/installer/componentmodel.h | 2 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 11 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 1 |
4 files changed, 12 insertions, 8 deletions
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp index dcecf74ce..88e502164 100644 --- a/src/libs/installer/componentmodel.cpp +++ b/src/libs/installer/componentmodel.cpp @@ -386,13 +386,13 @@ Component *ComponentModel::componentFromIndex(const QModelIndex &index) const // -- public slots /*! - Sets \a rootComponents to be the list of currently shown components. + Resets model and sets \a rootComponents to be the list of currently shown components. The model is repopulated and the individual component's checked state is used to show the check mark in front of the visual component representation. The modelAboutToBeReset() and modelReset() signals are emitted. */ -void ComponentModel::setRootComponents(QList<QInstaller::Component*> rootComponents) +void ComponentModel::reset(QList<Component *> rootComponents) { beginResetModel(); @@ -464,7 +464,7 @@ void ComponentModel::setCheckedState(QInstaller::ComponentModel::ModelStateFlag void ComponentModel::onVirtualStateChanged() { // If the virtual state of a component changes, force a reset of the component model. - setRootComponents(m_core->components(PackageManagerCore::ComponentType::Root)); + reset(m_core->components(PackageManagerCore::ComponentType::Root)); } diff --git a/src/libs/installer/componentmodel.h b/src/libs/installer/componentmodel.h index e5cd2c57d..829c95111 100644 --- a/src/libs/installer/componentmodel.h +++ b/src/libs/installer/componentmodel.h @@ -86,7 +86,7 @@ public: Component* componentFromIndex(const QModelIndex &index) const; public Q_SLOTS: - void setRootComponents(QList<QInstaller::Component*> rootComponents); + void reset(QList<Component *> rootComponents = QList<Component *>()); void setCheckedState(QInstaller::ComponentModel::ModelStateFlag state); Q_SIGNALS: diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 5ebe44d6c..010a68d21 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -2250,8 +2250,11 @@ ComponentModel *PackageManagerCore::defaultComponentModel() const d->m_defaultModel = componentModel(const_cast<PackageManagerCore*> (this), QLatin1String("AllComponentsModel")); } + connect(this, &PackageManagerCore::startAllComponentsReset, [&] { + d->m_defaultModel->reset(); + }); connect(this, &PackageManagerCore::finishAllComponentsReset, d->m_defaultModel, - &ComponentModel::setRootComponents); + &ComponentModel::reset); return d->m_defaultModel; } @@ -2265,8 +2268,11 @@ ComponentModel *PackageManagerCore::updaterComponentModel() const d->m_updaterModel = componentModel(const_cast<PackageManagerCore*> (this), QLatin1String("UpdaterComponentsModel")); } + connect(this, &PackageManagerCore::startUpdaterComponentsReset, [&] { + d->m_updaterModel->reset(); + }); connect(this, &PackageManagerCore::finishUpdaterComponentsReset, d->m_updaterModel, - &ComponentModel::setRootComponents); + &ComponentModel::reset); return d->m_updaterModel; } @@ -4118,7 +4124,6 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const } } catch (const Error &error) { d->clearUpdaterComponentLists(); - emit finishUpdaterComponentsReset(QList<QInstaller::Component*>()); d->setStatus(Failure, error.message()); // TODO: make sure we remove all message boxes inside the library at some point. diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 948093ad7..38909b4ea 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -474,7 +474,6 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c } catch (const Error &error) { clearAllComponentLists(); - emit m_core->finishAllComponentsReset(QList<QInstaller::Component*>()); setStatus(PackageManagerCore::Failure, error.message()); // TODO: make sure we remove all message boxes inside the library at some point. |