From 8cd38aca49b6f7886a7208366eb39a23fed074d1 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Thu, 13 Oct 2011 14:45:22 -0700 Subject: [PATCH] Bug 683280 - 'Workers: creating workers from 'localhost' or an IP address fails'. r=sicking. --- content/base/src/ThirdPartyUtil.cpp | 79 +++++++++++----------- content/base/src/ThirdPartyUtil.h | 1 - dom/workers/WorkerPrivate.cpp | 12 ++-- netwerk/base/public/mozIThirdPartyUtil.idl | 20 +++++- 4 files changed, 64 insertions(+), 48 deletions(-) diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp index e950af61cb9..6a415e99c82 100644 --- a/content/base/src/ThirdPartyUtil.cpp +++ b/content/base/src/ThirdPartyUtil.cpp @@ -57,46 +57,6 @@ ThirdPartyUtil::Init() return rv; } -// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be -// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing -// dot may be present. If aHostURI is an IP address, an alias such as -// 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will -// be the exact host. The result of this function should only be used in exact -// string comparisons, since substring comparisons will not be valid for the -// special cases elided above. -nsresult -ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, - nsCString& aBaseDomain) -{ - // Get the base domain. this will fail if the host contains a leading dot, - // more than one trailing dot, or is otherwise malformed. - nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain); - if (rv == NS_ERROR_HOST_IS_IP_ADDRESS || - rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) { - // aHostURI is either an IP address, an alias such as 'localhost', an eTLD - // such as 'co.uk', or the empty string. Uses the normalized host in such - // cases. - rv = aHostURI->GetAsciiHost(aBaseDomain); - } - NS_ENSURE_SUCCESS(rv, rv); - - // aHostURI (and thus aBaseDomain) may be the string '.'. If so, fail. - if (aBaseDomain.Length() == 1 && aBaseDomain.Last() == '.') - return NS_ERROR_INVALID_ARG; - - // Reject any URIs without a host that aren't file:// URIs. This makes it the - // only way we can get a base domain consisting of the empty string, which - // means we can safely perform foreign tests on such URIs where "not foreign" - // means "the involved URIs are all file://". - if (aBaseDomain.IsEmpty()) { - bool isFileURI = false; - aHostURI->SchemeIs("file", &isFileURI); - NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG); - } - - return NS_OK; -} - // Determine if aFirstDomain is a different base domain to aSecondURI; or, if // the concept of base domain does not apply, determine if the two hosts are not // string-identical. @@ -316,3 +276,42 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel, return IsThirdPartyWindow(ourWin, channelURI, aResult); } +// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be +// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing +// dot may be present. If aHostURI is an IP address, an alias such as +// 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will +// be the exact host. The result of this function should only be used in exact +// string comparisons, since substring comparisons will not be valid for the +// special cases elided above. +NS_IMETHODIMP +ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, + nsACString& aBaseDomain) +{ + // Get the base domain. this will fail if the host contains a leading dot, + // more than one trailing dot, or is otherwise malformed. + nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain); + if (rv == NS_ERROR_HOST_IS_IP_ADDRESS || + rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) { + // aHostURI is either an IP address, an alias such as 'localhost', an eTLD + // such as 'co.uk', or the empty string. Uses the normalized host in such + // cases. + rv = aHostURI->GetAsciiHost(aBaseDomain); + } + NS_ENSURE_SUCCESS(rv, rv); + + // aHostURI (and thus aBaseDomain) may be the string '.'. If so, fail. + if (aBaseDomain.Length() == 1 && aBaseDomain.Last() == '.') + return NS_ERROR_INVALID_ARG; + + // Reject any URIs without a host that aren't file:// URIs. This makes it the + // only way we can get a base domain consisting of the empty string, which + // means we can safely perform foreign tests on such URIs where "not foreign" + // means "the involved URIs are all file://". + if (aBaseDomain.IsEmpty()) { + bool isFileURI = false; + aHostURI->SchemeIs("file", &isFileURI); + NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG); + } + + return NS_OK; +} diff --git a/content/base/src/ThirdPartyUtil.h b/content/base/src/ThirdPartyUtil.h index 85af8496e49..58ddb156fcd 100644 --- a/content/base/src/ThirdPartyUtil.h +++ b/content/base/src/ThirdPartyUtil.h @@ -56,7 +56,6 @@ public: nsresult Init(); private: - nsresult GetBaseDomain(nsIURI* aHostURI, nsCString& aBaseDomain); nsresult IsThirdPartyInternal(const nsCString& aFirstDomain, nsIURI* aSecondURI, bool* aResult); static already_AddRefed GetURIFromWindow(nsIDOMWindow* aWin); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 7546f356b2e..90cd2696902 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -39,11 +39,11 @@ #include "WorkerPrivate.h" +#include "mozIThirdPartyUtil.h" #include "nsIClassInfo.h" #include "nsIConsoleService.h" #include "nsIDOMFile.h" #include "nsIDocument.h" -#include "nsIEffectiveTLDService.h" #include "nsIJSContextStack.h" #include "nsIMemoryReporter.h" #include "nsIScriptError.h" @@ -2336,14 +2336,14 @@ WorkerPrivate::Create(JSContext* aCx, JSObject* aObj, WorkerPrivate* aParent, domain = file; } else { - nsCOMPtr tldService = - do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); - if (!tldService) { - JS_ReportError(aCx, "Could not get TLD service!"); + nsCOMPtr thirdPartyUtil = + do_GetService(THIRDPARTYUTIL_CONTRACTID); + if (!thirdPartyUtil) { + JS_ReportError(aCx, "Could not get third party helper service!"); return nsnull; } - if (NS_FAILED(tldService->GetBaseDomain(codebase, 0, domain))) { + if (NS_FAILED(thirdPartyUtil->GetBaseDomain(codebase, domain))) { JS_ReportError(aCx, "Could not get domain!"); return nsnull; } diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl index e0b40ef29c3..ad419857692 100644 --- a/netwerk/base/public/mozIThirdPartyUtil.idl +++ b/netwerk/base/public/mozIThirdPartyUtil.idl @@ -45,7 +45,7 @@ interface nsIChannel; * Utility functions for determining whether a given URI, channel, or window * hierarchy is third party with respect to a known URI. */ -[scriptable, uuid(55385caa-1b94-4376-a34c-b47c51ef0837)] +[scriptable, uuid(d994fd1d-d2fe-4372-9ae7-88b08b7d9d90)] interface mozIThirdPartyUtil : nsISupports { /** @@ -155,6 +155,24 @@ interface mozIThirdPartyUtil : nsISupports * @see isThirdPartyWindow */ boolean isThirdPartyChannel(in nsIChannel aChannel, [optional] in nsIURI aURI); + + /** + * getBaseDomain + * + * Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be + * "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing + * dot may be present. If aHostURI is an IP address, an alias such as + * 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will + * be the exact host. The result of this function should only be used in exact + * string comparisons, since substring comparisons will not be valid for the + * special cases elided above. + * + * @param aHostURI + * The URI to analyze. + * + * @return the base domain. + */ + AUTF8String getBaseDomain(in nsIURI aHostURI); }; %{ C++