Parse Content-Length as digits with surrounding whitespace only - #1221
Open
pjfanning wants to merge 1 commit into
Open
Parse Content-Length as digits with surrounding whitespace only#1221pjfanning wants to merge 1 commit into
pjfanning wants to merge 1 commit into
Conversation
Motivation: `ContentLengthParser` skipped whitespace anywhere in the field value, so `Content-Length: 1 2` was read as 12 and `Content-Length: 5 5` as 55, and an empty value was read as 0. The field value is `1*DIGIT` surrounded by optional whitespace (RFC 9110, section 8.6 and RFC 9112, section 5). Every other length ambiguity is rejected by this parser already: two differing Content-Length headers, a Transfer-Encoding other than a single chunked, and chunked together with a Content-Length. This was the remaining spot where pekko-http could read a body length that another implementation in the request path reads differently or rejects. Modification: Skip whitespace before and after the digits, but require at least one digit and stop the value at the first non-digit. Result: A Content-Length value with whitespace between digits, or without any digit, is rejected with the "Illegal `Content-Length` header value" error that other malformed values already produce. Values with leading or trailing whitespace keep parsing as before. Note this rejects two inputs that were accepted before: whitespace inside the digits, and an empty value that was read as 0. Tests: - sbt "http-core/testOnly org.apache.pekko.http.impl.engine.parsing.RequestParserCRLFSpec org.apache.pekko.http.impl.engine.parsing.RequestParserLFSpec org.apache.pekko.http.impl.engine.parsing.ResponseParserSpec" - pass, 2 new tests that both fail without the change; leading whitespace stays covered by the existing "Content-length: 17" tests - sbt http-core/test - pass - sbt http-tests/test - pass - sbt http-core/mimaReportBinaryIssues - pass - sbt http-core/scalafmt http-core/Test/scalafmt - clean References: None - tightens Content-Length parsing to the grammar
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
ContentLengthParserskips whitespace anywhere in the field value:So
Content-Length: 1 2is read as12,Content-Length: 5 5as55, and an emptyContent-Length:as0. The field value is1*DIGITsurrounded by optional whitespace (RFC 9110, section 8.6 and RFC 9112, section 5).The other ways two implementations could disagree about a body length are already closed here — two Content-Length headers with different values are rejected,
Transfer-Encodingaccepts only a singlechunked, andchunkedtogether with aContent-Lengthis rejected — which is what makes this one worth tightening: it is the remaining case where pekko-http reads a length that a proxy or another server in the request path reads differently, or rejects.Modification
Skip whitespace before and after the digits, require at least one digit, and end the value at the first non-digit.
Result
A value with whitespace between digits, or with no digit at all, is rejected with the same "Illegal `Content-Length` header value" error that other malformed values already produce. Leading and trailing whitespace still parse as before.
This rejects two inputs that were accepted before: whitespace inside the digits, and an empty value that used to be read as
0. Both are malformed per the grammar, but it is a behaviour change for anyone who was relying on the lenient reading.Tests
sbt "http-core/testOnly org.apache.pekko.http.impl.engine.parsing.RequestParserCRLFSpec org.apache.pekko.http.impl.engine.parsing.RequestParserLFSpec org.apache.pekko.http.impl.engine.parsing.ResponseParserSpec"- pass, with 2 new tests, one for whitespace inside the value and one for an empty value; both fail without the change. Leading whitespace stays covered by the existingContent-length: 17tests, so the accepted cases are pinned too.sbt http-core/test- pass (1218 tests)sbt http-tests/test- pass (1483 tests)sbt http-core/mimaReportBinaryIssues- passsbt http-core/scalafmt http-core/Test/scalafmt- cleanReferences
None - tightens Content-Length parsing to the grammar