Stop parsing chunks once the chunk count limit is reached - #1220
Open
pjfanning wants to merge 1 commit into
Open
Stop parsing chunks once the chunk count limit is reached#1220pjfanning wants to merge 1 commit into
pjfanning wants to merge 1 commit into
Conversation
Motivation: The `max-chunk-count` check in `HttpMessageParser.parseChunkBody` has no `else` branch, so the `StateResult` of `failEntityStream` is discarded and parsing continues after the error has been emitted: the current chunk is emitted, the parser trampolines into the next one, and every following chunk in the buffer emits another error. The parser therefore keeps producing output after it has set itself to terminated. A consumer that stops at the first error does not notice, which is why the behaviour has gone unseen; the parser still does the work. Modification: Put the rest of `parseChunkBody` into the `else` branch of the check, the way the other limits in this parser are written. Result: Nothing is emitted after the chunk count error, and the parser stops parsing the rest of the body. Tests: - sbt "http-core/testOnly org.apache.pekko.http.impl.engine.parsing.RequestParserCRLFSpec org.apache.pekko.http.impl.engine.parsing.RequestParserLFSpec" - pass, 1 new test that collects the raw parser output; without the change it sees the chunks "a", "b", "c", "" instead of "a", "b" - sbt http-core/test - pass - sbt http-core/mimaReportBinaryIssues - pass - sbt http-core/scalafmt http-core/Test/scalafmt - clean References: None - makes the max-chunk-count limit stop parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The
max-chunk-countcheck inHttpMessageParser.parseChunkBodyis missing itselse:failEntityStreamdoes not throw — it emits anEntityStreamError, setsterminated = trueand returns aStateResult(done()isnull). Its result is dropped here, so after the error the parser emits the current chunk, continues with the next one, and emits a further error for every remaining chunk in the buffer, i.e. it keeps producing output after it has terminated itself. Every other limit in this parser is written asif (cond) failEntityStream(...) else <continue>.This is not a bypass: the error is emitted before the chunk, so a consumer that stops at the first error still fails the entity stream, which is presumably why it went unnoticed — there is no test for
max-chunk-countin the repo. But the parser does work it should not, and it emits the whole rest of the body behind the error.Modification
Move the rest of
parseChunkBodyinto theelsebranch of the check.Result
Nothing is emitted after the chunk count error and the parser stops parsing the remainder of the body.
Tests
sbt "http-core/testOnly org.apache.pekko.http.impl.engine.parsing.RequestParserCRLFSpec org.apache.pekko.http.impl.engine.parsing.RequestParserLFSpec"- pass, with a new test that collects the raw parser output for a body of three chunks withmax-chunk-count = 2. It asserts that only the chunks"a"and"b"are emitted and that the error is the last output. Without the change the parser emits"a", "b", "c", "", so the test fails. It deliberately reads the parser output directly, because the existing harness cancels the rest of the stream at the first error and therefore cannot see the difference.sbt http-core/test- pass (1216 tests)sbt http-core/mimaReportBinaryIssues- passsbt http-core/scalafmt http-core/Test/scalafmt- cleanReferences
None - makes the max-chunk-count limit stop parsing