Bug 1225384 - Change how the default resource "host names" are handled. r=michal
☠☠ backed out by 28b612e72ba1 ☠ ☠
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 17 Nov 2015 17:21:03 +0900
changeset 277252 e8c63b932647acd621cf0d2b4dfdd7eedff3d706
parent 277251 9652e130726aeb9f4c6bb90a2d97a40776ada010
child 277253 8916b45bc52703d5b29d9dc1d10fc3278477b9b8
push id29819
push usercbook@mozilla.com
push dateTue, 22 Dec 2015 10:47:17 +0000
treeherderautoland@ad16863d1d45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1225384, 1224000
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1225384 - Change how the default resource "host names" are handled. r=michal The meaning of resource:///, resource://app/ and resource://gre/ needs to remain constant. Unfortunately, the model of the resource protocol handler is that it is possible to set substitutions that change their meaning. So, we forbid setting overwriting the substitutions for those three special "host names". Unfortunately, with e10s, the full list of substitutions is also sent to the content process, which then sets substitutions, making it harder to know in which cases SetSubstitution is valid for those three "host names" or not. So instead of trying to find the right heuristics, use the recently added SubstitutingProtocolHandler::ResolveSpecialCases API to handle the three "host names" instead of storing them as "normal" substitutions. Still actively reject SetSubstitution with the three special "host names" so as to find issues such as bug 1224000 instead of allowing the chrome manifest entry and have it silently ignored.
netwerk/protocol/res/nsResProtocolHandler.cpp
netwerk/protocol/res/nsResProtocolHandler.h
--- a/netwerk/protocol/res/nsResProtocolHandler.cpp
+++ b/netwerk/protocol/res/nsResProtocolHandler.cpp
@@ -16,56 +16,37 @@
 #include "nsEscape.h"
 
 #include "mozilla/Omnijar.h"
 
 using mozilla::dom::ContentParent;
 using mozilla::LogLevel;
 using mozilla::Unused;
 
-#define kAPP           NS_LITERAL_CSTRING("app")
-#define kGRE           NS_LITERAL_CSTRING("gre")
+#define kAPP           "app"
+#define kGRE           "gre"
 
 nsresult
 nsResProtocolHandler::Init()
 {
     nsresult rv;
-    nsAutoCString appURI, greURI;
-    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, appURI);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, greURI);
+    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, mAppURI);
     NS_ENSURE_SUCCESS(rv, rv);
-
-    //
-    // make resource:/// point to the application directory or omnijar
-    //
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri), appURI.Length() ? appURI : greURI);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = SetSubstitution(EmptyCString(), uri);
+    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, mGREURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    //
-    // make resource://app/ point to the application directory or omnijar
-    //
-    rv = SetSubstitution(kAPP, uri);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    //
-    // make resource://gre/ point to the GRE directory
-    //
-    if (appURI.Length()) { // We already have greURI in uri if appURI.Length() is 0.
-        rv = NS_NewURI(getter_AddRefs(uri), greURI);
-        NS_ENSURE_SUCCESS(rv, rv);
+    // mozilla::Omnijar::GetURIString always returns a string ending with /,
+    // and we want to remove it.
+    mGREURI.Truncate(mGREURI.Length() - 1);
+    if (mAppURI.Length()) {
+      mAppURI.Truncate(mAppURI.Length() - 1);
+    } else {
+      mAppURI = mGREURI;
     }
 
-    rv = SetSubstitution(kGRE, uri);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     //XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
     // but once I finish multiple chrome registration I'm not sure that it is needed
 
     // XXX dveditz: resource://pchrome/ defeats profile directory salting
     // if web content can load it. Tread carefully.
 
     return rv;
 }
@@ -95,8 +76,33 @@ nsResProtocolHandler::GetSubstitutionInt
         return NS_ERROR_NOT_AVAILABLE;
         
     rv = IOService()->NewFileURI(file, result);
     if (NS_FAILED(rv))
         return NS_ERROR_NOT_AVAILABLE;
 
     return NS_OK;
 }
+
+bool
+nsResProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
+                                          const nsACString& aPath,
+                                          nsACString& aResult)
+{
+    if (aHost.Equals("") || aHost.Equals(kAPP)) {
+        aResult.Assign(mAppURI);
+    } else if (aHost.Equals(kGRE)) {
+        aResult.Assign(mGREURI);
+    } else {
+        return false;
+    }
+    aResult.Append(aPath);
+    return true;
+}
+
+nsresult
+nsResProtocolHandler::SetSubstitution(const nsACString& aRoot, nsIURI* aBaseURI)
+{
+    MOZ_ASSERT(!aRoot.Equals(""));
+    MOZ_ASSERT(!aRoot.Equals(kAPP));
+    MOZ_ASSERT(!aRoot.Equals(kGRE));
+    return SubstitutingProtocolHandler::SetSubstitution(aRoot, aBaseURI);
+}
--- a/netwerk/protocol/res/nsResProtocolHandler.h
+++ b/netwerk/protocol/res/nsResProtocolHandler.h
@@ -18,23 +18,46 @@ class nsResProtocolHandler final : publi
                                    public mozilla::SubstitutingProtocolHandler,
                                    public nsSupportsWeakReference
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIRESPROTOCOLHANDLER
 
     NS_FORWARD_NSIPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
-    NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
 
     nsResProtocolHandler()
       : SubstitutingProtocolHandler("resource", URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE,
                                     /* aEnforceFileOrJar = */ false)
     {}
 
     nsresult Init();
 
+    NS_IMETHOD SetSubstitution(const nsACString& aRoot, nsIURI* aBaseURI) override;
+
+    NS_IMETHOD GetSubstitution(const nsACString& aRoot, nsIURI** aResult) override
+    {
+        return mozilla::SubstitutingProtocolHandler::GetSubstitution(aRoot, aResult);
+    }
+
+    NS_IMETHOD HasSubstitution(const nsACString& aRoot, bool* aResult) override
+    {
+        return mozilla::SubstitutingProtocolHandler::HasSubstitution(aRoot, aResult);
+    }
+
+    NS_IMETHOD ResolveURI(nsIURI *aResURI, nsACString& aResult) override
+    {
+        return mozilla::SubstitutingProtocolHandler::ResolveURI(aResURI, aResult);
+    }
+
 protected:
     nsresult GetSubstitutionInternal(const nsACString& aRoot, nsIURI** aResult) override;
     virtual ~nsResProtocolHandler() {}
+
+    bool ResolveSpecialCases(const nsACString& aHost, const nsACString& aPath,
+                             nsACString& aResult) override;
+
+private:
+    nsCString mAppURI;
+    nsCString mGREURI;
 };
 
 #endif /* nsResProtocolHandler_h___ */