Skip to content

Commit

Permalink
Parse entire HTTP chunk size #396 (#528)
Browse files Browse the repository at this point in the history
* Parse entire HTTP chunk size #396

Continue parsing HTTP chunk size up until Int.MaxValue so the actual
size of the chunk can be logged if it exceeds the configured max chunk
size.

* Add reference to Integer.MAX_VALUE in the error message

* Fix formatting
  • Loading branch information
SkyTrix authored Mar 31, 2024
1 parent 8eb3a50 commit ab1b252
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -307,17 +307,20 @@ private[http] trait HttpMessageParser[Output >: MessageOutput <: ParserOutput] {
s"HTTP chunk extension length exceeds configured limit of ${settings.maxChunkExtLength} characters")

@tailrec def parseSize(cursor: Int, size: Long): StateResult =
if (size <= settings.maxChunkSize) {
if (size <= Int.MaxValue) {
byteChar(input, cursor) match {
case c if CharacterClasses.HEXDIG(c) => parseSize(cursor + 1, size * 16 + CharUtils.hexValue(c))
case ';' if cursor > offset => parseChunkExtensions(size.toInt, cursor + 1)()
case c if size > settings.maxChunkSize =>
failEntityStream(
s"HTTP chunk of $size bytes exceeds the configured limit of ${settings.maxChunkSize} bytes")
case ';' if cursor > offset => parseChunkExtensions(size.toInt, cursor + 1)()
case '\r' if cursor > offset && byteChar(input, cursor + 1) == '\n' =>
parseChunkBody(size.toInt, "", cursor + 2)
case '\n' if cursor > offset => parseChunkBody(size.toInt, "", cursor + 1)
case c if CharacterClasses.WSP(c) => parseSize(cursor + 1, size) // illegal according to the spec but can happen, see issue #1812
case c => failEntityStream(s"Illegal character '${escape(c)}' in chunk start")
}
} else failEntityStream(s"HTTP chunk size exceeds the configured limit of ${settings.maxChunkSize} bytes")
} else failEntityStream(s"HTTP chunk size exceeds Integer.MAX_VALUE (${Int.MaxValue}) bytes")

try parseSize(offset, 0)
catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,13 +531,24 @@ abstract class RequestParserSpec(mode: String, newLine: String) extends AnyFreeS
closeAfterResponseCompletion shouldEqual Seq(false)
}

"too-large chunk size" in new Test {
"too-large chunk size (> Int.MaxValue)" in new Test {
Seq(
start,
"""1a2b3c4d5e
|""") should generalMultiParseTo(
Right(baseRequest),
Left(EntityStreamError(ErrorInfo("HTTP chunk size exceeds the configured limit of 1048576 bytes"))))
Left(EntityStreamError(ErrorInfo("HTTP chunk size exceeds Integer.MAX_VALUE (2147483647) bytes"))))
closeAfterResponseCompletion shouldEqual Seq(false)
}

"too-large chunk size" in new Test {
Seq(
start,
"""400000
|""") should generalMultiParseTo(
Right(baseRequest),
Left(
EntityStreamError(ErrorInfo("HTTP chunk of 4194304 bytes exceeds the configured limit of 1048576 bytes"))))
closeAfterResponseCompletion shouldEqual Seq(false)
}

Expand Down

0 comments on commit ab1b252

Please sign in to comment.