Bug 1687820 - Fix bugs with null bytes in form payloads. r=smaug

On `multipart/form-data` payloads, a null byte on the name, filename or string
value cuts off the rest of the name, filename or value. On `text/plain`
payloads, a null byte anywhere cuts off the rest of the entire payload.

This is because `nsLinebreakConverter::ConvertLineBreaks` is called without
giving a length parameter, which causes it to treat the input C string as
null-terminated.

The tests for `text/plain` are under review on WPT:
https://github.com/web-platform-tests/wpt/pull/26740
(https://wpt.fyi/results/html/semantics/forms/form-submission-0/text-plain.window.html?label=pr_head&max-count=1&pr=26740)

Differential Revision: https://phabricator.services.mozilla.com/D102625
This commit is contained in:
Andreu Botella
2021-01-23 20:25:05 +00:00
parent 0dd3b1bc1c
commit 70b6deef58
3 changed files with 24 additions and 16 deletions

View File

@@ -388,9 +388,12 @@ nsresult FSMultipartFormData::AddNameValuePair(const nsAString& aName,
nsresult rv = EncodeVal(aValue, encodedVal, false);
NS_ENSURE_SUCCESS(rv, rv);
valueStr.Adopt(nsLinebreakConverter::ConvertLineBreaks(
int32_t convertedBufLength = 0;
char* convertedBuf = nsLinebreakConverter::ConvertLineBreaks(
encodedVal.get(), nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
nsLinebreakConverter::eLinebreakNet, encodedVal.Length(),
&convertedBufLength);
valueStr.Adopt(convertedBuf, convertedBufLength);
nsAutoCString nameStr;
rv = EncodeVal(aName, nameStr, true);
@@ -450,10 +453,13 @@ nsresult FSMultipartFormData::AddNameBlobOrNullPair(const nsAString& aName,
contentType16.AssignLiteral("application/octet-stream");
}
contentType.Adopt(nsLinebreakConverter::ConvertLineBreaks(
NS_ConvertUTF16toUTF8(contentType16).get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
NS_ConvertUTF16toUTF8 contentType8(contentType16);
int32_t convertedBufLength = 0;
char* convertedBuf = nsLinebreakConverter::ConvertLineBreaks(
contentType8.get(), nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace, contentType8.Length(),
&convertedBufLength);
contentType.Adopt(convertedBuf, convertedBufLength);
// Get input stream
aBlob->CreateInputStream(getter_AddRefs(fileStream), error);
@@ -681,9 +687,14 @@ nsresult FSTextPlain::GetEncodedSubmission(nsIURI* aURI,
// encoded, but that how text/plain is specced.
nsCString cbody;
EncodeVal(mBody, cbody, false);
cbody.Adopt(nsLinebreakConverter::ConvertLineBreaks(
int32_t convertedBufLength = 0;
char* convertedBuf = nsLinebreakConverter::ConvertLineBreaks(
cbody.get(), nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
nsLinebreakConverter::eLinebreakNet, cbody.Length(),
&convertedBufLength);
cbody.Adopt(convertedBuf, convertedBufLength);
nsCOMPtr<nsIInputStream> bodyStream;
rv = NS_NewCStringInputStream(getter_AddRefs(bodyStream), std::move(cbody));
if (!bodyStream) {
@@ -746,9 +757,12 @@ nsresult EncodingFormSubmission::EncodeVal(const nsAString& aStr,
}
if (aHeaderEncode) {
aOut.Adopt(nsLinebreakConverter::ConvertLineBreaks(
int32_t convertedBufLength = 0;
char* convertedBuf = nsLinebreakConverter::ConvertLineBreaks(
aOut.get(), nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
nsLinebreakConverter::eLinebreakSpace, aOut.Length(),
&convertedBufLength);
aOut.Adopt(convertedBuf, convertedBufLength);
aOut.ReplaceSubstring("\""_ns, "\\\""_ns);
}