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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user