QHttp2Connection: confirm successive remote stream IDs are higher

And it should also apply to the promised streams, not separate ID tracking.

https://datatracker.ietf.org/doc/html/rfc9113#section-5.1.1

Change-Id: I6826a39c98f9b6a585200e628533843db731a85b
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
(cherry picked from commit e247a6ce9ff83ef62424eef01d26cb752a4d2abc)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Mårten Nordheim 2024-02-16 15:47:56 +01:00
parent 36d14d76fd
commit 975ee89cea
2 changed files with 8 additions and 5 deletions

View File

@ -892,12 +892,16 @@ void QHttp2Connection::handleHEADERS()
if (streamID == connectionStreamID)
return connectionError(PROTOCOL_ERROR, "HEADERS on 0x0 stream");
if (QPointer<QHttp2Stream> stream = m_streams.value(streamID); !stream) {
if (streamID > m_lastIncomingStreamID) {
QHttp2Stream *newStream = createStreamInternal_impl(streamID);
m_lastIncomingStreamID = streamID;
qCDebug(qHttp2ConnectionLog, "[%p] Created new incoming stream %d", this, streamID);
emit newIncomingStream(newStream);
} else if (streamWasReset(streamID)) {
} else if (auto it = m_streams.constFind(streamID); it == m_streams.cend()) {
qCDebug(qHttp2ConnectionLog, "[%p] Received HEADERS on non-existent stream %d", this,
streamID);
return connectionError(PROTOCOL_ERROR, "HEADERS on invalid stream");
} else if (!*it || (*it)->wasReset()) {
qCDebug(qHttp2ConnectionLog, "[%p] Received HEADERS on reset stream %d", this, streamID);
return connectionError(ENHANCE_YOUR_CALM, "HEADERS on invalid stream");
}
@ -1048,13 +1052,13 @@ void QHttp2Connection::handlePUSH_PROMISE()
return connectionError(ENHANCE_YOUR_CALM, "PUSH_PROMISE with invalid associated stream");
const auto reservedID = qFromBigEndian<quint32>(inboundFrame.dataBegin());
if ((reservedID & 1) || reservedID <= lastPromisedID || reservedID > lastValidStreamID)
if ((reservedID & 1) || reservedID <= m_lastIncomingStreamID || reservedID > lastValidStreamID)
return connectionError(PROTOCOL_ERROR, "PUSH_PROMISE with invalid promised stream ID");
auto *stream = createStreamInternal_impl(reservedID);
if (!stream)
return connectionError(PROTOCOL_ERROR, "PUSH_PROMISE with already active stream ID");
lastPromisedID = reservedID;
m_lastIncomingStreamID = reservedID;
stream->setState(QHttp2Stream::State::ReservedRemote);
if (!pushPromiseEnabled) {

View File

@ -346,7 +346,6 @@ private:
bool m_upgradedConnection = false;
bool m_goingAway = false;
bool pushPromiseEnabled = false;
quint32 lastPromisedID = Http2::connectionStreamID;
quint32 m_lastIncomingStreamID = Http2::connectionStreamID;
// Server-side only: