mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 493544 - Don't decode the encoded text until it ends. r=smontagu
This commit is contained in:
parent
20a6d96dc4
commit
f3d486af9c
@ -1091,6 +1091,43 @@ void CopyRawHeader(const char *aInput, uint32_t aLen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult DecodeQOrBase64Str(const char *aEncoded, size_t aLen, char aQOrBase64,
|
||||||
|
const char *aCharset, nsACString &aResult)
|
||||||
|
{
|
||||||
|
char *decodedText;
|
||||||
|
NS_ASSERTION(aQOrBase64 == 'Q' || aQOrBase64 == 'B', "Should be 'Q' or 'B'");
|
||||||
|
if(aQOrBase64 == 'Q')
|
||||||
|
decodedText = DecodeQ(aEncoded, aLen);
|
||||||
|
else if (aQOrBase64 == 'B') {
|
||||||
|
decodedText = PL_Base64Decode(aEncoded, aLen, nullptr);
|
||||||
|
} else {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decodedText) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIUTF8ConverterService>
|
||||||
|
cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID, &rv));
|
||||||
|
nsAutoCString utf8Text;
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset.
|
||||||
|
rv = cvtUTF8->ConvertStringToUTF8(nsDependentCString(decodedText),
|
||||||
|
aCharset,
|
||||||
|
IS_7BIT_NON_ASCII_CHARSET(aCharset),
|
||||||
|
true, 1, utf8Text);
|
||||||
|
}
|
||||||
|
PR_Free(decodedText);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
aResult.Append(utf8Text);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static const char especials[] = "()<>@,;:\\\"/[]?.=";
|
static const char especials[] = "()<>@,;:\\\"/[]?.=";
|
||||||
|
|
||||||
// |decode_mime_part2_str| taken from comi18n.c
|
// |decode_mime_part2_str| taken from comi18n.c
|
||||||
@ -1103,14 +1140,13 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
|
|||||||
bool aOverrideCharset, nsACString &aResult)
|
bool aOverrideCharset, nsACString &aResult)
|
||||||
{
|
{
|
||||||
const char *p, *q = nullptr, *r;
|
const char *p, *q = nullptr, *r;
|
||||||
char *decodedText;
|
|
||||||
const char *begin; // tracking pointer for where we are in the input buffer
|
const char *begin; // tracking pointer for where we are in the input buffer
|
||||||
int32_t isLastEncodedWord = 0;
|
int32_t isLastEncodedWord = 0;
|
||||||
const char *charsetStart, *charsetEnd;
|
const char *charsetStart, *charsetEnd;
|
||||||
char charset[80];
|
nsAutoCString prevCharset, curCharset;
|
||||||
|
nsAutoCString encodedText;
|
||||||
// initialize charset name to an empty string
|
char prevEncoding = '\0', curEncoding;
|
||||||
charset[0] = '\0';
|
nsresult rv;
|
||||||
|
|
||||||
begin = aHeader;
|
begin = aHeader;
|
||||||
|
|
||||||
@ -1155,15 +1191,9 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
|
|||||||
charsetEnd = q;
|
charsetEnd = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for too-long charset name
|
|
||||||
if (uint32_t(charsetEnd - charsetStart) >= sizeof(charset))
|
|
||||||
goto badsyntax;
|
|
||||||
|
|
||||||
memcpy(charset, charsetStart, charsetEnd - charsetStart);
|
|
||||||
charset[charsetEnd - charsetStart] = 0;
|
|
||||||
|
|
||||||
q++;
|
q++;
|
||||||
if (*q != 'Q' && *q != 'q' && *q != 'B' && *q != 'b')
|
curEncoding = nsCRT::ToUpper(*q);
|
||||||
|
if (curEncoding != 'Q' && curEncoding != 'B')
|
||||||
goto badsyntax;
|
goto badsyntax;
|
||||||
|
|
||||||
if (q[1] != '?')
|
if (q[1] != '?')
|
||||||
@ -1182,55 +1212,88 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*q == 'Q' || *q == 'q')
|
curCharset.Assign(charsetStart, charsetEnd - charsetStart);
|
||||||
decodedText = DecodeQ(q + 2, r - (q + 2));
|
// Override charset if requested. Never override labeled UTF-8.
|
||||||
else {
|
// Use default charset instead of UNKNOWN-8BIT
|
||||||
|
if ((aOverrideCharset && 0 != nsCRT::strcasecmp(curCharset.get(), "UTF-8"))
|
||||||
|
|| (aDefaultCharset && 0 == nsCRT::strcasecmp(curCharset.get(), "UNKNOWN-8BIT"))
|
||||||
|
) {
|
||||||
|
curCharset = aDefaultCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *R;
|
||||||
|
R = r;
|
||||||
|
if (curEncoding == 'B') {
|
||||||
// bug 227290. ignore an extraneous '=' at the end.
|
// bug 227290. ignore an extraneous '=' at the end.
|
||||||
// (# of characters in B-encoded part has to be a multiple of 4)
|
// (# of characters in B-encoded part has to be a multiple of 4)
|
||||||
int32_t n = r - (q + 2);
|
int32_t n = r - (q + 2);
|
||||||
n -= (n % 4 == 1 && !PL_strncmp(r - 3, "===", 3)) ? 1 : 0;
|
R -= (n % 4 == 1 && !PL_strncmp(r - 3, "===", 3)) ? 1 : 0;
|
||||||
decodedText = PL_Base64Decode(q + 2, n, nullptr);
|
}
|
||||||
|
// Bug 493544. Don't decode the encoded text until it ends
|
||||||
|
if (R[-1] != '='
|
||||||
|
&& (prevCharset.IsEmpty()
|
||||||
|
|| (curCharset == prevCharset && curEncoding == prevEncoding))
|
||||||
|
) {
|
||||||
|
encodedText.Append(q + 2, R - (q + 2));
|
||||||
|
prevCharset = curCharset;
|
||||||
|
prevEncoding = curEncoding;
|
||||||
|
|
||||||
|
begin = r + 2;
|
||||||
|
isLastEncodedWord = 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodedText == nullptr)
|
bool bDecoded; // If the current line has been decoded.
|
||||||
goto badsyntax;
|
bDecoded = false;
|
||||||
|
if (!encodedText.IsEmpty()) {
|
||||||
// Override charset if requested. Never override labeled UTF-8.
|
if (curCharset == prevCharset && curEncoding == prevEncoding) {
|
||||||
// Use default charset instead of UNKNOWN-8BIT
|
encodedText.Append(q + 2, R - (q + 2));
|
||||||
if ((aOverrideCharset && 0 != nsCRT::strcasecmp(charset, "UTF-8")) ||
|
bDecoded = true;
|
||||||
(aDefaultCharset && 0 == nsCRT::strcasecmp(charset, "UNKNOWN-8BIT"))) {
|
}
|
||||||
PL_strncpy(charset, aDefaultCharset, sizeof(charset) - 1);
|
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
|
||||||
charset[sizeof(charset) - 1] = '\0';
|
prevEncoding, prevCharset.get(), aResult);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aResult.Append(encodedText);
|
||||||
|
}
|
||||||
|
encodedText.Truncate();
|
||||||
|
prevCharset.Truncate();
|
||||||
}
|
}
|
||||||
|
if (!bDecoded) {
|
||||||
{
|
rv = DecodeQOrBase64Str(q + 2, R - (q + 2), curEncoding,
|
||||||
nsCOMPtr<nsIUTF8ConverterService>
|
curCharset.get(), aResult);
|
||||||
cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID));
|
if (NS_FAILED(rv)) {
|
||||||
nsAutoCString utf8Text;
|
aResult.Append(encodedText);
|
||||||
// skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset.
|
|
||||||
if (cvtUTF8 &&
|
|
||||||
NS_SUCCEEDED(
|
|
||||||
cvtUTF8->ConvertStringToUTF8(nsDependentCString(decodedText),
|
|
||||||
charset,
|
|
||||||
IS_7BIT_NON_ASCII_CHARSET(charset),
|
|
||||||
true, 1, utf8Text))) {
|
|
||||||
aResult.Append(utf8Text);
|
|
||||||
} else {
|
|
||||||
aResult.Append(REPLACEMENT_CHAR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PR_Free(decodedText);
|
|
||||||
begin = r + 2;
|
begin = r + 2;
|
||||||
isLastEncodedWord = 1;
|
isLastEncodedWord = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
badsyntax:
|
badsyntax:
|
||||||
|
if (!encodedText.IsEmpty()) {
|
||||||
|
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
|
||||||
|
prevEncoding, prevCharset.get(), aResult);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aResult.Append(encodedText);
|
||||||
|
}
|
||||||
|
encodedText.Truncate();
|
||||||
|
prevCharset.Truncate();
|
||||||
|
}
|
||||||
// copy the part before the encoded-word
|
// copy the part before the encoded-word
|
||||||
aResult.Append(begin, p - begin);
|
aResult.Append(begin, p - begin);
|
||||||
begin = p;
|
begin = p;
|
||||||
isLastEncodedWord = 0;
|
isLastEncodedWord = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!encodedText.IsEmpty()) {
|
||||||
|
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
|
||||||
|
prevEncoding, prevCharset.get(), aResult);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aResult.Append(encodedText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// put the tail back
|
// put the tail back
|
||||||
CopyRawHeader(begin, strlen(begin), aDefaultCharset, aResult);
|
CopyRawHeader(begin, strlen(begin), aDefaultCharset, aResult);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user