diff options
author | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2018-11-13 02:32:35 +0200 |
---|---|---|
committer | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2018-11-13 23:26:34 +0200 |
commit | 253ba55f1f05a16e90102191e0e8adf636eb198a (patch) | |
tree | d41fb44b3e28572340e514119293da0c9b0c6d80 /platform/qt | |
parent | cd92a231b3e11c65321a48d0167898bb0e5a5fa8 (diff) | |
download | qtlocation-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.
Diffstat (limited to 'platform/qt')
-rw-r--r-- | platform/qt/src/http_file_source.cpp | 8 |
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); |