mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 16:17:29 +09:00
backport Bug 1724233 - Make sure to run ConvertUTF8toACE before ConvertToDisplayIDN. r=dragana, a=RyanVM
This commit is contained in:
parent
d025defb98
commit
0ffa8a018a
2 changed files with 95 additions and 28 deletions
|
|
@ -554,37 +554,76 @@ nsStandardURL::NormalizeIPv4(const nsCSubstring &host, nsCString &result)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns |true| if |aString| contains only ASCII characters according
|
||||||
|
* to our CRT.
|
||||||
|
*
|
||||||
|
* @param aString an 8-bit wide string to scan
|
||||||
|
*/
|
||||||
|
inline bool IsAsciiString(mozilla::Span<const char> aString) {
|
||||||
|
for (char c : aString) {
|
||||||
|
if (!nsCRT::IsAscii(c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsStandardURL::NormalizeIDN(const nsCSubstring &host, nsCString &result)
|
nsStandardURL::NormalizeIDN(const nsCSubstring &host, nsCString &result)
|
||||||
{
|
{
|
||||||
// If host is ACE, then convert to UTF-8. Else, if host is already UTF-8,
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
// then make sure it is normalized per IDN.
|
// Clear result even if we bail.
|
||||||
|
result.Truncate();
|
||||||
|
|
||||||
// this function returns true if normalization succeeds.
|
|
||||||
|
|
||||||
// NOTE: As a side-effect this function sets mHostEncoding. While it would
|
|
||||||
// be nice to avoid side-effects in this function, the implementation of
|
|
||||||
// this function is already somewhat bound to the behavior of the
|
|
||||||
// callsites. Anyways, this function exists to avoid code duplication, so
|
|
||||||
// side-effects abound :-/
|
|
||||||
|
|
||||||
NS_ASSERTION(mHostEncoding == eEncoding_ASCII, "unexpected default encoding");
|
|
||||||
|
|
||||||
bool isASCII;
|
|
||||||
if (!gIDN) {
|
if (!gIDN) {
|
||||||
nsCOMPtr<nsIIDNService> serv(do_GetService(NS_IDNSERVICE_CONTRACTID));
|
nsCOMPtr<nsIIDNService> serv(do_GetService(NS_IDNSERVICE_CONTRACTID));
|
||||||
if (serv) {
|
if (serv) {
|
||||||
NS_ADDREF(gIDN = serv.get());
|
NS_ADDREF(gIDN = serv.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!gIDN) {
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
result.Truncate();
|
NS_ASSERTION(mHostEncoding == eEncoding_ASCII, "unexpected default encoding");
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
||||||
if (gIDN) {
|
bool isASCII;
|
||||||
rv = gIDN->ConvertToDisplayIDN(host, &isASCII, result);
|
nsAutoCString normalized;
|
||||||
if (NS_SUCCEEDED(rv) && !isASCII) {
|
|
||||||
mHostEncoding = eEncoding_UTF8;
|
// If the input is ASCII, and not ACE encoded, then there's no processing
|
||||||
}
|
// needed. This is needed because we want to allow ascii labels longer than
|
||||||
|
// 64 characters for some schemes.
|
||||||
|
bool isACE = false;
|
||||||
|
if (IsAsciiString(host) && NS_SUCCEEDED(gIDN->IsACE(host, &isACE)) && !isACE) {
|
||||||
|
result = host;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the input is an ACE encoded string it MUST be ASCII or it's malformed
|
||||||
|
// according to the spec.
|
||||||
|
if (!IsAsciiString(host) && isACE) {
|
||||||
|
return NS_ERROR_MALFORMED_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even if it's already ACE, we must still call ConvertUTF8toACE in order
|
||||||
|
// for the input normalization to take place.
|
||||||
|
rv = gIDN->ConvertUTF8toACE(host, normalized);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the ASCII representation doesn't contain the xn-- token then we don't
|
||||||
|
// need to call ConvertToDisplayIDN as that would not change anything.
|
||||||
|
if (!StringBeginsWith(normalized, NS_LITERAL_CSTRING("xn--")) &&
|
||||||
|
normalized.Find(NS_LITERAL_CSTRING(".xn--")) == kNotFound) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, convert to IDN
|
||||||
|
rv = gIDN->ConvertToDisplayIDN(normalized, &isASCII, result);
|
||||||
|
if (NS_SUCCEEDED(rv) && !isASCII) {
|
||||||
|
mHostEncoding = eEncoding_UTF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,13 @@ nsIDNService::IDNA2008StringPrep(const nsAString& input,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.errors != 0) {
|
uint32_t ignoredErrors = 0;
|
||||||
|
if (flag == eStringPrepForDNS) {
|
||||||
|
ignoredErrors = UIDNA_ERROR_LEADING_HYPHEN | UIDNA_ERROR_TRAILING_HYPHEN |
|
||||||
|
UIDNA_ERROR_HYPHEN_3_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((info.errors & ~ignoredErrors) != 0) {
|
||||||
if (flag == eStringPrepForDNS) {
|
if (flag == eStringPrepForDNS) {
|
||||||
output.Truncate();
|
output.Truncate();
|
||||||
}
|
}
|
||||||
|
|
@ -309,18 +315,40 @@ nsresult nsIDNService::ACEtoUTF8(const nsACString & input, nsACString & _retval,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns |true| if |aString| contains only ASCII characters according
|
||||||
|
* to our CRT.
|
||||||
|
*
|
||||||
|
* @param aString an 8-bit wide string to scan
|
||||||
|
*/
|
||||||
|
inline bool IsAsciiString(mozilla::Span<const char> aString) {
|
||||||
|
for (char c : aString) {
|
||||||
|
if (!nsCRT::IsAscii(c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsIDNService::IsACE(const nsACString & input, bool *_retval)
|
NS_IMETHODIMP nsIDNService::IsACE(const nsACString & input, bool *_retval)
|
||||||
{
|
{
|
||||||
const char *data = input.BeginReading();
|
|
||||||
uint32_t dataLen = input.Length();
|
|
||||||
|
|
||||||
// look for the ACE prefix in the input string. it may occur
|
// look for the ACE prefix in the input string. it may occur
|
||||||
// at the beginning of any segment in the domain name. for
|
// at the beginning of any segment in the domain name. for
|
||||||
// example: "www.xn--ENCODED.com"
|
// example: "www.xn--ENCODED.com"
|
||||||
|
if (!IsAsciiString(input)) {
|
||||||
|
*_retval = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
auto stringContains = [](const nsACString& haystack,
|
||||||
|
const nsACString& needle) {
|
||||||
|
return std::search(haystack.BeginReading(), haystack.EndReading(),
|
||||||
|
needle.BeginReading(),
|
||||||
|
needle.EndReading()) != haystack.EndReading();
|
||||||
|
};
|
||||||
|
|
||||||
const char *p = PL_strncasestr(data, kACEPrefix, dataLen);
|
*_retval = StringBeginsWith(input, NS_LITERAL_CSTRING("xn--")) ||
|
||||||
|
(!input.IsEmpty() && input[0] != '.' &&
|
||||||
*_retval = p && (p == data || *(p - 1) == '.');
|
stringContains(input, NS_LITERAL_CSTRING(".xn--")));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue