summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <tmpsantos@gmail.com>2018-11-13 02:32:35 +0200
committerThiago Marcos P. Santos <tmpsantos@gmail.com>2018-11-13 23:26:34 +0200
commit253ba55f1f05a16e90102191e0e8adf636eb198a (patch)
treed41fb44b3e28572340e514119293da0c9b0c6d80
parentcd92a231b3e11c65321a48d0167898bb0e5a5fa8 (diff)
downloadqtlocation-mapboxgl-253ba55f1f05a16e90102191e0e8adf636eb198a.tar.gz
[qt] Fix crash on Qt filesource
When opening many maps and sharing the same filesource: - Say we open around 30 maps and they all have the same style. - They will all request the same sprite.json, but Qt filesource will restrict simultaneous request to 20. - Mapbox GL will send some sprite.json to the filesource and queue some internally along with other requests. - When the first sprite.json arrives and the Qt filesource calls the callback, Mapbox GL will synchronously push queued requests to the Qt filesource when a request is handled. - We are walking a QVector dispatching sprite.json requests, but more requests get added to this QVector while we are walking it using an iterator. - That corrupts the iterator and we get a crash. The fix is simple, just pop items from the QVector until it is empty instead of using iterators.
-rw-r--r--platform/qt/src/http_file_source.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/platform/qt/src/http_file_source.cpp b/platform/qt/src/http_file_source.cpp
index 90abdd0aa3..f4fb0749a6 100644
--- a/platform/qt/src/http_file_source.cpp
+++ b/platform/qt/src/http_file_source.cpp
@@ -75,8 +75,12 @@ void HTTPFileSource::Impl::onReplyFinished()
QByteArray data = reply->readAll();
QVector<HTTPRequest*>& requestsVector = it.value().second;
- for (auto req : requestsVector) {
- req->handleNetworkReply(reply, data);
+
+ // Cannot use the iterator to walk the requestsVector
+ // because calling handleNetworkReply() might get
+ // requests added to the requestsVector.
+ while (!requestsVector.isEmpty()) {
+ requestsVector.takeFirst()->handleNetworkReply(reply, data);
}
m_pending.erase(it);