Bug 1189555 - Support moz-extension URIs in addon path service (r=bholley,Mossop)
authorBill McCloskey <billm@mozilla.com>
Thu, 30 Jul 2015 16:04:25 -0700
changeset 256985 3254dd5330795ea6b610d5a41cfa48bf419d7c4d
parent 256984 8c8b24ff97b6fa8d25c24ca2b8c1e7d4f1e74946
child 256986 86bd23d0e40387fc2190d55ca01af84ae8ea6f77
push idunknown
push userunknown
push dateunknown
reviewersbholley, Mossop
bugs1189555
milestone42.0a1
Bug 1189555 - Support moz-extension URIs in addon path service (r=bholley,Mossop)
toolkit/mozapps/extensions/AddonPathService.cpp
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/mozapps/extensions/AddonPathService.cpp
+++ b/toolkit/mozapps/extensions/AddonPathService.cpp
@@ -9,22 +9,24 @@
 #include "nsIURI.h"
 #include "nsXULAppAPI.h"
 #include "jsapi.h"
 #include "nsServiceManagerUtils.h"
 #include "nsLiteralString.h"
 #include "nsThreadUtils.h"
 #include "nsIIOService.h"
 #include "nsNetUtil.h"
+#include "nsIAddonPolicyService.h"
 #include "nsIFileURL.h"
 #include "nsIResProtocolHandler.h"
 #include "nsIChromeRegistry.h"
 #include "nsIJARURI.h"
 #include "nsJSUtils.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/ToJSValue.h"
 #include "mozilla/AddonPathService.h"
 #include "mozilla/Omnijar.h"
 
 #include <algorithm>
 
 namespace mozilla {
 
 struct PathEntryComparator
@@ -60,16 +62,28 @@ AddonPathService::GetInstance()
 {
   if (!sInstance) {
     sInstance = new AddonPathService();
   }
   NS_ADDREF(sInstance);
   return sInstance;
 }
 
+static JSAddonId*
+ConvertAddonId(const nsAString& addonIdString)
+{
+  AutoSafeJSContext cx;
+  JS::RootedValue strv(cx);
+  if (!mozilla::dom::ToJSValue(cx, addonIdString, &strv)) {
+    return nullptr;
+  }
+  JS::RootedString str(cx, strv.toString());
+  return JS::NewAddonId(cx, str);
+}
+
 JSAddonId*
 AddonPathService::Find(const nsAString& path)
 {
   // Use binary search to find the nearest entry that is <= |path|.
   PathEntryComparator comparator;
   unsigned index = mPaths.IndexOfFirstElementGt(PathEntry(path, nullptr), comparator);
   if (index == 0) {
     return nullptr;
@@ -102,21 +116,17 @@ AddonPathService::FindAddonId(const nsAS
   }
 
   return sInstance->Find(path);
 }
 
 NS_IMETHODIMP
 AddonPathService::InsertPath(const nsAString& path, const nsAString& addonIdString)
 {
-  AutoSafeJSContext cx;
-  JS::RootedString str(cx, JS_NewUCStringCopyN(cx,
-                                               addonIdString.BeginReading(),
-                                               addonIdString.Length()));
-  JSAddonId* addonId = JS::NewAddonId(cx, str);
+  JSAddonId* addonId = ConvertAddonId(addonIdString);
 
   // Add the new path in sorted order.
   PathEntryComparator comparator;
   mPaths.InsertElementSorted(PathEntry(path, addonId), comparator);
   return NS_OK;
 }
 
 static nsresult
@@ -193,18 +203,32 @@ ResolveURI(nsIURI* aURI, nsAString& out)
 
 JSAddonId*
 MapURIToAddonID(nsIURI* aURI)
 {
   if (!NS_IsMainThread() || !XRE_IsParentProcess()) {
     return nullptr;
   }
 
+  bool equals;
+  nsresult rv;
+  if (NS_SUCCEEDED(aURI->SchemeIs("moz-extension", &equals)) && equals) {
+    nsCOMPtr<nsIAddonPolicyService> service = do_GetService("@mozilla.org/addons/policy-service;1");
+    if (service) {
+      nsString addonId;
+      rv = service->ExtensionURIToAddonId(aURI, addonId);
+      if (NS_FAILED(rv))
+        return nullptr;
+
+      return ConvertAddonId(addonId);
+    }
+  }
+
   nsAutoString filePath;
-  nsresult rv = ResolveURI(aURI, filePath);
+  rv = ResolveURI(aURI, filePath);
   if (NS_FAILED(rv))
     return nullptr;
 
   nsCOMPtr<nsIFile> greJar = Omnijar::GetPath(Omnijar::GRE);
   nsCOMPtr<nsIFile> appJar = Omnijar::GetPath(Omnijar::APP);
   if (greJar && appJar) {
     nsAutoString greJarString, appJarString;
     if (NS_FAILED(greJar->GetPath(greJarString)) || NS_FAILED(appJar->GetPath(appJarString)))
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -49,16 +49,20 @@ XPCOMUtils.defineLazyServiceGetter(this,
 XPCOMUtils.defineLazyServiceGetter(this,
                                    "ChromeRegistry",
                                    "@mozilla.org/chrome/chrome-registry;1",
                                    "nsIChromeRegistry");
 XPCOMUtils.defineLazyServiceGetter(this,
                                    "ResProtocolHandler",
                                    "@mozilla.org/network/protocol;1?name=resource",
                                    "nsIResProtocolHandler");
+XPCOMUtils.defineLazyServiceGetter(this,
+                                   "AddonPolicyService",
+                                   "@mozilla.org/addons/policy-service;1",
+                                   "nsIAddonPolicyService");
 
 XPCOMUtils.defineLazyGetter(this, "CertUtils", function certUtilsLazyGetter() {
   let certUtils = {};
   Components.utils.import("resource://gre/modules/CertUtils.jsm", certUtils);
   return certUtils;
 });
 
 const nsIFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile",
@@ -4023,16 +4027,20 @@ this.XPIProvider = {
    *
    * @param  aURI
    *         nsIURI to map or null
    * @return string containing the Addon ID
    * @see    AddonManager.mapURIToAddonID
    * @see    amIAddonManager.mapURIToAddonID
    */
   mapURIToAddonID: function XPI_mapURIToAddonID(aURI) {
+    if (aURI.scheme == "moz-extension") {
+      return AddonPolicyService.extensionURIToAddonId(aURI);
+    }
+
     let resolved = this._resolveURIToFile(aURI);
     if (!resolved || !(resolved instanceof Ci.nsIFileURL))
       return null;
 
     for (let [id, path] of this._addonFileMap) {
       if (resolved.file.path.startsWith(path))
         return id;
     }