Bug 1917925 - network.http.strict_response_status_line_parsing pref. r=gregp,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D223083
This commit is contained in:
tannal 2024-09-24 08:40:52 +00:00
parent 1c344cfc96
commit 0d46faca9e
4 changed files with 35 additions and 63 deletions

View File

@ -14069,13 +14069,7 @@
value: 5
mirror: always
# If true, will be more strict with status code parsing
- name: network.http.strict_response_status_line_parsing
type: RelaxedAtomicBool
value: true
mirror: always
# If true, remove the resumption token when 0RTT failed.
# If true, remove the resumption token when 0RTT failed.
- name: network.http.remove_resumption_token_when_early_data_failed
type: RelaxedAtomicBool
value: true

View File

@ -360,7 +360,7 @@ nsresult nsHttpResponseHead::ParseStatusLine(const nsACString& line) {
nsresult nsHttpResponseHead::ParseStatusLine_locked(const nsACString& line) {
//
// Parse Status-Line:: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
// Parse Status-Line: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
//
const char* start = line.BeginReading();
@ -371,57 +371,42 @@ nsresult nsHttpResponseHead::ParseStatusLine_locked(const nsACString& line) {
int32_t index = line.FindChar(' ');
if ((mVersion == HttpVersion::v0_9) || (index == -1)) {
if (mVersion == HttpVersion::v0_9 || index == -1) {
mStatus = 200;
AssignDefaultStatusText();
} else if (StaticPrefs::network_http_strict_response_status_line_parsing()) {
// Status-Code: all ASCII digits after any whitespace
const char* p = start + index + 1;
while (p < end && NS_IsHTTPWhitespace(*p)) ++p;
if (p == end || !mozilla::IsAsciiDigit(*p)) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
const char* codeStart = p;
while (p < end && mozilla::IsAsciiDigit(*p)) ++p;
// Only accept 3 digits (including all leading zeros)
// Also if next char isn't whitespace, fail (ie, code is 0x2)
if (p - codeStart > 3 || (p < end && !NS_IsHTTPWhitespace(*p))) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
// At this point the code is between 0 and 999 inclusive
nsDependentCSubstring strCode(codeStart, p - codeStart);
nsresult rv;
mStatus = strCode.ToInteger(&rv);
if (NS_FAILED(rv)) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
// Reason-Phrase: whatever remains after any whitespace (even empty)
while (p < end && NS_IsHTTPWhitespace(*p)) ++p;
if (p != end) {
mStatusText = nsDependentCSubstring(p, end - p);
}
} else {
// Status-Code
const char* p = start + index + 1;
mStatus = (uint16_t)atoi(p);
if (mStatus == 0) {
LOG(("mal-formed response status; assuming status = 200\n"));
mStatus = 200;
}
// Reason-Phrase is whatever is remaining of the line
index = line.FindChar(' ', p - start);
if (index == -1) {
AssignDefaultStatusText();
} else {
p = start + index + 1;
mStatusText = nsDependentCSubstring(p, end - p);
}
LOG1(("Have status line [version=%u status=%u statusText=%s]\n",
unsigned(mVersion), unsigned(mStatus), mStatusText.get()));
return NS_OK;
}
// Status-Code: all ASCII digits after any whitespace
const char* p = start + index + 1;
while (p < end && NS_IsHTTPWhitespace(*p)) ++p;
if (p == end || !mozilla::IsAsciiDigit(*p)) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
const char* codeStart = p;
while (p < end && mozilla::IsAsciiDigit(*p)) ++p;
// Only accept 3 digits (including all leading zeros)
// Also if next char isn't whitespace, fail (ie, code is 0x2)
if (p - codeStart > 3 || (p < end && !NS_IsHTTPWhitespace(*p))) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
// At this point the code is between 0 and 999 inclusive
nsDependentCSubstring strCode(codeStart, p - codeStart);
nsresult rv;
mStatus = strCode.ToInteger(&rv);
if (NS_FAILED(rv)) {
return NS_ERROR_PARSING_HTTP_STATUS_LINE;
}
// Reason-Phrase: whatever remains after any whitespace (even empty)
while (p < end && NS_IsHTTPWhitespace(*p)) ++p;
if (p != end) {
mStatusText = nsDependentCSubstring(p, end - p);
}
LOG1(("Have status line [version=%u status=%u statusText=%s]\n",
unsigned(mVersion), unsigned(mStatus), mStatusText.get()));
return NS_OK;

View File

@ -101,15 +101,9 @@ TEST(TestHttpResponseHead, bug1687903)
{
nsHttpResponseHead head;
bool usingStrictParsing = false;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
prefs->GetBoolPref("network.http.strict_response_status_line_parsing",
&usingStrictParsing);
}
nsresult expectation =
usingStrictParsing ? NS_ERROR_PARSING_HTTP_STATUS_LINE : NS_OK;
nsresult expectation = NS_ERROR_PARSING_HTTP_STATUS_LINE;
ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 "_ns));
ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 BLAH"_ns));

View File

@ -1,2 +1 @@
leak-threshold: [default:3020800]
prefs: [network.http.strict_response_status_line_parsing:true]