summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Nicole <nicole@kolabsystems.com>2018-04-17 16:01:23 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-04-17 16:01:46 +0200
commit9db117c7e3b230729c73913932bf8b65760f5e98 (patch)
treea98ff6de339047ec5705cb2c0cc531cbe23ad559
parentcd81aed814286887911d99648d62bbb3c63e404c (diff)
downloadsink-9db117c7e3b230729c73913932bf8b65760f5e98.tar.gz
sink-9db117c7e3b230729c73913932bf8b65760f5e98.zip
Fix non-deterministic use after free in WebDAV
Summary: Reviewers: cmollekopf Tags: #sink Differential Revision: https://phabricator.kde.org/D12280
-rw-r--r--examples/webdavcommon/webdav.cpp51
1 files changed, 34 insertions, 17 deletions
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<void> runJob(KJob *job)
63 }); 63 });
64} 64}
65 65
66template <typename T>
67static KAsync::Job<T> runJob(KJob *job, const std::function<T(KJob *)> &func)
68{
69 return KAsync::start<T>([job, func](KAsync::Future<T> &future) {
70 QObject::connect(job, &KJob::result, [&future, func](KJob *job) {
71 SinkTrace() << "Job done: " << job->metaObject()->className();
72 if (job->error()) {
73 SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className() << job->error();
74 auto proxyError = translateDavError(job);
75 future.setError(proxyError, job->errorString());
76 } else {
77 future.setValue(func(job));
78 future.setFinished();
79 }
80 });
81 SinkTrace() << "Starting job: " << job->metaObject()->className();
82 job->start();
83 });
84}
85
66WebDavSynchronizer::WebDavSynchronizer(const Sink::ResourceContext &context, 86WebDavSynchronizer::WebDavSynchronizer(const Sink::ResourceContext &context,
67 KDAV2::Protocol protocol, QByteArray collectionName, QByteArray itemName) 87 KDAV2::Protocol protocol, QByteArray collectionName, QByteArray itemName)
68 : Sink::Synchronizer(context), 88 : Sink::Synchronizer(context),
@@ -100,16 +120,13 @@ KAsync::Job<void> WebDavSynchronizer::synchronizeWithSource(const Sink::QueryBas
100 120
101 SinkLog() << "Synchronizing" << query.type() << "through WebDAV at:" << serverUrl().url(); 121 SinkLog() << "Synchronizing" << query.type() << "through WebDAV at:" << serverUrl().url();
102 122
103 auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob{serverUrl()}; 123 auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob{ serverUrl() };
104 auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob](const KAsync::Error &error) { 124 auto job = runJob<KDAV2::DavCollection::List>(collectionsFetchJob,
105 if (error) { 125 [](KJob *job) { return static_cast<KDAV2::DavCollectionsFetchJob *>(job)->collections(); })
106 SinkWarning() << "Failed to synchronize collections:" << error; 126 .then([this](const KDAV2::DavCollection::List &collections) {
107 } else { 127 updateLocalCollections(collections);
108 updateLocalCollections(collectionsFetchJob->collections()); 128 return collections;
109 } 129 });
110
111 return collectionsFetchJob->collections();
112 });
113 130
114 if (query.type() == collectionName) { 131 if (query.type() == collectionName) {
115 // Do nothing more 132 // Do nothing more
@@ -167,11 +184,11 @@ KAsync::Job<void> WebDavSynchronizer::synchronizeCollection(const KDAV2::DavColl
167 auto cache = std::make_shared<KDAV2::EtagCache>(); 184 auto cache = std::make_shared<KDAV2::EtagCache>();
168 auto davItemsListJob = new KDAV2::DavItemsListJob(collection.url(), std::move(cache)); 185 auto davItemsListJob = new KDAV2::DavItemsListJob(collection.url(), std::move(cache));
169 186
170 return runJob(davItemsListJob) 187 return runJob<KDAV2::DavItem::List>(davItemsListJob,
171 .then([this, davItemsListJob, total] { 188 [](KJob *job) { return static_cast<KDAV2::DavItemsListJob *>(job)->items(); })
172 auto items = davItemsListJob->items(); 189 .then([this, total](const KDAV2::DavItem::List &items) {
173 *total += items.size(); 190 *total += items.size();
174 return KAsync::value(items); 191 return items;
175 }) 192 })
176 .serialEach([this, collectionRid, localRid, progress(std::move(progress)), total(std::move(total)), 193 .serialEach([this, collectionRid, localRid, progress(std::move(progress)), total(std::move(total)),
177 itemsResourceIDs(std::move(itemsResourceIDs))](const KDAV2::DavItem &item) { 194 itemsResourceIDs(std::move(itemsResourceIDs))](const KDAV2::DavItem &item) {
@@ -199,9 +216,9 @@ KAsync::Job<void> WebDavSynchronizer::synchronizeItem(const KDAV2::DavItem &item
199 auto etag = item.etag().toLatin1(); 216 auto etag = item.etag().toLatin1();
200 217
201 auto itemFetchJob = new KDAV2::DavItemFetchJob(item); 218 auto itemFetchJob = new KDAV2::DavItemFetchJob(item);
202 return runJob(itemFetchJob) 219 return runJob<KDAV2::DavItem>(
203 .then([this, itemFetchJob(std::move(itemFetchJob)), collectionLocalRid] { 220 itemFetchJob, [](KJob *job) { return static_cast<KDAV2::DavItemFetchJob *>(job)->item(); })
204 auto item = itemFetchJob->item(); 221 .then([this, collectionLocalRid](const KDAV2::DavItem &item) {
205 updateLocalItem(item, collectionLocalRid); 222 updateLocalItem(item, collectionLocalRid);
206 return item; 223 return item;
207 }) 224 })