From 9db117c7e3b230729c73913932bf8b65760f5e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Nicole?= Date: Tue, 17 Apr 2018 16:01:23 +0200 Subject: Fix non-deterministic use after free in WebDAV Summary: Reviewers: cmollekopf Tags: #sink Differential Revision: https://phabricator.kde.org/D12280 --- examples/webdavcommon/webdav.cpp | 51 ++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'examples/webdavcommon') diff --git a/examples/webdavcommon/webdav.cpp b/examples/webdavcommon/webdav.cpp index 05b5348..ad1af35 100644 --- a/examples/webdavcommon/webdav.cpp +++ b/examples/webdavcommon/webdav.cpp @@ -63,6 +63,26 @@ static KAsync::Job runJob(KJob *job) }); } +template +static KAsync::Job runJob(KJob *job, const std::function &func) +{ + return KAsync::start([job, func](KAsync::Future &future) { + QObject::connect(job, &KJob::result, [&future, func](KJob *job) { + SinkTrace() << "Job done: " << job->metaObject()->className(); + if (job->error()) { + SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className() << job->error(); + auto proxyError = translateDavError(job); + future.setError(proxyError, job->errorString()); + } else { + future.setValue(func(job)); + future.setFinished(); + } + }); + SinkTrace() << "Starting job: " << job->metaObject()->className(); + job->start(); + }); +} + WebDavSynchronizer::WebDavSynchronizer(const Sink::ResourceContext &context, KDAV2::Protocol protocol, QByteArray collectionName, QByteArray itemName) : Sink::Synchronizer(context), @@ -100,16 +120,13 @@ KAsync::Job WebDavSynchronizer::synchronizeWithSource(const Sink::QueryBas SinkLog() << "Synchronizing" << query.type() << "through WebDAV at:" << serverUrl().url(); - auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob{serverUrl()}; - auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob](const KAsync::Error &error) { - if (error) { - SinkWarning() << "Failed to synchronize collections:" << error; - } else { - updateLocalCollections(collectionsFetchJob->collections()); - } - - return collectionsFetchJob->collections(); - }); + auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob{ serverUrl() }; + auto job = runJob(collectionsFetchJob, + [](KJob *job) { return static_cast(job)->collections(); }) + .then([this](const KDAV2::DavCollection::List &collections) { + updateLocalCollections(collections); + return collections; + }); if (query.type() == collectionName) { // Do nothing more @@ -167,11 +184,11 @@ KAsync::Job WebDavSynchronizer::synchronizeCollection(const KDAV2::DavColl auto cache = std::make_shared(); auto davItemsListJob = new KDAV2::DavItemsListJob(collection.url(), std::move(cache)); - return runJob(davItemsListJob) - .then([this, davItemsListJob, total] { - auto items = davItemsListJob->items(); + return runJob(davItemsListJob, + [](KJob *job) { return static_cast(job)->items(); }) + .then([this, total](const KDAV2::DavItem::List &items) { *total += items.size(); - return KAsync::value(items); + return items; }) .serialEach([this, collectionRid, localRid, progress(std::move(progress)), total(std::move(total)), itemsResourceIDs(std::move(itemsResourceIDs))](const KDAV2::DavItem &item) { @@ -199,9 +216,9 @@ KAsync::Job WebDavSynchronizer::synchronizeItem(const KDAV2::DavItem &item auto etag = item.etag().toLatin1(); auto itemFetchJob = new KDAV2::DavItemFetchJob(item); - return runJob(itemFetchJob) - .then([this, itemFetchJob(std::move(itemFetchJob)), collectionLocalRid] { - auto item = itemFetchJob->item(); + return runJob( + itemFetchJob, [](KJob *job) { return static_cast(job)->item(); }) + .then([this, collectionLocalRid](const KDAV2::DavItem &item) { updateLocalItem(item, collectionLocalRid); return item; }) -- cgit v1.2.3