summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2021-11-04 12:40:46 +0000
committerMoonchild <moonchild@palemoon.org>2022-04-04 22:04:54 +0200
commit97ee3ee428c8fc848f67b95f746bc268c6892eeb (patch)
tree312b177bfbd86f744f74d2ef4169924cdd0e1ee8
parent78d1f689320f649076565ade1f61a940c1f8542e (diff)
downloaduxp-97ee3ee428c8fc848f67b95f746bc268c6892eeb.tar.gz
[network] Clean up IDN logic and add some corner case use.
-rw-r--r--netwerk/base/nsStandardURL.cpp68
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;