diff options
author | Moonchild <moonchild@palemoon.org> | 2021-11-04 12:40:46 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2022-04-04 22:04:54 +0200 |
commit | 97ee3ee428c8fc848f67b95f746bc268c6892eeb (patch) | |
tree | 312b177bfbd86f744f74d2ef4169924cdd0e1ee8 | |
parent | 78d1f689320f649076565ade1f61a940c1f8542e (diff) | |
download | uxp-97ee3ee428c8fc848f67b95f746bc268c6892eeb.tar.gz |
[network] Clean up IDN logic and add some corner case use.
-rw-r--r-- | netwerk/base/nsStandardURL.cpp | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index 3d77093004..e021bbf5fb 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -554,37 +554,63 @@ nsStandardURL::NormalizeIPv4(const nsCSubstring &host, nsCString &result) 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 nsStandardURL::NormalizeIDN(const nsCSubstring &host, nsCString &result) { - // If host is ACE, then convert to UTF-8. Else, if host is already UTF-8, - // then make sure it is normalized per IDN. - - // 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; + nsresult rv = NS_ERROR_UNEXPECTED; + // Clear result even if we bail. + result.Truncate(); + if (!gIDN) { nsCOMPtr<nsIIDNService> serv(do_GetService(NS_IDNSERVICE_CONTRACTID)); if (serv) { NS_ADDREF(gIDN = serv.get()); } } + if (!gIDN) { + return NS_ERROR_UNEXPECTED; + } - result.Truncate(); - nsresult rv = NS_ERROR_UNEXPECTED; - if (gIDN) { - rv = gIDN->ConvertToDisplayIDN(host, &isASCII, result); - if (NS_SUCCEEDED(rv) && !isASCII) { - mHostEncoding = eEncoding_UTF8; - } + NS_ASSERTION(mHostEncoding == eEncoding_ASCII, "unexpected default encoding"); + + bool isASCII; + nsAutoCString normalized; + + // 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; + } + + // 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; + } + + // Finally, convert to IDN + rv = gIDN->ConvertToDisplayIDN(normalized, &isASCII, result); + if (NS_SUCCEEDED(rv) && !isASCII) { + mHostEncoding = eEncoding_UTF8; } return rv; |