ActivityListModel: fix possible crash in slotActivitiesReceived

Backtrace from the crash reporter:

Crash: EXCEPTION_ACCESS_VIOLATION_READ at 0x401
  File "moc_activitylistmo_M5OEXJ7XGJYTWT.cpp", line 92, in OCC::ActivityListModel::qt_static_metacall
  File "qobject.cpp", line 3730, in QMetaObject::activate
  File "moc_networkjobs_7AMNCW4BBANVRK.cpp", line 1342, in OCC::JsonApiJob::jsonReceived
  File "networkjobs.cpp", line 714, in OCC::JsonApiJob::finished
  File "abstractnetworkjob.cpp", line 207, in OCC::AbstractNetworkJob::slotFinished
  File "moc_abstractnetwor_PFI2TXGQHRE33H.cpp", line 98, in OCC::AbstractNetworkJob::qt_static_metacall
  File "qobject.cpp", line 3730, in QMetaObject::activate
  File "moc_qnetworkreply.cpp", line 367, in QNetworkReply::finished
  File "qnetworkreplyhttpimpl.cpp", line 2100, in QNetworkReplyHttpImplPrivate::finished
  File "qnetworkreplyhttpimpl.cpp", line 279, in QNetworkReplyHttpImpl::abort

My theory is that the AccountState stored in a property of the job was destroyed.
before the job timed out.
Therefore, the qobject_cast within the qvariant_cast would call the metaObject()
virtual function on a dangling pointer.

Fix it by storing a QPointer instead which will track the deletion.
This commit is contained in:
Olivier Goffart 2017-03-06 16:14:09 +01:00 committed by Olivier Goffart
parent f862c626a1
commit f4495c5c80

View file

@ -27,6 +27,10 @@
#include "activitydata.h"
#include "activitylistmodel.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
Q_DECLARE_METATYPE(QPointer<OCC::AccountState>)
#endif
namespace OCC {
ActivityListModel::ActivityListModel(QWidget *parent)
@ -122,7 +126,7 @@ void ActivityListModel::startFetchJob(AccountState* s)
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
job->setProperty("AccountStatePtr", QVariant::fromValue<QPointer<AccountState>>(s));
QList< QPair<QString,QString> > params;
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
@ -139,7 +143,10 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
auto activities = json.value("ocs").toMap().value("data").toList();
ActivityList list;
AccountState* ast = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
auto ast = qvariant_cast<QPointer<AccountState>>(sender()->property("AccountStatePtr"));
if (!ast)
return;
_currentlyFetching.remove(ast);
foreach( auto activ, activities ) {