From 0c3deda0ffa58cb727988c251995d6ad8ffad6ab Mon Sep 17 00:00:00 2001 From: "jshin%mailaps.org" Date: Mon, 20 Jun 2005 05:23:30 +0000 Subject: [PATCH] bug 286584 : Implement IDN punycode display by .tld (r=gerv, sr=darin, a=asa) --- modules/libpref/src/init/all.js | 20 ++++++++++++++++++- netwerk/base/src/nsStandardURL.cpp | 31 ++++++++++++++++++++++++++++-- netwerk/base/src/nsStandardURL.h | 2 ++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 6d04fb4449d..ea78a217519 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -556,7 +556,25 @@ pref("network.enableIDN", true); // This preference, if true, causes all UTF-8 domain names to be normalized to // punycode. The intention is to allow UTF-8 domain names as input, but never // generate them from punycode. -pref("network.IDN_show_punycode", true); +pref("network.IDN_show_punycode", false); + +// TLDs with "network.IDN.whitelist.tld" explicitly set to true are treated as +// IDN-safe. Otherwise, they're treated as unsafe and punycode will be used +// for displaying them in the UI (e.g. URL bar). Note that these preferences +// are referred to ONLY when "network.IDN_show_punycode" is false. In other +// words, all IDNs will be shown in punycode if "network.IDN_show_punycode" +// is true. +pref("network.IDN.whitelist.at", true); +pref("network.IDN.whitelist.ch", true); +pref("network.IDN.whitelist.cn", true); +pref("network.IDN.whitelist.de", true); +pref("network.IDN.whitelist.dk", true); +pref("network.IDN.whitelist.jp", true); +pref("network.IDN.whitelist.kr", true); +pref("network.IDN.whitelist.li", true); +pref("network.IDN.whitelist.no", true); +pref("network.IDN.whitelist.se", true); +pref("network.IDN.whitelist.tw", true); // This preference specifies a list of domains for which DNS lookups will be // IPv4 only. Works around broken DNS servers which can't handle IPv6 lookups diff --git a/netwerk/base/src/nsStandardURL.cpp b/netwerk/base/src/nsStandardURL.cpp index 1b9ef1636b2..d0d78c6415a 100644 --- a/netwerk/base/src/nsStandardURL.cpp +++ b/netwerk/base/src/nsStandardURL.cpp @@ -64,6 +64,7 @@ PRBool nsStandardURL::gInitialized = PR_FALSE; PRBool nsStandardURL::gEscapeUTF8 = PR_TRUE; PRBool nsStandardURL::gAlwaysEncodeInUTF8 = PR_TRUE; PRBool nsStandardURL::gShowPunycode = PR_FALSE; +nsIPrefBranch *nsStandardURL::gIDNWhitelistPrefBranch = nsnull; #if defined(PR_LOGGING) // @@ -137,6 +138,7 @@ end: #define NS_NET_PREF_ENABLEIDN "network.enableIDN" #define NS_NET_PREF_ALWAYSENCODEINUTF8 "network.standard-url.encode-utf8" #define NS_NET_PREF_SHOWPUNYCODE "network.IDN_show_punycode" +#define NS_NET_PREF_IDNWHITELIST "network.IDN.whitelist." NS_IMPL_ISUPPORTS1(nsStandardURL::nsPrefObserver, nsIObserver) @@ -302,6 +304,14 @@ nsStandardURL::InitGlobalObjects() prefBranch->AddObserver(NS_NET_PREF_SHOWPUNYCODE, obs.get(), PR_FALSE); PrefsChanged(prefBranch, nsnull); + + nsCOMPtr prefs = do_QueryInterface(prefBranch); + if (prefs) { + nsCOMPtr branch; + if (NS_SUCCEEDED(prefs->GetBranch( NS_NET_PREF_IDNWHITELIST, + getter_AddRefs(branch) ))) + NS_ADDREF(gIDNWhitelistPrefBranch = branch); + } } } @@ -310,6 +320,7 @@ nsStandardURL::ShutdownGlobalObjects() { NS_IF_RELEASE(gIDN); NS_IF_RELEASE(gCharsetMgr); + NS_IF_RELEASE(gIDNWhitelistPrefBranch); } //---------------------------------------------------------------------------- @@ -843,7 +854,7 @@ nsStandardURL::PrefsChanged(nsIPrefBranch *prefs, const char *pref) /* static */ nsresult nsStandardURL::ACEtoUTF8(const nsCSubstring &host, nsCString &result) { - if (gShowPunycode) { + if (gShowPunycode || !IsInWhitelist(host)) { result = host; return NS_OK; } @@ -854,12 +865,28 @@ nsStandardURL::ACEtoUTF8(const nsCSubstring &host, nsCString &result) /* static */ nsresult nsStandardURL::NormalizeUTF8(const nsCSubstring &host, nsCString &result) { - if (gShowPunycode) + if (gShowPunycode || !IsInWhitelist(host)) return gIDN->ConvertUTF8toACE(host, result); return gIDN->Normalize(host, result); } +/* static */ PRBool +nsStandardURL::IsInWhitelist(const nsCSubstring &host) +{ + PRInt32 pos; + PRBool safe; + + if (gIDNWhitelistPrefBranch && + (pos = nsCAutoString(host).RFind(".")) != kNotFound && + NS_SUCCEEDED(gIDNWhitelistPrefBranch-> + GetBoolPref(nsCAutoString(Substring(host, pos + 1)).get(), + &safe))) + return safe; + + return PR_FALSE; +} + //---------------------------------------------------------------------------- // nsStandardURL::nsISupports //---------------------------------------------------------------------------- diff --git a/netwerk/base/src/nsStandardURL.h b/netwerk/base/src/nsStandardURL.h index d1612df48ed..6ab40f14126 100644 --- a/netwerk/base/src/nsStandardURL.h +++ b/netwerk/base/src/nsStandardURL.h @@ -221,6 +221,7 @@ private: // IDN routines static nsresult ACEtoUTF8(const nsCSubstring &in, nsCString &out); static nsresult NormalizeUTF8(const nsCSubstring &in, nsCString &out); + static PRBool IsInWhitelist(const nsCSubstring &host); // mSpec contains the normalized version of the URL spec (UTF-8 encoded). nsCString mSpec; @@ -272,6 +273,7 @@ private: static PRBool gEscapeUTF8; static PRBool gAlwaysEncodeInUTF8; static PRBool gShowPunycode; + static nsIPrefBranch *gIDNWhitelistPrefBranch; }; #define NS_THIS_STANDARDURL_IMPL_CID \