From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- netwerk/dns/GetAddrInfo.cpp | 2 + netwerk/dns/GetAddrInfo.h | 2 + netwerk/dns/PlatformDNSAndroid.cpp | 2 + netwerk/dns/PlatformDNSUnix.cpp | 35 ++++++++- netwerk/dns/PlatformDNSWin.cpp | 2 + netwerk/dns/TRR.cpp | 2 + netwerk/dns/effective_tld_names.dat | 22 ++++-- netwerk/dns/nsEffectiveTLDService.cpp | 2 +- netwerk/dns/nsHostResolver.cpp | 21 ++++++ netwerk/dns/nsIDNService.cpp | 98 ++++++++++++++++++++----- netwerk/dns/nsIDNService.h | 37 ++++++---- netwerk/dns/nsIIDNService.idl | 6 -- netwerk/dns/tests/unit/test_PublicSuffixList.js | 2 +- 13 files changed, 179 insertions(+), 54 deletions(-) (limited to 'netwerk/dns') diff --git a/netwerk/dns/GetAddrInfo.cpp b/netwerk/dns/GetAddrInfo.cpp index 0dd1f0099a..352a01226e 100644 --- a/netwerk/dns/GetAddrInfo.cpp +++ b/netwerk/dns/GetAddrInfo.cpp @@ -579,6 +579,8 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags, return NS_ERROR_NOT_IMPLEMENTED; } +void DNSThreadShutdown() {} + #endif // MOZ_NO_HTTPS_IMPL } // namespace mozilla::net diff --git a/netwerk/dns/GetAddrInfo.h b/netwerk/dns/GetAddrInfo.h index e8dc095415..c8b4ebae69 100644 --- a/netwerk/dns/GetAddrInfo.h +++ b/netwerk/dns/GetAddrInfo.h @@ -67,6 +67,8 @@ nsresult GetAddrInfoInit(); */ nsresult GetAddrInfoShutdown(); +void DNSThreadShutdown(); + /** * Resolves a HTTPS record. Will check overrides before calling the * native OS implementation. diff --git a/netwerk/dns/PlatformDNSAndroid.cpp b/netwerk/dns/PlatformDNSAndroid.cpp index 78a944777f..171797b938 100644 --- a/netwerk/dns/PlatformDNSAndroid.cpp +++ b/netwerk/dns/PlatformDNSAndroid.cpp @@ -151,4 +151,6 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags, return NS_OK; } +void DNSThreadShutdown() {} + } // namespace mozilla::net diff --git a/netwerk/dns/PlatformDNSUnix.cpp b/netwerk/dns/PlatformDNSUnix.cpp index dedbe337df..c7f57fcdda 100644 --- a/netwerk/dns/PlatformDNSUnix.cpp +++ b/netwerk/dns/PlatformDNSUnix.cpp @@ -9,6 +9,7 @@ #include "nsIDNSService.h" #include "mozilla/Maybe.h" #include "mozilla/StaticPrefs_network.h" +#include "mozilla/ThreadLocal.h" #include #include @@ -18,6 +19,10 @@ namespace mozilla::net { +#if defined(HAVE_RES_NINIT) +MOZ_THREAD_LOCAL(struct __res_state*) sThreadRes; +#endif + #define LOG(msg, ...) \ MOZ_LOG(gGetAddrInfoLog, LogLevel::Debug, ("[DNS]: " msg, ##__VA_ARGS__)) @@ -33,16 +38,28 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags, return NS_ERROR_UNKNOWN_HOST; } +#if defined(HAVE_RES_NINIT) + if (!sThreadRes.get()) { + UniquePtr resState(new struct __res_state); + memset(resState.get(), 0, sizeof(struct __res_state)); + if (int ret = res_ninit(resState.get())) { + LOG("res_ninit failed: %d", ret); + return NS_ERROR_UNKNOWN_HOST; + } + sThreadRes.set(resState.release()); + } +#endif + LOG("resolving %s\n", host.get()); // Perform the query rv = packet.FillBuffer( [&](unsigned char response[DNSPacket::MAX_SIZE]) -> int { int len = 0; -#if defined(XP_LINUX) - len = res_nquery(&_res, host.get(), ns_c_in, +#if defined(HAVE_RES_NINIT) + len = res_nquery(sThreadRes.get(), host.get(), ns_c_in, nsIDNSService::RESOLVE_TYPE_HTTPSSVC, response, DNSPacket::MAX_SIZE); -#elif defined(XP_MACOSX) +#else len = res_query(host.get(), ns_c_in, nsIDNSService::RESOLVE_TYPE_HTTPSSVC, response, DNSPacket::MAX_SIZE); @@ -60,4 +77,16 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags, return ParseHTTPSRecord(host, packet, aResult, aTTL); } +void DNSThreadShutdown() { +#if defined(HAVE_RES_NINIT) + auto* res = sThreadRes.get(); + if (!res) { + return; + } + + sThreadRes.set(nullptr); + res_nclose(res); +#endif +} + } // namespace mozilla::net diff --git a/netwerk/dns/PlatformDNSWin.cpp b/netwerk/dns/PlatformDNSWin.cpp index 8b5539d7de..42f1483ec3 100644 --- a/netwerk/dns/PlatformDNSWin.cpp +++ b/netwerk/dns/PlatformDNSWin.cpp @@ -137,4 +137,6 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags, return NS_OK; } +void DNSThreadShutdown() {} + } // namespace mozilla::net diff --git a/netwerk/dns/TRR.cpp b/netwerk/dns/TRR.cpp index aad65ab809..66bca3f423 100644 --- a/netwerk/dns/TRR.cpp +++ b/netwerk/dns/TRR.cpp @@ -616,6 +616,7 @@ TRR::OnPush(nsIHttpChannel* associated, nsIHttpChannel* pushed) { } RefPtr trr = new TRR(mHostResolver, mPB); + trr->SetPurpose(mPurpose); return trr->ReceivePush(pushed, mRec); } @@ -901,6 +902,7 @@ nsresult TRR::FollowCname(nsIChannel* aChannel) { mCnameLoop)); RefPtr trr = new TRR(mHostResolver, mRec, mCname, mType, mCnameLoop, mPB); + trr->SetPurpose(mPurpose); if (!TRRService::Get()) { return NS_ERROR_FAILURE; } diff --git a/netwerk/dns/effective_tld_names.dat b/netwerk/dns/effective_tld_names.dat index c2b813fa68..21df77442b 100644 --- a/netwerk/dns/effective_tld_names.dat +++ b/netwerk/dns/effective_tld_names.dat @@ -6710,7 +6710,7 @@ org.zw // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-06T15:14:58Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-28T15:13:37Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html @@ -6988,10 +6988,6 @@ auto // https://www.iana.org/domains/root/db/autos.html autos -// avianca : Avianca Inc. -// https://www.iana.org/domains/root/db/avianca.html -avianca - // aws : AWS Registry LLC // https://www.iana.org/domains/root/db/aws.html aws @@ -13480,6 +13476,10 @@ whitesnow.jp zombie.jp heteml.net +// GoDaddy Registry : https://registry.godaddy +// Submitted by Rohan Durrant +graphic.design + // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell cloudapps.digital @@ -13737,7 +13737,7 @@ biz.at info.at // info.cx : http://info.cx -// Submitted by Jacob Slater +// Submitted by June Slater info.cx // Interlegis : http://www.interlegis.leg.br @@ -13786,6 +13786,10 @@ iopsys.se // Submitted by Matthew Hardeman ipifony.net +// ir.md : https://nic.ir.md +// Submitted by Ali Soizi +ir.md + // IServ GmbH : https://iserv.de // Submitted by Mario Hoberg iservschule.de @@ -14141,7 +14145,7 @@ co.pl // Managed by Corporate Domains // Microsoft Azure : https://home.azure *.azurecontainer.io -*.cloudapp.azure.com +cloudapp.azure.com azure-api.net azureedge.net azurefd.net @@ -14255,6 +14259,10 @@ nh-serv.co.uk // Submitted by Jeff Wheelhouse nfshost.com +// NFT.Storage : https://nft.storage/ +// Submitted by Vasco Santos or +ipfs.nftstorage.link + // Noop : https://noop.app // Submitted by Nathaniel Schweinberg *.developer.app diff --git a/netwerk/dns/nsEffectiveTLDService.cpp b/netwerk/dns/nsEffectiveTLDService.cpp index fafbc296d5..fc9e8c0692 100644 --- a/netwerk/dns/nsEffectiveTLDService.cpp +++ b/netwerk/dns/nsEffectiveTLDService.cpp @@ -74,7 +74,7 @@ NS_IMETHODIMP nsEffectiveTLDService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { /** - * Signal sent from netwerk/dns/PublicSuffixList.jsm + * Signal sent from netwerk/dns/PublicSuffixList.sys.mjs * aSubject is the nsIFile object for dafsa.bin * aData is the absolute path to the dafsa.bin file (not used) */ diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index ccd6dca57b..ad28cbb284 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -3,6 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsIThreadPool.h" #if defined(HAVE_RES_NINIT) # include # include @@ -137,6 +138,24 @@ class nsResState { #endif // RES_RETRY_ON_FAILURE +class DnsThreadListener final : public nsIThreadPoolListener { + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSITHREADPOOLLISTENER + private: + virtual ~DnsThreadListener() = default; +}; + +NS_IMETHODIMP +DnsThreadListener::OnThreadCreated() { return NS_OK; } + +NS_IMETHODIMP +DnsThreadListener::OnThreadShuttingDown() { + DNSThreadShutdown(); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(DnsThreadListener, nsIThreadPoolListener) + //---------------------------------------------------------------------------- static const char kPrefGetTtl[] = "network.dns.get-ttl"; @@ -252,6 +271,8 @@ nsresult nsHostResolver::Init() MOZ_NO_THREAD_SAFETY_ANALYSIS { MOZ_ALWAYS_SUCCEEDS( threadPool->SetThreadStackSize(nsIThreadManager::kThreadPoolStackSize)); MOZ_ALWAYS_SUCCEEDS(threadPool->SetName("DNS Resolver"_ns)); + nsCOMPtr listener = new DnsThreadListener(); + threadPool->SetListener(listener); mResolverThreads = ToRefPtr(std::move(threadPool)); return NS_OK; diff --git a/netwerk/dns/nsIDNService.cpp b/netwerk/dns/nsIDNService.cpp index 3db169d3af..6a87c8ee06 100644 --- a/netwerk/dns/nsIDNService.cpp +++ b/netwerk/dns/nsIDNService.cpp @@ -10,6 +10,8 @@ #include "nsReadableUtils.h" #include "nsCRT.h" #include "nsServiceManagerUtils.h" +#include "nsString.h" +#include "nsStringFwd.h" #include "nsUnicharUtils.h" #include "nsUnicodeProperties.h" #include "harfbuzz/hb.h" @@ -286,12 +288,35 @@ nsresult nsIDNService::ACEtoUTF8(const nsACString& input, nsACString& _retval, input.EndReading(end); _retval.Truncate(); + if (input.IsEmpty()) { + return NS_OK; + } + + nsAutoCString tld; + nsCString::const_iterator it = end, tldEnd = end; + --it; + if (it != start && *it == (char16_t)'.') { + // This is an FQDN (ends in .) + // Skip this dot to extract the TLD + tldEnd = it; + --it; + } + // Find last . and compute TLD + while (it != start) { + if (*it == (char16_t)'.') { + ++it; + tld.Assign(Substring(it, tldEnd)); + break; + } + --it; + } + // loop and decode nodes while (start != end) { len++; if (*start++ == '.') { nsDependentCSubstring origLabel(input, offset, len - 1); - if (NS_FAILED(decodeACE(origLabel, decodedBuf, flag))) { + if (NS_FAILED(decodeACE(origLabel, decodedBuf, flag, tld))) { // If decoding failed, use the original input sequence // for this label. _retval.Append(origLabel); @@ -307,7 +332,7 @@ nsresult nsIDNService::ACEtoUTF8(const nsACString& input, nsACString& _retval, // decode the last node if (len) { nsDependentCSubstring origLabel(input, offset, len); - if (NS_FAILED(decodeACE(origLabel, decodedBuf, flag))) { + if (NS_FAILED(decodeACE(origLabel, decodedBuf, flag, tld))) { _retval.Append(origLabel); } else { _retval.Append(decodedBuf); @@ -343,8 +368,7 @@ NS_IMETHODIMP nsIDNService::IsACE(const nsACString& input, bool* _retval) { return NS_OK; } -NS_IMETHODIMP nsIDNService::Normalize(const nsACString& input, - nsACString& output) { +nsresult nsIDNService::Normalize(const nsACString& input, nsACString& output) { // protect against bogus input NS_ENSURE_TRUE(IsUtf8(input), NS_ERROR_UNEXPECTED); @@ -562,7 +586,7 @@ nsresult nsIDNService::stringPrepAndACE(const nsAString& in, nsACString& out, return NS_OK; } - if (flag == eStringPrepForUI && NS_SUCCEEDED(rv) && isLabelSafe(in)) { + if (flag == eStringPrepForUI && NS_SUCCEEDED(rv) && isLabelSafe(in, u""_ns)) { CopyUTF16toUTF8(strPrep, out); return NS_OK; } @@ -598,7 +622,7 @@ void nsIDNService::normalizeFullStops(nsAString& s) { } nsresult nsIDNService::decodeACE(const nsACString& in, nsACString& out, - stringPrepFlag flag) { + stringPrepFlag flag, const nsACString& aTLD) { bool isAce; IsACE(in, &isAce); if (!isAce) { @@ -610,7 +634,9 @@ nsresult nsIDNService::decodeACE(const nsACString& in, nsACString& out, nsresult result = IDNA2008ToUnicode(in, utf16); NS_ENSURE_SUCCESS(result, result); - if (flag != eStringPrepForUI || isLabelSafe(utf16)) { + NS_ConvertUTF8toUTF16 tld(aTLD); + + if (flag != eStringPrepForUI || isLabelSafe(utf16, tld)) { CopyUTF16toUTF8(utf16, out); } else { out.Assign(in); @@ -652,17 +678,21 @@ enum ScriptCombo : int32_t { } // namespace mozilla::net -bool nsIDNService::isLabelSafe(const nsAString& label) { - AutoReadLock lock(mLock); +bool nsIDNService::isLabelSafe(const nsAString& label, const nsAString& tld) { + restrictionProfile profile{eASCIIOnlyProfile}; + { + AutoReadLock lock(mLock); - if (!isOnlySafeChars(PromiseFlatString(label), mIDNBlocklist)) { - return false; - } + if (!isOnlySafeChars(PromiseFlatString(label), mIDNBlocklist)) { + return false; + } - // We should never get here if the label is ASCII - NS_ASSERTION(!IsAscii(label), "ASCII label in IDN checking"); - if (mRestrictionProfile == eASCIIOnlyProfile) { - return false; + // We should never get here if the label is ASCII + NS_ASSERTION(!IsAscii(label), "ASCII label in IDN checking"); + if (mRestrictionProfile == eASCIIOnlyProfile) { + return false; + } + profile = mRestrictionProfile; } nsAString::const_iterator current, end; @@ -697,7 +727,7 @@ bool nsIDNService::isLabelSafe(const nsAString& label) { Script script = UnicodeProperties::GetScriptCode(ch); if (script != Script::COMMON && script != Script::INHERITED && script != lastScript) { - if (illegalScriptCombo(script, savedScript)) { + if (illegalScriptCombo(profile, script, savedScript)) { return false; } } @@ -708,11 +738,39 @@ bool nsIDNService::isLabelSafe(const nsAString& label) { return false; } + Script nextScript = Script::INVALID; + if (current != end) { + nextScript = UnicodeProperties::GetScriptCode(*current); + } + + if (ch == 0x30FB && + (lastScript == Script::LATIN || nextScript == Script::LATIN)) { + return false; + } + if (ch == 0x307 && (previousChar == 'i' || previousChar == 'j' || previousChar == 'l')) { return false; } + // U+00B7 is only allowed on Catalan domains between two l's. + if (ch == 0xB7 && (!tld.EqualsLiteral("cat") || previousChar != 'l' || + current == end || *current != 'l')) { + return false; + } + + // Disallow Icelandic confusables for domains outside Icelandic and Faroese + // ccTLD (.is, .fo) + if ((ch == 0xFE || ch == 0xF0) && !tld.EqualsLiteral("is") && + !tld.EqualsLiteral("fo")) { + return false; + } + + // Block single/double-quote-like characters. + if (ch == 0x2BB || ch == 0x2BC) { + return false; + } + // Check for mixed numbering systems auto genCat = GetGeneralCategory(ch); if (genCat == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) { @@ -834,7 +892,8 @@ static const ScriptCombo scriptComboTable[13][9] = { /* KORE */ {FAIL, FAIL, FAIL, KORE, KORE, FAIL, FAIL, KORE, FAIL}, /* HNLT */ {CHNA, FAIL, FAIL, KORE, HNLT, JPAN, JPAN, HNLT, FAIL}}; -bool nsIDNService::illegalScriptCombo(Script script, ScriptCombo& savedScript) { +bool nsIDNService::illegalScriptCombo(restrictionProfile profile, Script script, + ScriptCombo& savedScript) { if (savedScript == ScriptCombo::UNSET) { savedScript = findScriptIndex(script); return false; @@ -849,7 +908,6 @@ bool nsIDNService::illegalScriptCombo(Script script, ScriptCombo& savedScript) { * In the Moderately Restrictive profile Latin mixed with any other * single script is allowed. */ - return ((savedScript == OTHR && - mRestrictionProfile == eHighlyRestrictiveProfile) || + return ((savedScript == OTHR && profile == eHighlyRestrictiveProfile) || savedScript == FAIL); } diff --git a/netwerk/dns/nsIDNService.h b/netwerk/dns/nsIDNService.h index 1e90191326..6e5900e842 100644 --- a/netwerk/dns/nsIDNService.h +++ b/netwerk/dns/nsIDNService.h @@ -16,6 +16,7 @@ #include "mozilla/UniquePtr.h" #include "nsString.h" +#include "nsStringFwd.h" class nsIPrefBranch; @@ -83,8 +84,8 @@ class nsIDNService final : public nsIIDNService { * display, the output is the same as the input * @see isLabelSafe */ - nsresult decodeACE(const nsACString& in, nsACString& out, - stringPrepFlag flag); + nsresult decodeACE(const nsACString& in, nsACString& out, stringPrepFlag flag, + const nsACString& tld); /** * Convert complete domain names between UTF8 and ACE and vice versa @@ -98,6 +99,8 @@ class nsIDNService final : public nsIIDNService { nsresult ACEtoUTF8(const nsACString& input, nsACString& _retval, stringPrepFlag flag); + nsresult Normalize(const nsACString& input, nsACString& output); + void prefsChanged(const char* pref); static void PrefChanged(const char* aPref, void* aSelf) { @@ -132,7 +135,19 @@ class nsIDNService final : public nsIIDNService { * Both simplified-only and traditional-only Chinese characters * XXX this test was disabled by bug 857481 */ - bool isLabelSafe(const nsAString& label) MOZ_EXCLUDES(mLock); + bool isLabelSafe(const nsAString& label, const nsAString& tld) + MOZ_EXCLUDES(mLock); + + /** + * Restriction-level Detection profiles defined in UTR 39 + * http://www.unicode.org/reports/tr39/#Restriction_Level_Detection, + * and selected by the pref network.IDN.restriction_profile + */ + enum restrictionProfile { + eASCIIOnlyProfile, + eHighlyRestrictiveProfile, + eModeratelyRestrictiveProfile + }; /** * Determine whether a combination of scripts in a single label is @@ -148,9 +163,9 @@ class nsIDNService final : public nsIIDNService { * For the "Moderately restrictive" profile, Latin is also allowed * with other scripts except Cyrillic and Greek */ - bool illegalScriptCombo(mozilla::intl::Script script, - mozilla::net::ScriptCombo& savedScript) - MOZ_REQUIRES_SHARED(mLock); + bool illegalScriptCombo(restrictionProfile profile, + mozilla::intl::Script script, + mozilla::net::ScriptCombo& savedScript); /** * Convert a DNS label from ASCII to Unicode using IDNA2008 @@ -173,16 +188,6 @@ class nsIDNService final : public nsIIDNService { // guarded by mLock nsTArray mIDNBlocklist MOZ_GUARDED_BY(mLock); - /** - * Restriction-level Detection profiles defined in UTR 39 - * http://www.unicode.org/reports/tr39/#Restriction_Level_Detection, - * and selected by the pref network.IDN.restriction_profile - */ - enum restrictionProfile { - eASCIIOnlyProfile, - eHighlyRestrictiveProfile, - eModeratelyRestrictiveProfile - }; // guarded by mLock; restrictionProfile mRestrictionProfile MOZ_GUARDED_BY(mLock){ eASCIIOnlyProfile}; diff --git a/netwerk/dns/nsIIDNService.idl b/netwerk/dns/nsIIDNService.idl index 47ef561237..218e64a6e2 100644 --- a/netwerk/dns/nsIIDNService.idl +++ b/netwerk/dns/nsIIDNService.idl @@ -42,12 +42,6 @@ interface nsIIDNService : nsISupports */ boolean isACE(in ACString input); - /** - * Performs the unicode normalization needed for hostnames in IDN, - * for callers that want early normalization. - */ - AUTF8String normalize(in AUTF8String input); - /** * Normalizes and converts a host to UTF-8 if the host is in the IDN * whitelist, otherwise converts it to ACE. This is useful for display diff --git a/netwerk/dns/tests/unit/test_PublicSuffixList.js b/netwerk/dns/tests/unit/test_PublicSuffixList.js index ad61abea8e..a0d837e465 100644 --- a/netwerk/dns/tests/unit/test_PublicSuffixList.js +++ b/netwerk/dns/tests/unit/test_PublicSuffixList.js @@ -71,7 +71,7 @@ const downloadToDiskBackup = CLIENT.attachments.downloadToDisk; // returns a fake fileURI and sends a signal with filePath and no nsifile function mockDownloadToDisk() { downloadToDiskCalled = false; - CLIENT.attachments.downloadToDisk = async rec => { + CLIENT.attachments.downloadToDisk = async () => { downloadToDiskCalled = true; return `file://${mockedFilePath}`; // Create a fake file URI }; -- cgit v1.2.3