Bug 1312260 - Part 1: Allow access to execCommand("paste") with permission draft
authorTomislav Jovanovic <tomica@gmail.com>
Thu, 09 Feb 2017 15:09:22 +0100
changeset 481308 8add08e8d2be902be711a9085c32bee6f809fe4f
parent 480213 c80c2c7bc043d438f11a32ca08a2fc6743b9152f
child 481309 0963226cb14b7534e20c5ddc9664636bdd57690b
child 481946 ca47bdfab8890094129864608d0f87668c0377ea
child 481950 7122106481d66493eb840b8273d2c576c9a9f583
push id44761
push userbmo:tomica@gmail.com
push dateThu, 09 Feb 2017 16:01:16 +0000
bugs1312260
milestone54.0a1
Bug 1312260 - Part 1: Allow access to execCommand("paste") with permission MozReview-Commit-ID: B1sfhsQWWQa
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/html/nsHTMLDocument.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2071,25 +2071,32 @@ nsContentUtils::CanCallerAccess(nsPIDOMW
   nsCOMPtr<nsIScriptObjectPrincipal> scriptObject = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(scriptObject, false);
 
   return CanCallerAccess(SubjectPrincipal(), scriptObject->GetPrincipal());
 }
 
 // static
 bool
-nsContentUtils::CallerHasPermission(JSContext* aCx, const nsAString& aPerm)
+nsContentUtils::PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsAString& aPerm)
 {
   // Chrome gets access by default.
-  if (IsSystemCaller(aCx)) {
+  if (IsSystemPrincipal(aPrincipal)) {
     return true;
   }
 
   // Otherwise, only allow if caller is an addon with the permission.
-  return BasePrincipal::Cast(SubjectPrincipal(aCx))->AddonHasPermission(aPerm);
+  return BasePrincipal::Cast(aPrincipal)->AddonHasPermission(aPerm);
+}
+
+// static
+bool
+nsContentUtils::CallerHasPermission(JSContext* aCx, const nsAString& aPerm)
+{
+  return PrincipalHasPermission(SubjectPrincipal(aCx), aPerm);
 }
 
 //static
 bool
 nsContentUtils::InProlog(nsINode *aNode)
 {
   NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
 
@@ -6889,22 +6896,21 @@ nsContentUtils::IsRequestFullScreenAllow
          EventStateManager::IsHandlingUserInput() ||
          aCallerType == CallerType::System;
 }
 
 /* static */
 bool
 nsContentUtils::IsCutCopyAllowed(nsIPrincipal* aSubjectPrincipal)
 {
-  if ((!IsCutCopyRestricted() && EventStateManager::IsHandlingUserInput()) ||
-      IsSystemPrincipal(aSubjectPrincipal)) {
+  if (!IsCutCopyRestricted() && EventStateManager::IsHandlingUserInput()) {
     return true;
   }
 
-  return BasePrincipal::Cast(aSubjectPrincipal)->AddonHasPermission(NS_LITERAL_STRING("clipboardWrite"));
+  return PrincipalHasPermission(aSubjectPrincipal, NS_LITERAL_STRING("clipboardWrite"));
 }
 
 /* static */
 bool
 nsContentUtils::IsFrameTimingEnabled()
 {
   return sIsFrameTimingPrefEnabled;
 }
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -498,16 +498,19 @@ public:
   // Check if the (JS) caller can access aNode.
   static bool CanCallerAccess(nsIDOMNode *aNode);
   static bool CanCallerAccess(nsINode* aNode);
 
   // Check if the (JS) caller can access aWindow.
   // aWindow can be either outer or inner window.
   static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);
 
+  // Check if the principal is chrome or an addon with the permission.
+  static bool PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsAString& aPerm);
+
   // Check if the JS caller is chrome or an addon with the permission.
   static bool CallerHasPermission(JSContext* aCx, const nsAString& aPerm);
 
   /**
    * GetDocumentFromCaller gets its document by looking at the last called
    * function and finding the document that the function itself relates to.
    * For example, consider two windows A and B in the same origin. B has a
    * function which does something that ends up needing the current document.
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -3194,17 +3194,18 @@ nsHTMLDocument::ExecCommand(const nsAStr
   }
 
   if (commandID.LowerCaseEqualsLiteral("gethtml")) {
     rv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   bool restricted = commandID.LowerCaseEqualsLiteral("paste");
-  if (restricted && !nsContentUtils::IsSystemPrincipal(&aSubjectPrincipal)) {
+  if (restricted && !nsContentUtils::PrincipalHasPermission(&aSubjectPrincipal,
+                                                            NS_LITERAL_STRING("clipboardRead"))) {
     return false;
   }
 
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr) {
     rv.Throw(NS_ERROR_FAILURE);