![](https://seccdn.libravatar.org/avatar/af22e20b6884acbc89be6d7736c43e92.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package libqmatrixclient for openSUSE:Factory checked in at 2020-03-31 17:17:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqmatrixclient (Old) and /work/SRC/openSUSE:Factory/.libqmatrixclient.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "libqmatrixclient" Tue Mar 31 17:17:51 2020 rev:7 rq:790121 version:0.5.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libqmatrixclient/libqmatrixclient.changes 2020-03-30 23:03:52.388192573 +0200 +++ /work/SRC/openSUSE:Factory/.libqmatrixclient.new.3160/libqmatrixclient.changes 2020-03-31 17:17:54.523729085 +0200 @@ -1,0 +2,12 @@ +Tue Mar 31 11:29:21 UTC 2020 - ecsos@opensuse.org + +- Update to 0.5.3.1 + One more "sustaining" release that fixes a long-standing problem + with job objects lifetime lasting beyond their connection + lifetime, leading to crashes on connection removal (#397/#398). + This problem became very apparent with introduction of SSO in + Quaternion, where connection objects are removed as soon as the + login dialog is cancelled; this release is aimed solely at fixing + that. + +------------------------------------------------------------------- Old: ---- libqmatrixclient-0.5.3.tar.gz New: ---- libqmatrixclient-0.5.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqmatrixclient.spec ++++++ --- /var/tmp/diff_new_pack.XojZhb/_old 2020-03-31 17:17:55.599729768 +0200 +++ /var/tmp/diff_new_pack.XojZhb/_new 2020-03-31 17:17:55.599729768 +0200 @@ -22,7 +22,7 @@ %define sname libQuotient Name: libqmatrixclient -Version: 0.5.3 +Version: 0.5.3.1 Release: 0 Summary: Library for Qt Matrix Clients License: LGPL-2.1-only ++++++ libqmatrixclient-0.5.3.tar.gz -> libqmatrixclient-0.5.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libQuotient-0.5.3/CMakeLists.txt new/libQuotient-0.5.3.1/CMakeLists.txt --- old/libQuotient-0.5.3/CMakeLists.txt 2020-03-27 18:07:13.000000000 +0100 +++ new/libQuotient-0.5.3.1/CMakeLists.txt 2020-03-31 07:46:55.000000000 +0200 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.1) set(API_VERSION "0.5.1") # Normally it should just include major.minor -project(qmatrixclient VERSION "0.5.3" LANGUAGES CXX) +project(qmatrixclient VERSION "0.5.3.1" LANGUAGES CXX) option(QMATRIXCLIENT_INSTALL_EXAMPLE "install qmc-example application" ON) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libQuotient-0.5.3/lib/connection.cpp new/libQuotient-0.5.3.1/lib/connection.cpp --- old/libQuotient-0.5.3/lib/connection.cpp 2020-03-27 18:07:13.000000000 +0100 +++ new/libQuotient-0.5.3.1/lib/connection.cpp 2020-03-31 07:46:55.000000000 +0200 @@ -175,52 +175,60 @@ maybeBaseUrl.setScheme("https"); // Instead of the Qt-default "http" if (!match.hasMatch() || !maybeBaseUrl.isValid()) { - emit resolveError( - tr("%1 is not a valid homeserver address") - .arg(maybeBaseUrl.toString())); + emit resolveError(tr("%1 is not a valid homeserver address") + .arg(maybeBaseUrl.toString())); return; } - setHomeserver(maybeBaseUrl); - auto domain = maybeBaseUrl.host(); qCDebug(MAIN) << "Finding the server" << domain; + d->data->setBaseUrl(maybeBaseUrl); // Just enough to check .well-known file auto getWellKnownJob = callApi<GetWellknownJob>(); - connect(getWellKnownJob, &BaseJob::finished, [this, getWellKnownJob, maybeBaseUrl] { - if (getWellKnownJob->status() == BaseJob::NotFoundError) { - qCDebug(MAIN) << "No .well-known file, IGNORE"; - } else if (getWellKnownJob->status() != BaseJob::Success) { - qCDebug(MAIN) << "Fetching .well-known file failed, FAIL_PROMPT"; - emit resolveError(tr("Fetching .well-known file failed")); - return; - } else if (getWellKnownJob->data().homeserver.baseUrl.isEmpty()) { - qCDebug(MAIN) << "base_url not provided, FAIL_PROMPT"; - emit resolveError(tr("base_url not provided")); - return; - } else if (!QUrl(getWellKnownJob->data().homeserver.baseUrl).isValid()) { - qCDebug(MAIN) << "base_url invalid, FAIL_ERROR"; - emit resolveError(tr("base_url invalid")); - return; - } else { - QUrl baseUrl(getWellKnownJob->data().homeserver.baseUrl); - - qCDebug(MAIN) << ".well-known for" << maybeBaseUrl.host() << "is" << baseUrl.authority(); - setHomeserver(baseUrl); - } - - auto getVersionsJob = callApi<GetVersionsJob>(); - - connect(getVersionsJob, &BaseJob::finished, [this, getVersionsJob] { - if (getVersionsJob->status() == BaseJob::Success) { - qCDebug(MAIN) << "homeserver url is valid"; - emit resolved(); + // This is a workaround for 0.5.x; due to the way Quaternion's login dialog + // operates, Connection can disappear any moment during server resolution. + // Quotient 0.6 will reparent all jobs to enforce lifetimes. See also #398. + getWellKnownJob->setParent(this); + connect(getWellKnownJob, &BaseJob::finished, this, + [this, getWellKnownJob, maybeBaseUrl] { + if (getWellKnownJob->status() != BaseJob::NotFoundError) { + if (getWellKnownJob->status() != BaseJob::Success) { + qCWarning(MAIN) + << "Fetching .well-known file failed, FAIL_PROMPT"; + emit resolveError(tr("Failed resolving the homeserver")); + return; + } + QUrl baseUrl { getWellKnownJob->data().homeserver.baseUrl }; + if (baseUrl.isEmpty()) { + qCWarning(MAIN) << "base_url not provided, FAIL_PROMPT"; + emit resolveError( + tr("The homeserver base URL is not provided")); + return; + } + if (!baseUrl.isValid()) { + qCWarning(MAIN) << "base_url invalid, FAIL_ERROR"; + emit resolveError(tr("The homeserver base URL is invalid")); + return; + } + qCInfo(MAIN) << ".well-known URL for" << maybeBaseUrl.host() + << "is" << baseUrl.authority(); + setHomeserver(baseUrl); } else { - qCDebug(MAIN) << "homeserver url invalid"; - emit resolveError(tr("homeserver url invalid")); + qCInfo(MAIN) << "No .well-known file, using" << maybeBaseUrl + << "for base URL"; + setHomeserver(maybeBaseUrl); } + + auto getVersionsJob = callApi<GetVersionsJob>(); + getVersionsJob->setParent(this); // Same workaround as above + connect(getVersionsJob, &BaseJob::success, this, + &Connection::resolved); + connect(getVersionsJob, &BaseJob::failure, this, [this] { + qCWarning(MAIN) << "Homeserver base URL invalid"; + emit resolveError(tr("The homeserver base URL " + "doesn't seem to work")); + }); }); - }); } inline UserIdentifier makeUserIdentifier(const QString& id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libQuotient-0.5.3/lib/jobs/basejob.cpp new/libQuotient-0.5.3.1/lib/jobs/basejob.cpp --- old/libQuotient-0.5.3/lib/jobs/basejob.cpp 2020-03-27 18:07:13.000000000 +0100 +++ new/libQuotient-0.5.3.1/lib/jobs/basejob.cpp 2020-03-31 07:46:55.000000000 +0200 @@ -104,6 +104,7 @@ BaseJob::~BaseJob() { stop(); + d->retryTimer.stop(); // See #398 qCDebug(d->logCat) << this << "destroyed"; } @@ -210,6 +211,7 @@ // some sources claim that there are issues with QT 5.8 req.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); #endif + Q_ASSERT(req.url().isValid()); for (auto it = requestHeaders.cbegin(); it != requestHeaders.cend(); ++it) req.setRawHeader(it.key(), it.value()); switch( verb ) @@ -240,16 +242,23 @@ void BaseJob::start(const ConnectionData* connData, bool inBackground) { - d->connection = connData; - d->retryTimer.setSingleShot(true); - connect (&d->retryTimer, &QTimer::timeout, - this, [this,inBackground] { sendRequest(inBackground); }); - - beforeStart(connData); - if (status().good()) - sendRequest(inBackground); - if (status().good()) - afterStart(connData, d->reply.data()); + if (connData && connData->baseUrl().isValid()) { + d->connection = connData; + d->retryTimer.setSingleShot(true); + connect(&d->retryTimer, &QTimer::timeout, this, + [this, inBackground] { sendRequest(inBackground); }); + + beforeStart(connData); + if (status().good()) + sendRequest(inBackground); + if (status().good()) + afterStart(connData, d->reply.data()); + } else { + qCCritical(d->logCat) + << "Developers, ensure the Connection is valid before using it"; + Q_ASSERT(false); + setStatus(IncorrectRequestError, tr("Invalid server connection")); + } if (!status().good()) QTimer::singleShot(0, this, &BaseJob::finishJob); } @@ -641,6 +650,8 @@ void BaseJob::abandon() { beforeAbandon(d->reply ? d->reply.data() : nullptr); + d->timer.stop(); + d->retryTimer.stop(); // In case abandon() was called between retries setStatus(Abandoned); if (d->reply) d->reply->disconnect(this);