diff options
author | beat <beat@FreeBSD.org> | 2009-06-13 15:05:48 +0800 |
---|---|---|
committer | beat <beat@FreeBSD.org> | 2009-06-13 15:05:48 +0800 |
commit | dd57a086b559cde4a78c96c3365634fd98d99d78 (patch) | |
tree | 605e20fc6e44961e6c4d1bed667e1d777120c7ca /www/firefox | |
parent | bb0d2b306718d3ba2a8f0efcd706c3c3abd54387 (diff) | |
download | freebsd-ports-gnome-dd57a086b559cde4a78c96c3365634fd98d99d78.tar.gz freebsd-ports-gnome-dd57a086b559cde4a78c96c3365634fd98d99d78.tar.zst freebsd-ports-gnome-dd57a086b559cde4a78c96c3365634fd98d99d78.zip |
- Backport patches to fix the following security vulnerabilities:
CVE-2009-1834
CVE-2009-1835
CVE-2009-1836
CVE-2009-1838
CVE-2009-1841
Obtained from: Mozilla Bugzilla
Security: http://www.vuxml.org/freebsd/da185955-5738-11de-b857-000f20797ede.html
With hat: Gecko gang
Diffstat (limited to 'www/firefox')
-rw-r--r-- | www/firefox/Makefile | 2 | ||||
-rw-r--r-- | www/firefox/files/patch-ff-479413 | 1184 | ||||
-rw-r--r-- | www/firefox/files/patch-ff-479560 | 69 | ||||
-rw-r--r-- | www/firefox/files/patch-ff-479880 | 145 | ||||
-rw-r--r-- | www/firefox/files/patch-ff-489131 | 29 | ||||
-rw-r--r-- | www/firefox/files/patch-ff-491801 | 91 |
6 files changed, 1519 insertions, 1 deletions
diff --git a/www/firefox/Makefile b/www/firefox/Makefile index ec92d9bcd379..8263833c7f3d 100644 --- a/www/firefox/Makefile +++ b/www/firefox/Makefile @@ -8,7 +8,7 @@ PORTNAME= firefox DISTVERSION= 2.0.0.20 -PORTREVISION= 7 +PORTREVISION= 8 PORTEPOCH= 1 CATEGORIES= www ipv6 MASTER_SITES= ${MASTER_SITE_MOZILLA_EXTENDED} diff --git a/www/firefox/files/patch-ff-479413 b/www/firefox/files/patch-ff-479413 new file mode 100644 index 000000000000..7f5e606e6401 --- /dev/null +++ b/www/firefox/files/patch-ff-479413 @@ -0,0 +1,1184 @@ +Index: netwerk/base/src/nsStandardURL.cpp +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/base/src/nsStandardURL.cpp,v +retrieving revision 1.82.4.12 +diff -u -9 -p -r1.82.4.12 nsStandardURL.cpp +--- netwerk/base/src/nsStandardURL.cpp 7 Aug 2008 21:24:18 -0000 1.82.4.12 ++++ netwerk/base/src/nsStandardURL.cpp 3 Jun 2009 09:48:29 -0000 +@@ -52,25 +52,23 @@ + #include "nsIPrefBranch2.h" + #include "nsIIDNService.h" + #include "nsNetUtil.h" + #include "prlog.h" + #include "nsAutoPtr.h" + + static NS_DEFINE_CID(kThisImplCID, NS_THIS_STANDARDURL_IMPL_CID); + static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID); + +-nsIIDNService *nsStandardURL::gIDN = nsnull; ++nsIIDNService_MOZILLA_1_8_BRANCH *nsStandardURL::gIDN = nsnull; + nsICharsetConverterManager *nsStandardURL::gCharsetMgr = nsnull; + 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) + // + // setenv NSPR_LOG_MODULES nsStandardURL:5 + // + static PRLogModuleInfo *gStandardURLLog; + #endif + #define LOG(args) PR_LOG(gStandardURLLog, PR_LOG_DEBUG, args) + #define LOG_ENABLED() PR_LOG_TEST(gStandardURLLog, PR_LOG_DEBUG) +@@ -131,20 +129,18 @@ end: + } + + //---------------------------------------------------------------------------- + // nsStandardURL::nsPrefObserver + //---------------------------------------------------------------------------- + + #define NS_NET_PREF_ESCAPEUTF8 "network.standard-url.escape-utf8" + #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) + + NS_IMETHODIMP nsStandardURL:: + nsPrefObserver::Observe(nsISupports *subject, + const char *topic, + const PRUnichar *data) + { + if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { +@@ -298,38 +294,28 @@ nsStandardURL::~nsStandardURL() + void + nsStandardURL::InitGlobalObjects() + { + nsCOMPtr<nsIPrefBranch2> prefBranch( do_GetService(NS_PREFSERVICE_CONTRACTID) ); + if (prefBranch) { + nsCOMPtr<nsIObserver> obs( new nsPrefObserver() ); + prefBranch->AddObserver(NS_NET_PREF_ESCAPEUTF8, obs.get(), PR_FALSE); + prefBranch->AddObserver(NS_NET_PREF_ALWAYSENCODEINUTF8, obs.get(), PR_FALSE); + prefBranch->AddObserver(NS_NET_PREF_ENABLEIDN, obs.get(), PR_FALSE); +- prefBranch->AddObserver(NS_NET_PREF_SHOWPUNYCODE, obs.get(), PR_FALSE); + + PrefsChanged(prefBranch, nsnull); +- +- nsCOMPtr<nsIPrefService> prefs = do_QueryInterface(prefBranch); +- if (prefs) { +- nsCOMPtr<nsIPrefBranch> branch; +- if (NS_SUCCEEDED(prefs->GetBranch( NS_NET_PREF_IDNWHITELIST, +- getter_AddRefs(branch) ))) +- NS_ADDREF(gIDNWhitelistPrefBranch = branch); +- } + } + } + + void + nsStandardURL::ShutdownGlobalObjects() + { + NS_IF_RELEASE(gIDN); + NS_IF_RELEASE(gCharsetMgr); +- NS_IF_RELEASE(gIDNWhitelistPrefBranch); + } + + //---------------------------------------------------------------------------- + // nsStandardURL <private> + //---------------------------------------------------------------------------- + + void + nsStandardURL::Clear() + { +@@ -378,45 +364,35 @@ nsStandardURL::EscapeIPv6(const char *ho + return PR_FALSE; + } + + PRBool + 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 PR_TRUE iff it writes something to |result|. ++ // this function returns PR_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"); + +- if (IsASCII(host)) { +- PRBool isACE; +- if (gIDN && +- NS_SUCCEEDED(gIDN->IsACE(host, &isACE)) && isACE && +- NS_SUCCEEDED(ACEtoDisplayIDN(host, result))) { ++ PRBool isASCII; ++ if (gIDN && ++ NS_SUCCEEDED(gIDN->ConvertToDisplayIDN(host, &isASCII, result))) { ++ if (!isASCII) + mHostEncoding = eEncoding_UTF8; +- return PR_TRUE; +- } +- } +- else { +- mHostEncoding = eEncoding_UTF8; +- if (gIDN && NS_SUCCEEDED(UTF8toDisplayIDN(host, result))) { +- // normalization could result in an ASCII only hostname +- if (IsASCII(result)) +- mHostEncoding = eEncoding_ASCII; +- return PR_TRUE; +- } ++ ++ return PR_TRUE; + } + + result.Truncate(); + return PR_FALSE; + } + + void + nsStandardURL::CoalescePath(netCoalesceFlags coalesceFlag, char *path) + { +@@ -819,98 +795,40 @@ nsStandardURL::PrefsChanged(nsIPrefBranc + LOG(("nsStandardURL::PrefsChanged [pref=%s]\n", pref)); + + #define PREF_CHANGED(p) ((pref == nsnull) || !strcmp(pref, p)) + #define GOT_PREF(p, b) (NS_SUCCEEDED(prefs->GetBoolPref(p, &b))) + + if (PREF_CHANGED(NS_NET_PREF_ENABLEIDN)) { + NS_IF_RELEASE(gIDN); + if (GOT_PREF(NS_NET_PREF_ENABLEIDN, val) && val) { + // initialize IDN +- nsCOMPtr<nsIIDNService> serv(do_GetService(NS_IDNSERVICE_CONTRACTID)); ++ nsCOMPtr<nsIIDNService_MOZILLA_1_8_BRANCH> ++ serv(do_GetService(NS_IDNSERVICE_CONTRACTID)); + if (serv) + NS_ADDREF(gIDN = serv.get()); + } + LOG(("IDN support %s\n", gIDN ? "enabled" : "disabled")); + } + + if (PREF_CHANGED(NS_NET_PREF_ESCAPEUTF8)) { + if (GOT_PREF(NS_NET_PREF_ESCAPEUTF8, val)) + gEscapeUTF8 = val; + LOG(("escape UTF-8 %s\n", gEscapeUTF8 ? "enabled" : "disabled")); + } + + if (PREF_CHANGED(NS_NET_PREF_ALWAYSENCODEINUTF8)) { + if (GOT_PREF(NS_NET_PREF_ALWAYSENCODEINUTF8, val)) + gAlwaysEncodeInUTF8 = val; + LOG(("encode in UTF-8 %s\n", gAlwaysEncodeInUTF8 ? "enabled" : "disabled")); + } +- +- if (PREF_CHANGED(NS_NET_PREF_SHOWPUNYCODE)) { +- if (GOT_PREF(NS_NET_PREF_SHOWPUNYCODE, val)) +- gShowPunycode = val; +- LOG(("show punycode %s\n", gShowPunycode ? "enabled" : "disabled")); +- } + #undef PREF_CHANGED + #undef GOT_PREF + } +- +-/* static */ nsresult +-nsStandardURL::ACEtoDisplayIDN(const nsCSubstring &host, nsCString &result) +-{ +- if (gShowPunycode || !IsInWhitelist(host)) { +- result = host; +- return NS_OK; +- } +- +- return gIDN->ConvertACEtoUTF8(host, result); +-} +- +-/* static */ nsresult +-nsStandardURL::UTF8toDisplayIDN(const nsCSubstring &host, nsCString &result) +-{ +- // We have to normalize the hostname before testing against the domain +- // whitelist. See bug 315411. +- +- nsCAutoString temp; +- if (gShowPunycode || NS_FAILED(gIDN->Normalize(host, temp))) +- return gIDN->ConvertUTF8toACE(host, result); +- +- PRBool isACE = PR_FALSE; +- gIDN->IsACE(temp, &isACE); +- +- // If host is converted to ACE by the normalizer, then the host may contain +- // unsafe characters. See bug 283016, bug 301694, and bug 309311. +- +- if (!isACE && !IsInWhitelist(temp)) +- return gIDN->ConvertUTF8toACE(temp, result); +- +- result = temp; +- return NS_OK; +-} +- +-/* static */ PRBool +-nsStandardURL::IsInWhitelist(const nsCSubstring &host) +-{ +- PRInt32 pos; +- PRBool safe; +- +- // XXX This code uses strings inefficiently. +- +- 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 + //---------------------------------------------------------------------------- + + NS_IMPL_ADDREF(nsStandardURL) + NS_IMPL_RELEASE(nsStandardURL) + + NS_INTERFACE_MAP_BEGIN(nsStandardURL) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL) +Index: netwerk/base/src/nsStandardURL.h +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/base/src/nsStandardURL.h,v +retrieving revision 1.28.4.1 +diff -u -9 -p -r1.28.4.1 nsStandardURL.h +--- netwerk/base/src/nsStandardURL.h 13 Sep 2005 18:23:14 -0000 1.28.4.1 ++++ netwerk/base/src/nsStandardURL.h 3 Jun 2009 09:48:29 -0000 +@@ -49,19 +49,19 @@ + #include "nsIURLParser.h" + #include "nsIUnicodeEncoder.h" + #include "nsIObserver.h" + #include "nsIIOService.h" + #include "nsCOMPtr.h" + #include "nsURLHelper.h" + + class nsIBinaryInputStream; + class nsIBinaryOutputStream; +-class nsIIDNService; ++class nsIIDNService_MOZILLA_1_8_BRANCH; + class nsICharsetConverterManager; + class nsIPrefBranch; + + //----------------------------------------------------------------------------- + // standard URL implementation + //----------------------------------------------------------------------------- + + class nsStandardURL : public nsIFileURL + , public nsIStandardURL +@@ -213,23 +213,18 @@ private: + void ShiftFromQuery(PRInt32 diff) { mQuery.mPos += diff; ShiftFromRef(diff); } + void ShiftFromRef(PRInt32 diff) { mRef.mPos += diff; } + + // fastload helper functions + nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &); + nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &); + + static void PrefsChanged(nsIPrefBranch *prefs, const char *pref); + +- // IDN routines +- static nsresult ACEtoDisplayIDN(const nsCSubstring &in, nsCString &out); +- static nsresult UTF8toDisplayIDN(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; + PRInt32 mDefaultPort; + PRInt32 mPort; + + // url parts (relative to mSpec) + URLSegment mScheme; + URLSegment mAuthority; + URLSegment mUsername; +@@ -262,25 +257,23 @@ private: + + PRUint32 mHostEncoding : 2; // eEncoding_xxx + PRUint32 mSpecEncoding : 2; // eEncoding_xxx + PRUint32 mURLType : 2; // nsIStandardURL::URLTYPE_xxx + PRUint32 mMutable : 1; // nsIStandardURL::mutable + PRUint32 mSupportsFileURL : 1; // QI to nsIFileURL? + + // global objects. don't use COMPtr as its destructor will cause a + // coredump if we leak it. +- static nsIIDNService *gIDN; ++ static nsIIDNService_MOZILLA_1_8_BRANCH *gIDN; + static nsICharsetConverterManager *gCharsetMgr; + static PRBool gInitialized; + static PRBool gEscapeUTF8; + static PRBool gAlwaysEncodeInUTF8; +- static PRBool gShowPunycode; +- static nsIPrefBranch *gIDNWhitelistPrefBranch; + }; + + #define NS_THIS_STANDARDURL_IMPL_CID \ + { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \ + 0xb8e3e97b, \ + 0x1ccd, \ + 0x4b45, \ + {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \ + } +Index: netwerk/dns/public/nsIIDNService.idl +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/dns/public/nsIIDNService.idl,v +retrieving revision 1.4 +diff -u -9 -p -r1.4 nsIIDNService.idl +--- netwerk/dns/public/nsIIDNService.idl 3 Apr 2004 07:32:18 -0000 1.4 ++++ netwerk/dns/public/nsIIDNService.idl 3 Jun 2009 09:48:29 -0000 +@@ -18,19 +18,21 @@ + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): bobj@netscape.com, + * brendan@mozilla.org, + * darin@netscape.com, + * ftang@netscape.com, + * gagan@netscape.com, + * nhotta@netscape.com, +- * william.tan@i-dns.net ++ * william.tan@i-dns.net, ++ * dwitte@stanford.edu, ++ * smontagu@smontagu.org + * + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your +@@ -83,9 +85,21 @@ 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); + }; ++ ++[scriptable, uuid(7be196fc-82fd-40d8-9d8c-6421faddeee9)] ++interface nsIIDNService_MOZILLA_1_8_BRANCH : nsIIDNService ++{ ++ /** ++ * 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 ++ * purposes and to ensure an encoding consistent with nsIURI::GetHost(). ++ * If the result is ASCII or ACE encoded, |isASCII| will be true. ++ */ ++ AUTF8String convertToDisplayIDN(in AUTF8String input, out boolean isASCII); ++}; +\ No newline at end of file +Index: netwerk/dns/src/nsIDNService.cpp +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/dns/src/nsIDNService.cpp,v +retrieving revision 1.28.2.1 +diff -u -9 -p -r1.28.2.1 nsIDNService.cpp +--- netwerk/dns/src/nsIDNService.cpp 27 Aug 2008 07:36:26 -0000 1.28.2.1 ++++ netwerk/dns/src/nsIDNService.cpp 3 Jun 2009 09:48:29 -0000 +@@ -1,10 +1,10 @@ +-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + /* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, +@@ -51,43 +51,50 @@ + //----------------------------------------------------------------------------- + // RFC 1034 - 3.1. Name space specifications and terminology + static const PRUint32 kMaxDNSNodeLen = 63; + + //----------------------------------------------------------------------------- + + #define NS_NET_PREF_IDNTESTBED "network.IDN_testbed" + #define NS_NET_PREF_IDNPREFIX "network.IDN_prefix" + #define NS_NET_PREF_IDNBLACKLIST "network.IDN.blacklist_chars" ++#define NS_NET_PREF_SHOWPUNYCODE "network.IDN_show_punycode" ++#define NS_NET_PREF_IDNWHITELIST "network.IDN.whitelist." + + inline PRBool isOnlySafeChars(const nsAFlatString& in, + const nsAFlatString& blacklist) + { + return (blacklist.IsEmpty() || + in.FindCharInSet(blacklist) == kNotFound); + } + + //----------------------------------------------------------------------------- + // nsIDNService + //----------------------------------------------------------------------------- + + /* Implementation file */ + NS_IMPL_THREADSAFE_ISUPPORTS3(nsIDNService, +- nsIIDNService, ++ nsIIDNService_MOZILLA_1_8_BRANCH, + nsIObserver, + nsISupportsWeakReference) + + nsresult nsIDNService::Init() + { +- nsCOMPtr<nsIPrefBranch2> prefInternal(do_GetService(NS_PREFSERVICE_CONTRACTID)); ++ nsCOMPtr<nsIPrefService> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); ++ if (prefs) ++ prefs->GetBranch(NS_NET_PREF_IDNWHITELIST, getter_AddRefs(mIDNWhitelistPrefBranch)); ++ ++ nsCOMPtr<nsIPrefBranch2> prefInternal(do_QueryInterface(prefs)); + if (prefInternal) { + prefInternal->AddObserver(NS_NET_PREF_IDNTESTBED, this, PR_TRUE); + prefInternal->AddObserver(NS_NET_PREF_IDNPREFIX, this, PR_TRUE); + prefInternal->AddObserver(NS_NET_PREF_IDNBLACKLIST, this, PR_TRUE); ++ prefInternal->AddObserver(NS_NET_PREF_SHOWPUNYCODE, this, PR_TRUE); + prefsChanged(prefInternal, nsnull); + } + return NS_OK; + } + + NS_IMETHODIMP nsIDNService::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) + { +@@ -116,18 +123,23 @@ void nsIDNService::prefsChanged(nsIPrefB + nsCOMPtr<nsISupportsString> blacklist; + nsresult rv = prefBranch->GetComplexValue(NS_NET_PREF_IDNBLACKLIST, + NS_GET_IID(nsISupportsString), + getter_AddRefs(blacklist)); + if (NS_SUCCEEDED(rv)) + blacklist->ToString(getter_Copies(mIDNBlacklist)); + else + mIDNBlacklist.Truncate(); + } ++ if (!pref || NS_LITERAL_STRING(NS_NET_PREF_SHOWPUNYCODE).Equals(pref)) { ++ PRBool val; ++ if (NS_SUCCEEDED(prefBranch->GetBoolPref(NS_NET_PREF_SHOWPUNYCODE, &val))) ++ mShowPunycode = val; ++ } + } + + nsIDNService::nsIDNService() + { + nsresult rv; + + // initialize to the official prefix (RFC 3490 "5. ACE prefix") + const char kIDNSPrefix[] = "xn--"; + strcpy(mACEPrefix, kIDNSPrefix); +@@ -148,18 +160,23 @@ nsIDNService::~nsIDNService() + idn_nameprep_destroy(mNamePrepHandle); + } + + /* ACString ConvertUTF8toACE (in AUTF8String input); */ + NS_IMETHODIMP nsIDNService::ConvertUTF8toACE(const nsACString & input, nsACString & ace) + { + // protect against bogus input + NS_ENSURE_TRUE(IsUTF8(input), NS_ERROR_UNEXPECTED); + ++ return UTF8toACE(input, ace, PR_TRUE); ++} ++ ++nsresult nsIDNService::UTF8toACE(const nsACString & input, nsACString & ace, PRBool allowUnassigned) ++{ + nsresult rv; + NS_ConvertUTF8toUCS2 ustr(input); + + // map ideographic period to ASCII period etc. + normalizeFullStops(ustr); + + + PRUint32 len, offset; + len = 0; +@@ -169,45 +186,53 @@ NS_IMETHODIMP nsIDNService::ConvertUTF8t + nsAString::const_iterator start, end; + ustr.BeginReading(start); + ustr.EndReading(end); + ace.Truncate(); + + // encode nodes if non ASCII + while (start != end) { + len++; + if (*start++ == (PRUnichar)'.') { +- rv = stringPrepAndACE(Substring(ustr, offset, len - 1), encodedBuf); ++ rv = stringPrepAndACE(Substring(ustr, offset, len - 1), encodedBuf, ++ allowUnassigned); + NS_ENSURE_SUCCESS(rv, rv); + + ace.Append(encodedBuf); + ace.Append('.'); + offset += len; + len = 0; + } + } + + // add extra node for multilingual test bed + if (mMultilingualTestBed) + ace.AppendLiteral("mltbd."); + // encode the last node if non ASCII + if (len) { +- rv = stringPrepAndACE(Substring(ustr, offset, len), encodedBuf); ++ rv = stringPrepAndACE(Substring(ustr, offset, len), encodedBuf, ++ allowUnassigned); + NS_ENSURE_SUCCESS(rv, rv); + + ace.Append(encodedBuf); + } + + return NS_OK; + } + + /* [noscript] string ConvertACEtoUTF8 (in string input); */ + NS_IMETHODIMP nsIDNService::ConvertACEtoUTF8(const nsACString & input, nsACString & _retval) + { ++ return ACEtoUTF8(input, _retval, PR_TRUE); ++} ++ ++nsresult nsIDNService::ACEtoUTF8(const nsACString & input, nsACString & _retval, ++ PRBool allowUnassigned) ++{ + // RFC 3490 - 4.2 ToUnicode + // ToUnicode never fails. If any step fails, then the original input + // sequence is returned immediately in that step. + + if (!IsASCII(input)) { + _retval.Assign(input); + return NS_OK; + } + +@@ -217,32 +242,34 @@ NS_IMETHODIMP nsIDNService::ConvertACEto + nsACString::const_iterator start, end; + input.BeginReading(start); + input.EndReading(end); + _retval.Truncate(); + + // loop and decode nodes + while (start != end) { + len++; + if (*start++ == '.') { +- if (NS_FAILED(decodeACE(Substring(input, offset, len - 1), decodedBuf))) { ++ if (NS_FAILED(decodeACE(Substring(input, offset, len - 1), decodedBuf, ++ allowUnassigned))) { + _retval.Assign(input); + return NS_OK; + } + + _retval.Append(decodedBuf); + _retval.Append('.'); + offset += len; + len = 0; + } + } + // decode the last node + if (len) { +- if (NS_FAILED(decodeACE(Substring(input, offset, len), decodedBuf))) ++ if (NS_FAILED(decodeACE(Substring(input, offset, len), decodedBuf, ++ allowUnassigned))) + _retval.Assign(input); + else + _retval.Append(decodedBuf); + } + + return NS_OK; + } + + /* boolean encodedInACE (in ACString input); */ +@@ -266,30 +293,100 @@ NS_IMETHODIMP nsIDNService::IsACE(const + + NS_IMETHODIMP nsIDNService::Normalize(const nsACString & input, nsACString & output) + { + // protect against bogus input + NS_ENSURE_TRUE(IsUTF8(input), NS_ERROR_UNEXPECTED); + + NS_ConvertUTF8toUTF16 inUTF16(input); + normalizeFullStops(inUTF16); + +- nsAutoString outUTF16; +- nsresult rv = stringPrep(inUTF16, outUTF16); +- if (NS_FAILED(rv)) +- return rv; ++ // pass the domain name to stringprep label by label ++ nsAutoString outUTF16, outLabel; ++ ++ PRUint32 len = 0, offset = 0; ++ nsresult rv; ++ nsAString::const_iterator start, end; ++ inUTF16.BeginReading(start); ++ inUTF16.EndReading(end); ++ ++ while (start != end) { ++ len++; ++ if (*start++ == PRUnichar('.')) { ++ rv = stringPrep(Substring(inUTF16, offset, len - 1), outLabel, PR_TRUE); ++ NS_ENSURE_SUCCESS(rv, rv); ++ ++ outUTF16.Append(outLabel); ++ outUTF16.Append(PRUnichar('.')); ++ offset += len; ++ len = 0; ++ } ++ } ++ if (len) { ++ rv = stringPrep(Substring(inUTF16, offset, len), outLabel, PR_TRUE); ++ NS_ENSURE_SUCCESS(rv, rv); ++ ++ outUTF16.Append(outLabel); ++ } + + CopyUTF16toUTF8(outUTF16, output); + if (!isOnlySafeChars(outUTF16, mIDNBlacklist)) + return ConvertUTF8toACE(output, output); + + return NS_OK; + } + ++NS_IMETHODIMP nsIDNService::ConvertToDisplayIDN(const nsACString & input, PRBool * _isASCII, nsACString & _retval) ++{ ++ // If host is ACE, then convert to UTF-8 if the host is in the IDN whitelist. ++ // Else, if host is already UTF-8, then make sure it is normalized per IDN. ++ ++ nsresult rv; ++ ++ if (IsASCII(input)) { ++ // first, canonicalize the host to lowercase, for whitelist lookup ++ _retval = input; ++ ToLowerCase(_retval); ++ ++ PRBool isACE; ++ IsACE(_retval, &isACE); ++ ++ if (isACE && !mShowPunycode && isInWhitelist(_retval)) { ++ // ACEtoUTF8() can't fail, but might return the original ACE string ++ nsCAutoString temp(_retval); ++ ACEtoUTF8(temp, _retval, PR_FALSE); ++ *_isASCII = IsASCII(_retval); ++ } else { ++ *_isASCII = PR_TRUE; ++ } ++ } else { ++ if (mShowPunycode && NS_SUCCEEDED(ConvertUTF8toACE(input, _retval))) { ++ *_isASCII = PR_TRUE; ++ return NS_OK; ++ } ++ ++ // We have to normalize the hostname before testing against the domain ++ // whitelist. See bug 315411. ++ rv = Normalize(input, _retval); ++ if (NS_FAILED(rv)) return rv; ++ ++ // normalization could result in an ASCII-only hostname. alternatively, if ++ // the host is converted to ACE by the normalizer, then the host may contain ++ // unsafe characters, so leave it ACE encoded. see bug 283016, bug 301694, and bug 309311. ++ *_isASCII = IsASCII(_retval); ++ if (!*_isASCII && !isInWhitelist(_retval)) { ++ *_isASCII = PR_TRUE; ++ return ConvertUTF8toACE(_retval, _retval); ++ } ++ } ++ ++ return NS_OK; ++} ++ + //----------------------------------------------------------------------------- + + static void utf16ToUcs4(const nsAString& in, PRUint32 *out, PRUint32 outBufLen, PRUint32 *outLen) + { + PRUint32 i = 0; + nsAString::const_iterator start, end; + in.BeginReading(start); + in.EndReading(end); + +@@ -404,19 +501,24 @@ static nsresult encodeToRACE(const char* + // 3) Prohibit -- Check for any characters that are not allowed in the + // output. If any are found, return an error. This is described in section + // 5. + // + // 4) Check bidi -- Possibly check for right-to-left characters, and if any + // are found, make sure that the whole string satisfies the requirements + // for bidirectional strings. If the string does not satisfy the requirements + // for bidirectional strings, return an error. This is described in section 6. + // +-nsresult nsIDNService::stringPrep(const nsAString& in, nsAString& out) ++// 5) Check unassigned code points -- If allowUnassigned is false, check for ++// any unassigned Unicode points and if any are found return an error. ++// This is described in section 7. ++// ++nsresult nsIDNService::stringPrep(const nsAString& in, nsAString& out, ++ PRBool allowUnassigned) + { + if (!mNamePrepHandle || !mNormalizer) + return NS_ERROR_FAILURE; + + nsresult rv = NS_OK; + PRUint32 ucs4Buf[kMaxDNSNodeLen + 1]; + PRUint32 ucs4Len; + utf16ToUcs4(in, ucs4Buf, kMaxDNSNodeLen, &ucs4Len); + +@@ -446,50 +548,59 @@ nsresult nsIDNService::stringPrep(const + if (idn_err != idn_success || found) + return NS_ERROR_FAILURE; + + // check bidi + idn_err = idn_nameprep_isvalidbidi(mNamePrepHandle, + (const PRUint32 *) ucs4Buf, &found); + if (idn_err != idn_success || found) + return NS_ERROR_FAILURE; + ++ if (!allowUnassigned) { ++ // check unassigned code points ++ idn_err = idn_nameprep_isunassigned(mNamePrepHandle, ++ (const PRUint32 *) ucs4Buf, &found); ++ if (idn_err != idn_success || found) ++ return NS_ERROR_FAILURE; ++ } ++ + // set the result string + out.Assign(normlizedStr); + + return rv; + } + + nsresult nsIDNService::encodeToACE(const nsAString& in, nsACString& out) + { + // RACE encode is supported for existing testing environment + if (!strcmp("bq--", mACEPrefix)) + return encodeToRACE(mACEPrefix, in, out); + + // use punycoce + return punycode(mACEPrefix, in, out); + } + +-nsresult nsIDNService::stringPrepAndACE(const nsAString& in, nsACString& out) ++nsresult nsIDNService::stringPrepAndACE(const nsAString& in, nsACString& out, ++ PRBool allowUnassigned) + { + nsresult rv = NS_OK; + + out.Truncate(); + + if (in.Length() > kMaxDNSNodeLen) { + NS_ERROR("IDN node too large"); + return NS_ERROR_FAILURE; + } + + if (IsASCII(in)) + CopyUCS2toASCII(in, out); + else { + nsAutoString strPrep; +- rv = stringPrep(in, strPrep); ++ rv = stringPrep(in, strPrep, allowUnassigned); + if (NS_SUCCEEDED(rv)) { + if (IsASCII(strPrep)) + CopyUCS2toASCII(strPrep, out); + else + rv = encodeToACE(strPrep, out); + } + } + + if (out.Length() > kMaxDNSNodeLen) { +@@ -522,19 +633,20 @@ void nsIDNService::normalizeFullStops(ns + break; + default: + break; + } + start++; + index++; + } + } + +-nsresult nsIDNService::decodeACE(const nsACString& in, nsACString& out) ++nsresult nsIDNService::decodeACE(const nsACString& in, nsACString& out, ++ PRBool allowUnassigned) + { + PRBool isAce; + IsACE(in, &isAce); + if (!isAce) { + out.Assign(in); + return NS_OK; + } + + // RFC 3490 - 4.2 ToUnicode +@@ -558,17 +670,39 @@ nsresult nsIDNService::decodeACE(const n + nsAutoString utf16; + ucs4toUtf16(output, utf16); + delete [] output; + if (!isOnlySafeChars(utf16, mIDNBlacklist)) + return NS_ERROR_FAILURE; + CopyUTF16toUTF8(utf16, out); + + // Validation: encode back to ACE and compare the strings + nsCAutoString ace; +- nsresult rv = ConvertUTF8toACE(out, ace); ++ nsresult rv = UTF8toACE(out, ace, allowUnassigned); + NS_ENSURE_SUCCESS(rv, rv); + + if (!ace.Equals(in, nsCaseInsensitiveCStringComparator())) + return NS_ERROR_FAILURE; + + return NS_OK; + } ++ ++PRBool nsIDNService::isInWhitelist(const nsACString &host) ++{ ++ if (mIDNWhitelistPrefBranch) { ++ nsCAutoString tld(host); ++ // make sure the host is ACE for lookup and check that there are no ++ // unassigned codepoints ++ if (!IsASCII(tld) && NS_FAILED(UTF8toACE(tld, tld, PR_FALSE))) { ++ return PR_FALSE; ++ } ++ ++ tld.Trim("."); ++ PRInt32 pos = tld.RFind("."); ++ ++ PRBool safe; ++ if (pos != kNotFound && ++ NS_SUCCEEDED(mIDNWhitelistPrefBranch->GetBoolPref(tld.get() + pos + 1, &safe))) ++ return safe; ++ } ++ ++ return PR_FALSE; ++} +Index: netwerk/dns/src/nsIDNService.h +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/dns/src/nsIDNService.h,v +retrieving revision 1.8 +diff -u -9 -p -r1.8 nsIDNService.h +--- netwerk/dns/src/nsIDNService.h 22 Jul 2005 15:07:33 -0000 1.8 ++++ netwerk/dns/src/nsIDNService.h 3 Jun 2009 09:48:30 -0000 +@@ -1,10 +1,10 @@ +-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + /* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, +@@ -49,39 +49,50 @@ + + class nsIPrefBranch; + + //----------------------------------------------------------------------------- + // nsIDNService + //----------------------------------------------------------------------------- + + #define kACEPrefixLen 4 + +-class nsIDNService : public nsIIDNService, ++class nsIDNService : public nsIIDNService_MOZILLA_1_8_BRANCH, + public nsIObserver, + public nsSupportsWeakReference + { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIIDNSERVICE ++ NS_DECL_NSIIDNSERVICE_MOZILLA_1_8_BRANCH + NS_DECL_NSIOBSERVER + + nsIDNService(); + virtual ~nsIDNService(); + + nsresult Init(); + + private: + void normalizeFullStops(nsAString& s); +- nsresult stringPrepAndACE(const nsAString& in, nsACString& out); ++ nsresult stringPrepAndACE(const nsAString& in, nsACString& out, ++ PRBool allowUnassigned); + nsresult encodeToACE(const nsAString& in, nsACString& out); +- nsresult stringPrep(const nsAString& in, nsAString& out); +- nsresult decodeACE(const nsACString& in, nsACString& out); ++ nsresult stringPrep(const nsAString& in, nsAString& out, ++ PRBool allowUnassigned); ++ nsresult decodeACE(const nsACString& in, nsACString& out, ++ PRBool allowUnassigned); ++ nsresult UTF8toACE(const nsACString& in, nsACString& out, ++ PRBool allowUnassigned); ++ nsresult ACEtoUTF8(const nsACString& in, nsACString& out, ++ PRBool allowUnassigned); ++ PRBool isInWhitelist(const nsACString &host); + void prefsChanged(nsIPrefBranch *prefBranch, const PRUnichar *pref); + +- PRBool mMultilingualTestBed; // if true generates extra node for mulitlingual testbed ++ PRBool mMultilingualTestBed; // if true generates extra node for multilingual testbed + idn_nameprep_t mNamePrepHandle; + nsCOMPtr<nsIUnicodeNormalizer> mNormalizer; + char mACEPrefix[kACEPrefixLen+1]; + nsXPIDLString mIDNBlacklist; ++ PRBool mShowPunycode; ++ nsCOMPtr<nsIPrefBranch> mIDNWhitelistPrefBranch; + }; + + #endif // nsIDNService_h__ +Index: netwerk/test/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/test/Makefile.in,v +retrieving revision 1.85.2.7 +diff -u -9 -p -r1.85.2.7 Makefile.in +--- netwerk/test/Makefile.in 27 Jun 2006 20:27:29 -0000 1.85.2.7 ++++ netwerk/test/Makefile.in 3 Jun 2009 09:48:31 -0000 +@@ -97,20 +97,23 @@ _UNIT_FILES = unit/test_all.sh \ + unit/head.js \ + unit/head_http_server.js \ + unit/tail.js \ + unit/test_protocolproxyservice.js \ + unit/test_http_headers.js \ + unit/test_cookie_header.js \ + unit/test_parse_content_type.js \ + unit/test_event_sink.js \ + unit/test_content_sniffer.js \ ++ unit/test_idnservice.js \ + unit/test_bug331825.js \ + unit/test_bug336501.js \ ++ unit/test_bug427957.js \ ++ unit/test_bug479413.js \ + $(NULL) + libs:: $(_UNIT_FILES) + $(INSTALL) $^ $(DIST)/bin/necko_unit_tests + + check:: + $(RUN_TEST_PROGRAM) $(DIST)/bin/necko_unit_tests/test_all.sh + + _RES_FILES = urlparse.dat \ + urlparse_unx.dat \ +Index: netwerk/test/unit/test_bug427957.js +=================================================================== +RCS file: netwerk/test/unit/test_bug427957.js +diff -N netwerk/test/unit/test_bug427957.js +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ netwerk/test/unit/test_bug427957.js 3 Jun 2009 09:48:31 -0000 +@@ -0,0 +1,100 @@ ++/** ++ * Test for Bidi restrictions on IDNs from RFC 3454 ++ */ ++ ++var Cc = Components.classes; ++var Ci = Components.interfaces; ++var idnService; ++ ++function expected_pass(inputIDN) ++{ ++ var isASCII = {}; ++ var displayIDN = idnService.convertToDisplayIDN(inputIDN, isASCII); ++ do_check_eq(displayIDN, inputIDN); ++} ++ ++function expected_fail(inputIDN) ++{ ++ var isASCII = {}; ++ var displayIDN = ""; ++ ++ try { ++ displayIDN = idnService.convertToDisplayIDN(inputIDN, isASCII); ++ } ++ catch(e) {} ++ ++ do_check_neq(displayIDN, inputIDN); ++} ++ ++function run_test() { ++ // add an IDN whitelist pref ++ var pbi = Cc["@mozilla.org/preferences-service;1"] ++ .getService(Ci.nsIPrefBranch2); ++ pbi.setBoolPref("network.IDN.whitelist.com", true); ++ ++ idnService = Cc["@mozilla.org/network/idn-service;1"] ++ .getService(Ci.nsIIDNService_MOZILLA_1_8_BRANCH); ++ /* ++ * In any profile that specifies bidirectional character handling, all ++ * three of the following requirements MUST be met: ++ * ++ * 1) The characters in section 5.8 MUST be prohibited. ++ */ ++ ++ // 0340; COMBINING GRAVE TONE MARK ++ expected_fail("foo\u0340bar.com"); ++ // 0341; COMBINING ACUTE TONE MARK ++ expected_fail("foo\u0341bar.com"); ++ // 200E; LEFT-TO-RIGHT MARK ++ expected_fail("foo\200ebar.com"); ++ // 200F; RIGHT-TO-LEFT MARK ++ // Note: this is an RTL IDN so that it doesn't fail test 2) below ++ expected_fail("\u200f\u0645\u062B\u0627\u0644.\u0622\u0632\u0645\u0627\u06CC\u0634\u06CC"); ++ // 202A; LEFT-TO-RIGHT EMBEDDING ++ expected_fail("foo\u202abar.com"); ++ // 202B; RIGHT-TO-LEFT EMBEDDING ++ expected_fail("foo\u202bbar.com"); ++ // 202C; POP DIRECTIONAL FORMATTING ++ expected_fail("foo\u202cbar.com"); ++ // 202D; LEFT-TO-RIGHT OVERRIDE ++ expected_fail("foo\u202dbar.com"); ++ // 202E; RIGHT-TO-LEFT OVERRIDE ++ expected_fail("foo\u202ebar.com"); ++ // 206A; INHIBIT SYMMETRIC SWAPPING ++ expected_fail("foo\u206abar.com"); ++ // 206B; ACTIVATE SYMMETRIC SWAPPING ++ expected_fail("foo\u206bbar.com"); ++ // 206C; INHIBIT ARABIC FORM SHAPING ++ expected_fail("foo\u206cbar.com"); ++ // 206D; ACTIVATE ARABIC FORM SHAPING ++ expected_fail("foo\u206dbar.com"); ++ // 206E; NATIONAL DIGIT SHAPES ++ expected_fail("foo\u206ebar.com"); ++ // 206F; NOMINAL DIGIT SHAPES ++ expected_fail("foo\u206fbar.com"); ++ ++ /* ++ * 2) If a string contains any RandALCat character, the string MUST NOT ++ * contain any LCat character. ++ */ ++ ++ // www.מיץpetel.com is invalid ++ expected_fail("www.\u05DE\u05D9\u05E5petel.com"); ++ // But www.מיץפטל.com is fine because the ltr and rtl characters are in ++ // different labels ++ expected_pass("www.\u05DE\u05D9\u05E5\u05E4\u05D8\u05DC.com"); ++ ++ /* ++ * 3) If a string contains any RandALCat character, a RandALCat ++ * character MUST be the first character of the string, and a ++ * RandALCat character MUST be the last character of the string. ++ */ ++ ++ // www.1מיץ.com is invalid ++ expected_fail("www.1\u05DE\u05D9\u05E5.com"); ++ // www.מיץ1.com is invalid ++ expected_fail("www.\u05DE\u05D9\u05E51.com"); ++ // But www.מיץ1פטל.com is fine ++ expected_pass("www.\u05DE\u05D9\u05E51\u05E4\u05D8\u05DC.com"); ++} ++ +Index: netwerk/test/unit/test_bug479413.js +=================================================================== +RCS file: netwerk/test/unit/test_bug479413.js +diff -N netwerk/test/unit/test_bug479413.js +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ netwerk/test/unit/test_bug479413.js 3 Jun 2009 09:48:31 -0000 +@@ -0,0 +1,60 @@ ++/** ++ * Test for unassigned code points in IDNs (RFC 3454 section 7) ++ */ ++ ++const Cc = Components.classes; ++const Ci = Components.interfaces; ++var idnService; ++ ++function expected_pass(inputIDN) ++{ ++ var isASCII = {}; ++ var displayIDN = idnService.convertToDisplayIDN(inputIDN, isASCII); ++ do_check_eq(displayIDN, inputIDN); ++} ++ ++function expected_fail(inputIDN) ++{ ++ var isASCII = {}; ++ var displayIDN = ""; ++ ++ try { ++ displayIDN = idnService.convertToDisplayIDN(inputIDN, isASCII); ++ } ++ catch(e) {} ++ ++ do_check_neq(displayIDN, inputIDN); ++} ++ ++function run_test() { ++ // add an IDN whitelist pref ++ var pbi = Cc["@mozilla.org/preferences-service;1"] ++ .getService(Ci.nsIPrefBranch2); ++ var whitelistPref = "network.IDN.whitelist.com"; ++ ++ pbi.setBoolPref(whitelistPref, true); ++ ++ idnService = Cc["@mozilla.org/network/idn-service;1"] ++ .getService(Ci.nsIIDNService_MOZILLA_1_8_BRANCH); ++ ++ // assigned code point ++ expected_pass("foo\u0101bar.com"); ++ ++ // assigned code point in punycode. Should *fail* because the URL will be ++ // converted to Unicode for display ++ expected_fail("xn--foobar-5za.com"); ++ ++ // unassigned code point ++ expected_fail("foo\u3040bar.com"); ++ ++ // unassigned code point in punycode. Should *pass* because the URL will not ++ // be converted to Unicode ++ expected_pass("xn--foobar-533e.com"); ++ ++ // code point assigned since Unicode 3.0 ++ // XXX This test will unexpectedly pass when we update to IDNAbis ++ expected_fail("foo\u0370bar.com"); ++ ++ // reset the pref ++ pbi.clearUserPref(whitelistPref); ++} +Index: netwerk/test/unit/test_idnservice.js +=================================================================== +RCS file: netwerk/test/unit/test_idnservice.js +diff -N netwerk/test/unit/test_idnservice.js +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ netwerk/test/unit/test_idnservice.js 3 Jun 2009 09:48:31 -0000 +@@ -0,0 +1,48 @@ ++// Tests nsIIDNService ++ ++var reference = [ ++ // The 3rd element indicates whether the second element ++ // is ACE-encoded ++ ["asciihost", "asciihost", false], ++ ["b\u00FCcher", "xn--bcher-kva", true] ++ ]; ++ ++function run_test() { ++ var idnService = Components.classes["@mozilla.org/network/idn-service;1"] ++ .getService(Components.interfaces.nsIIDNService_MOZILLA_1_8_BRANCH); ++ ++ for (var i = 0; i < reference.length; ++i) { ++ dump("Testing " + reference[i] + "\n"); ++ // We test the following: ++ // - Converting UTF-8 to ACE and back gives us the expected answer ++ // - Converting the ASCII string UTF-8 -> ACE leaves the string unchanged ++ // - isACE returns true when we expect it to (third array elem true) ++ do_check_eq(idnService.convertUTF8toACE(reference[i][0]), reference[i][1]); ++ do_check_eq(idnService.convertUTF8toACE(reference[i][1]), reference[i][1]); ++ do_check_eq(idnService.convertACEtoUTF8(reference[i][1]), reference[i][0]); ++ do_check_eq(idnService.isACE(reference[i][1]), reference[i][2]); ++ } ++ ++ // add an IDN whitelist pref ++ var pbi = Components.classes["@mozilla.org/preferences-service;1"] ++ .getService(Components.interfaces.nsIPrefBranch2); ++ pbi.setBoolPref("network.IDN.whitelist.es", true); ++ ++ // check convertToDisplayIDN against the whitelist ++ var isASCII = {}; ++ do_check_eq(idnService.convertToDisplayIDN("b\u00FCcher.es", isASCII), "b\u00FCcher.es"); ++ do_check_eq(isASCII.value, false); ++ do_check_eq(idnService.convertToDisplayIDN("xn--bcher-kva.es", isASCII), "b\u00FCcher.es"); ++ do_check_eq(isASCII.value, false); ++ do_check_eq(idnService.convertToDisplayIDN("b\u00FCcher.uk", isASCII), "xn--bcher-kva.uk"); ++ do_check_eq(isASCII.value, true); ++ do_check_eq(idnService.convertToDisplayIDN("xn--bcher-kva.uk", isASCII), "xn--bcher-kva.uk"); ++ do_check_eq(isASCII.value, true); ++ ++ // check ACE TLD's are handled by the whitelist ++ pbi.setBoolPref("network.IDN.whitelist.xn--k-dha", true); ++ do_check_eq(idnService.convertToDisplayIDN("test.\u00FCk", isASCII), "test.\u00FCk"); ++ do_check_eq(isASCII.value, false); ++ do_check_eq(idnService.convertToDisplayIDN("test.xn--k-dha", isASCII), "test.\u00FCk"); ++ do_check_eq(isASCII.value, false); ++} diff --git a/www/firefox/files/patch-ff-479560 b/www/firefox/files/patch-ff-479560 new file mode 100644 index 000000000000..2609935bbdc9 --- /dev/null +++ b/www/firefox/files/patch-ff-479560 @@ -0,0 +1,69 @@ +diff -up mozilla/js/src/xpconnect/src/xpcprivate.h.479560 mozilla/js/src/xpconnect/src/xpcprivate.h +--- js/src/xpconnect/src/xpcprivate.h.479560 2008-03-22 09:04:17.000000000 +0100 ++++ js/src/xpconnect/src/xpcprivate.h 2009-05-13 14:56:10.000000000 +0200 +@@ -2167,7 +2167,7 @@ private: + nsXPCWrappedJSClass(XPCCallContext& ccx, REFNSIID aIID, + nsIInterfaceInfo* aInfo); + +- JSObject* NewOutObject(JSContext* cx); ++ JSObject* NewOutObject(JSContext* cx, JSObject* scope); + + JSBool IsReflectable(uint16 i) const + {return (JSBool)(mDescriptors[i/32] & (1 << (i%32)));} +diff -up mozilla/js/src/xpconnect/src/xpcwrappedjsclass.cpp.479560 mozilla/js/src/xpconnect/src/xpcwrappedjsclass.cpp +--- js/src/xpconnect/src/xpcwrappedjsclass.cpp.479560 2007-06-30 01:21:28.000000000 +0200 ++++ js/src/xpconnect/src/xpcwrappedjsclass.cpp 2009-05-13 14:51:35.000000000 +0200 +@@ -1338,7 +1338,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra + if(param.IsOut()) + { + // create an 'out' object +- JSObject* out_obj = NewOutObject(cx); ++ JSObject* out_obj = NewOutObject(cx, obj); + if(!out_obj) + { + retval = NS_ERROR_OUT_OF_MEMORY; +@@ -1706,9 +1706,9 @@ nsXPCWrappedJSClass::GetInterfaceName() + } + + JSObject* +-nsXPCWrappedJSClass::NewOutObject(JSContext* cx) ++nsXPCWrappedJSClass::NewOutObject(JSContext* cx, JSObject* scope) + { +- return JS_NewObject(cx, nsnull, nsnull, nsnull); ++ return JS_NewObject(cx, nsnull, nsnull, JS_GetGlobalForObject(cx, scope)); + } + + +diff -up mozilla/js/src/jsapi.c.old mozilla/js/src/jsapi.c +--- js/src/jsapi.c.old 2009-05-13 15:13:20.000000000 +0200 ++++ js/src/jsapi.c 2009-05-13 15:13:32.000000000 +0200 +@@ -122,6 +122,16 @@ JS_GetPositiveInfinityValue(JSContext *c + return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); + } + ++JS_PUBLIC_API(JSObject *) ++JS_GetGlobalForObject(JSContext *cx, JSObject *obj) ++{ ++ JSObject *parent; ++ ++ while ((parent = OBJ_GET_PARENT(cx, obj)) != NULL) ++ obj = parent; ++ return obj; ++} ++ + JS_PUBLIC_API(jsval) + JS_GetEmptyStringValue(JSContext *cx) + { +diff -up mozilla/js/src/jsapi.h.old mozilla/js/src/jsapi.h +--- js/src/jsapi.h.old 2009-05-13 15:13:20.000000000 +0200 ++++ js/src/jsapi.h 2009-05-13 15:13:32.000000000 +0200 +@@ -668,6 +668,9 @@ JS_DumpNamedRoots(JSRuntime *rt, + void *data); + #endif + ++extern JS_PUBLIC_API(JSObject *) ++JS_GetGlobalForObject(JSContext *cx, JSObject *obj); ++ + /* + * Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data). + * The root is pointed at by rp; if the root is unnamed, name is null; data is diff --git a/www/firefox/files/patch-ff-479880 b/www/firefox/files/patch-ff-479880 new file mode 100644 index 000000000000..761b90bbd345 --- /dev/null +++ b/www/firefox/files/patch-ff-479880 @@ -0,0 +1,145 @@ +? 1.8.patch +Index: nsHttpChannel.cpp +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp,v +retrieving revision 1.256.2.22 +diff -U 8 -p -p -r1.256.2.22 nsHttpChannel.cpp +--- netwerk/protocol/http/src/nsHttpChannel.cpp 20 Jul 2006 22:59:31 -0000 1.256.2.22 ++++ netwerk/protocol/http/src/nsHttpChannel.cpp 28 May 2009 20:20:06 -0000 +@@ -755,24 +755,92 @@ nsHttpChannel::CallOnStartRequest() + + // install stream converter if required + ApplyContentConversions(); + + return rv; + } + + nsresult ++nsHttpChannel::ProcessFailedSSLConnect(PRUint32 httpStatus) ++{ ++ // Failure to set up SSL proxy tunnel means one of the following: ++ // 1) Proxy wants authorization, or forbids. ++ // 2) DNS at proxy couldn't resolve target URL. ++ // 3) Proxy connection to target failed or timed out. ++ // 4) Eve noticed our proxy CONNECT, and is replying with malicious HTML. ++ // ++ // Our current architecture will parse response content with the ++ // permission of the target URL! Given #4, we must avoid rendering the ++ // body of the reply, and instead give the user a (hopefully helpful) ++ // boilerplate error page, based on just the HTTP status of the reply. ++ ++ NS_ABORT_IF_FALSE(mConnectionInfo->UsingSSL(), ++ "SSL connect failed but not using SSL?"); ++ nsresult rv; ++ switch (httpStatus) ++ { ++ case 403: // HTTP/1.1: "Forbidden" ++ case 407: // ProcessAuthentication() failed ++ case 501: // HTTP/1.1: "Not Implemented" ++ // user sees boilerplate Mozilla "Proxy Refused Connection" page. ++ rv = NS_ERROR_PROXY_CONNECTION_REFUSED; ++ break; ++ // Squid sends 404 if DNS fails (regular 404 from target is tunneled) ++ case 404: // HTTP/1.1: "Not Found" ++ // RFC 2616: "some deployed proxies are known to return 400 or 500 when ++ // DNS lookups time out." (Squid uses 500 if it runs out of sockets: so ++ // we have a conflict here). ++ case 400: // HTTP/1.1 "Bad Request" ++ case 500: // HTTP/1.1: "Internal Server Error" ++ /* User sees: "Address Not Found: Firefox can't find the server at ++ * www.foo.com." ++ */ ++ rv = NS_ERROR_UNKNOWN_HOST; ++ break; ++ case 502: // HTTP/1.1: "Bad Gateway" (invalid resp from target server) ++ // Squid returns 503 if target request fails for anything but DNS. ++ case 503: // HTTP/1.1: "Service Unavailable" ++ /* User sees: "Failed to Connect: ++ * Firefox can't establish a connection to the server at ++ * www.foo.com. Though the site seems valid, the browser ++ * was unable to establish a connection." ++ */ ++ rv = NS_ERROR_CONNECTION_REFUSED; ++ break; ++ // RFC 2616 uses 504 for both DNS and target timeout, so not clear what to ++ // do here: picking target timeout, as DNS covered by 400/404/500 ++ case 504: // HTTP/1.1: "Gateway Timeout" ++ // user sees: "Network Timeout: The server at www.foo.com ++ // is taking too long to respond." ++ rv = NS_ERROR_NET_TIMEOUT; ++ break; ++ // Confused proxy server or malicious response ++ default: ++ rv = NS_ERROR_PROXY_CONNECTION_REFUSED; ++ break; ++ } ++ LOG(("Cancelling failed SSL proxy connection [this=%x httpStatus=%u]\n", ++ this, httpStatus)); ++ Cancel(rv); ++ return rv; ++} ++ ++nsresult + nsHttpChannel::ProcessResponse() + { + nsresult rv; + PRUint32 httpStatus = mResponseHead->Status(); + + LOG(("nsHttpChannel::ProcessResponse [this=%x httpStatus=%u]\n", + this, httpStatus)); + ++ if (mTransaction->SSLConnectFailed() && httpStatus != 407) ++ return ProcessFailedSSLConnect(httpStatus); ++ + // notify "http-on-examine-response" observers + gHttpHandler->OnExamineResponse(this); + + // set cookies, if any exist; done after OnExamineResponse to allow those + // observers to modify the cookie response headers + SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie)); + + // handle unused username and password in url (see bug 232567) +@@ -837,16 +905,18 @@ nsHttpChannel::ProcessResponse() + rv = ProcessNormal(); + } + break; + case 401: + case 407: + rv = ProcessAuthentication(httpStatus); + if (NS_FAILED(rv)) { + LOG(("ProcessAuthentication failed [rv=%x]\n", rv)); ++ if (mTransaction->SSLConnectFailed()) ++ return ProcessFailedSSLConnect(httpStatus); + CheckForSuperfluousAuth(); + rv = ProcessNormal(); + } + break; + case 412: // Precondition failed + case 416: // Invalid range + if (mResuming) { + Cancel(NS_ERROR_ENTITY_CHANGED); +Index: nsHttpChannel.h +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/protocol/http/src/nsHttpChannel.h,v +retrieving revision 1.70.4.5 +diff -U 8 -p -p -r1.70.4.5 nsHttpChannel.h +--- netwerk/protocol/http/src/nsHttpChannel.h 27 Jun 2006 20:27:29 -0000 1.70.4.5 ++++ netwerk/protocol/http/src/nsHttpChannel.h 28 May 2009 20:20:06 -0000 +@@ -155,16 +155,17 @@ private: + nsresult SetupTransaction(); + void AddCookiesToRequest(); + void ApplyContentConversions(); + nsresult CallOnStartRequest(); + nsresult ProcessResponse(); + nsresult ProcessNormal(); + nsresult ProcessNotModified(); + nsresult ProcessRedirection(PRUint32 httpStatus); ++ nsresult ProcessFailedSSLConnect(PRUint32 httpStatus); + nsresult ProcessAuthentication(PRUint32 httpStatus); + PRBool ResponseWouldVary(); + + // redirection specific methods + void HandleAsyncRedirect(); + void HandleAsyncNotModified(); + nsresult PromptTempRedirect(); + nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, PRBool preserveMethod); diff --git a/www/firefox/files/patch-ff-489131 b/www/firefox/files/patch-ff-489131 new file mode 100644 index 000000000000..bb7f1f60698f --- /dev/null +++ b/www/firefox/files/patch-ff-489131 @@ -0,0 +1,29 @@ +diff -U12 -up mozilla/content/base/src/nsContentUtils.cpp.489131 mozilla/content/base/src/nsContentUtils.cpp +--- content/base/src/nsContentUtils.cpp.489131 2009-05-14 13:30:53.000000000 +0200 ++++ content/base/src/nsContentUtils.cpp 2009-05-14 13:30:53.000000000 +0200 +@@ -2310,24 +2310,25 @@ nsCxPusher::Push(nsISupports *aCurrentTa + if (mScx) { + NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!"); + + return PR_FALSE; + } + + nsCOMPtr<nsIScriptGlobalObject> sgo; + nsCOMPtr<nsIContent> content(do_QueryInterface(aCurrentTarget)); + nsCOMPtr<nsIDocument> document; + + if (content) { + document = content->GetOwnerDoc(); ++ NS_ENSURE_TRUE(document, PR_FALSE); + } + + if (!document) { + document = do_QueryInterface(aCurrentTarget); + } + + if (document) { + nsCOMPtr<nsIDocument_MOZILLA_1_8_BRANCH3> branch3doc = + do_QueryInterface(document); + NS_ASSERTION(branch3doc, + "Document must implement nsIDocument_MOZILLA_1_8_BRANCH3!!!"); + PRBool hasHadScriptObject = PR_TRUE; diff --git a/www/firefox/files/patch-ff-491801 b/www/firefox/files/patch-ff-491801 new file mode 100644 index 000000000000..49e84152f180 --- /dev/null +++ b/www/firefox/files/patch-ff-491801 @@ -0,0 +1,91 @@ +Index: netwerk/base/src/nsURLParsers.cpp +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/base/src/nsURLParsers.cpp,v +retrieving revision 1.32 +diff -p -u -6 -r1.32 nsURLParsers.cpp +--- netwerk/base/src/nsURLParsers.cpp 24 Nov 2008 22:46:16 -0000 1.32 ++++ netwerk/base/src/nsURLParsers.cpp 8 May 2009 01:31:15 -0000 +@@ -385,12 +385,23 @@ nsBaseURLParser::ParseFileName(const cha + } + + //---------------------------------------------------------------------------- + // nsNoAuthURLParser implementation + //---------------------------------------------------------------------------- + ++NS_IMETHODIMP ++nsNoAuthURLParser::ParseAuthority(const char *auth, PRInt32 authLen, ++ PRUint32 *usernamePos, PRInt32 *usernameLen, ++ PRUint32 *passwordPos, PRInt32 *passwordLen, ++ PRUint32 *hostnamePos, PRInt32 *hostnameLen, ++ PRInt32 *port) ++{ ++ NS_NOTREACHED("Shouldn't parse auth in a NoAuthURL!"); ++ return NS_ERROR_UNEXPECTED; ++} ++ + void + nsNoAuthURLParser::ParseAfterScheme(const char *spec, PRInt32 specLen, + PRUint32 *authPos, PRInt32 *authLen, + PRUint32 *pathPos, PRInt32 *pathLen) + { + NS_PRECONDITION(specLen >= 0, "unexpected"); +@@ -416,17 +427,17 @@ nsNoAuthURLParser::ParseAfterScheme(cons + break; + } + #endif + p = (const char *) memchr(spec + 2, '/', specLen - 2); + } + if (p) { +- SET_RESULT(auth, 2, p - (spec + 2)); ++ SET_RESULT(auth, 0, -1); + SET_RESULT(path, p - spec, specLen - (p - spec)); + } + else { +- SET_RESULT(auth, 2, specLen - 2); ++ SET_RESULT(auth, 0, -1); + SET_RESULT(path, 0, -1); + } + return; + } + default: + pos = 2; +Index: netwerk/base/src/nsURLParsers.h +=================================================================== +RCS file: /cvsroot/mozilla/netwerk/base/src/nsURLParsers.h,v +retrieving revision 1.4 +diff -p -u -6 -r1.4 nsURLParsers.h +--- netwerk/base/src/nsURLParsers.h 18 Apr 2004 21:59:09 -0000 1.4 ++++ netwerk/base/src/nsURLParsers.h 8 May 2009 01:31:15 -0000 +@@ -67,25 +67,31 @@ protected: + // file:/foo/bar.txt (treated equivalently) + // file:///foo/bar.txt + // + // eg. file:////foo/bar.txt (UNC-filepath = \\foo\bar.txt) + // + // XXX except in this case: +-// file://foo/bar.txt (foo is authority) ++// file://foo/bar.txt (the authority "foo" is ignored) + //---------------------------------------------------------------------------- + + class nsNoAuthURLParser : public nsBaseURLParser + { + public: + #if defined(XP_WIN) || defined(XP_OS2) + NS_IMETHOD ParseFilePath(const char *, PRInt32, + PRUint32 *, PRInt32 *, + PRUint32 *, PRInt32 *, + PRUint32 *, PRInt32 *); + #endif + ++ NS_IMETHOD ParseAuthority(const char *auth, PRInt32 authLen, ++ PRUint32 *usernamePos, PRInt32 *usernameLen, ++ PRUint32 *passwordPos, PRInt32 *passwordLen, ++ PRUint32 *hostnamePos, PRInt32 *hostnameLen, ++ PRInt32 *port); ++ + void ParseAfterScheme(const char *spec, PRInt32 specLen, + PRUint32 *authPos, PRInt32 *authLen, + PRUint32 *pathPos, PRInt32 *pathLen); + }; + + //---------------------------------------------------------------------------- |