Skip to content

require three ASCII digits for the response status code - #9731

Open
basavaraj-sm05 wants to merge 2 commits into
lysine-dev:mainfrom
basavaraj-sm05:status-code-ascii-digits
Open

require three ASCII digits for the response status code#9731
basavaraj-sm05 wants to merge 2 commits into
lysine-dev:mainfrom
basavaraj-sm05:status-code-ascii-digits

Conversation

@basavaraj-sm05

Copy link
Copy Markdown
Contributor

StatusLine.parse pulls the three response-code characters out of the status line and hands them to toIntOrNull() to get the numeric code. That delegate does more than read ASCII digits: it accepts a leading + or - sign, and because it resolves each character through Character.digit it also accepts any Unicode decimal digit, so an Arabic-Indic "٢٠٠" comes back as 200 and "+99" as 99. RFC 9112 defines status-code as exactly three ASCII DIGIT, and the value here comes straight off the wire, whether from an HTTP/1 status line, an HTTP/2 :status pseudo-header (Http2ExchangeCodec builds "HTTP/1.1 $value" from it), or a cached response, so a hostile or non-conforming server can hand okhttp a code that a conforming proxy or log sitting in front of it reads differently. A "-12" even parses to a negative code that only trips a check much later when the Response is built. I noticed it while adding cases to the existing nonThreeDigitCode test, which only covered letters and wrong lengths. Restricting the three characters to '0'..'9' before converting keeps every valid code working and rejects the rest at the parser.

Comment on lines +80 to +84
val codeString = statusLine.substring(codeStart, codeStart + 3)
if (!codeString.all { it in '0'..'9' }) {
throw ProtocolException("Unexpected status line: $statusLine")
}
val code = codeString.toInt()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes multiple passes and allocations. If we're going to modify this code, we should also improve its performance by not creating the substring and operating directly on chars/doing the trivial math ourselves.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. It now walks the three chars once, checking each is in '0'..'9' and accumulating the code in the same loop, so the substring and the extra pass are both gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants