diff options
author | Lorn Potter <lorn.potter@gmail.com> | 2020-05-09 08:32:43 +1000 |
---|---|---|
committer | Lorn Potter <lorn.potter@gmail.com> | 2020-05-25 17:41:49 +1000 |
commit | 745a7fa31e3e56a9c645334811b8f4298d680323 (patch) | |
tree | fd5c4d8128de26b2d0cb3b2ade54e7e738855ef2 /src/network/access | |
parent | f061c413de2e3fdc4cc1578f420651a7c45da3e9 (diff) |
wasm: fix heap crash when making multiple network calls
Pick-to: 5.15
Task-number: QTBUG-83991
Change-Id: I354934b53799f3eeb958395932bed18289b1e279
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl.cpp | 41 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl_p.h | 2 |
2 files changed, 23 insertions, 20 deletions
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 5b84014789..73fd139607 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -221,7 +221,7 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() if (headersData.count() > 0) { const char* customHeaders[arrayLength]; int i = 0; - for (i; i < headersData.count() * 2; (i = i + 2)) { + for (i; i < headersData.count(); i++) { customHeaders[i] = headersData[i].constData(); customHeaders[i + 1] = request.rawHeader(headersData[i]).constData(); } @@ -365,24 +365,28 @@ static int parseHeaderName(const QByteArray &headerName) } -void QNetworkReplyWasmImplPrivate::headersReceived(const QString &bufferString) +void QNetworkReplyWasmImplPrivate::headersReceived(const QByteArray &buffer) { Q_Q(QNetworkReplyWasmImpl); - if (!bufferString.isEmpty()) { - QStringList headers = bufferString.split(QString::fromUtf8("\r\n"), Qt::SkipEmptyParts); + if (!buffer.isEmpty()) { + QList<QByteArray> headers = buffer.split('\n'); + for (int i = 0; i < headers.size(); i++) { - QString headerName = headers.at(i).split(QString::fromUtf8(": ")).at(0); - QString headersValue = headers.at(i).split(QString::fromUtf8(": ")).at(1); - if (headerName.isEmpty() || headersValue.isEmpty()) - continue; + if (headers.at(i).contains(':')) { // headers include final \x00, so skip + QByteArray headerName = headers.at(i).split(': ').at(0).trimmed(); + QByteArray headersValue = headers.at(i).split(': ').at(1).trimmed(); + + if (headerName.isEmpty() || headersValue.isEmpty()) + continue; - int headerIndex = parseHeaderName(headerName.toLocal8Bit()); + int headerIndex = parseHeaderName(headerName); - if (headerIndex == -1) - q->setRawHeader(headerName.toLocal8Bit(), headersValue.toLocal8Bit()); - else - q->setHeader(static_cast<QNetworkRequest::KnownHeaders>(headerIndex), (QVariant)headersValue); + if (headerIndex == -1) + q->setRawHeader(headerName, headersValue); + else + q->setHeader(static_cast<QNetworkRequest::KnownHeaders>(headerIndex), (QVariant)headersValue); + } } } emit q->metaDataChanged(); @@ -463,12 +467,11 @@ void QNetworkReplyWasmImplPrivate::stateChange(emscripten_fetch_t *fetch) { if (fetch->readyState == /*HEADERS_RECEIVED*/ 2) { size_t headerLength = emscripten_fetch_get_response_headers_length(fetch); - char *dst = nullptr; - emscripten_fetch_get_response_headers(fetch, dst, headerLength + 1); - std::string str = dst; - QNetworkReplyWasmImplPrivate *reply = - reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); - reply->headersReceived(QString::fromStdString(str)); + QByteArray str(headerLength, Qt::Uninitialized); + emscripten_fetch_get_response_headers(fetch, str.data(), str.size()); + QNetworkReplyWasmImplPrivate *reply = + reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + reply->headersReceived(str); } } diff --git a/src/network/access/qnetworkreplywasmimpl_p.h b/src/network/access/qnetworkreplywasmimpl_p.h index 5463ce8a98..3c18342c6c 100644 --- a/src/network/access/qnetworkreplywasmimpl_p.h +++ b/src/network/access/qnetworkreplywasmimpl_p.h @@ -110,7 +110,7 @@ public: void emitReplyError(QNetworkReply::NetworkError errorCode, const QString &); void emitDataReadProgress(qint64 done, qint64 total); void dataReceived(const QByteArray &buffer, int bufferSize); - void headersReceived(const QString &bufferString); + void headersReceived(const QByteArray &buffer); void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData); |