Bug 1340578 - Allow execCommand('paste') to be called from webextensions without a target, r=ehsan
authorMichael Layzell <michael@thelayzells.com>
Thu, 07 Sep 2017 13:41:13 -0400
changeset 429597 e40d55e7a132cd5e3133b6e372acfd0dce5317eb
parent 429595 1852c4dfd856e5adcf98d00da8204c7f2ee250ac
child 429598 5dd42a4922955671ed11fd317775c8a37845f5fe
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1340578
milestone57.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 1340578 - Allow execCommand('paste') to be called from webextensions without a target, r=ehsan
dom/html/nsHTMLDocument.cpp
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_execCommandPaste_noTarget.html
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -3237,19 +3237,20 @@ nsHTMLDocument::ExecCommand(const nsAStr
   if (!ConvertToMidasInternalCommand(commandID, value,
                                      cmdToDispatch, paramStr,
                                      isBool, boolVal)) {
     return false;
   }
 
   bool isCutCopy = (commandID.LowerCaseEqualsLiteral("cut") ||
                     commandID.LowerCaseEqualsLiteral("copy"));
+  bool isPaste = commandID.LowerCaseEqualsLiteral("paste");
 
   // if editing is not on, bail
-  if (!isCutCopy && !IsEditingOnAfterFlush()) {
+  if (!isCutCopy && !isPaste && !IsEditingOnAfterFlush()) {
     return false;
   }
 
   // if they are requesting UI from us, let's fail since we have no UI
   if (doShowUI) {
     return false;
   }
 
@@ -3280,19 +3281,18 @@ nsHTMLDocument::ExecCommand(const nsAStr
     return false;
   }
 
   if (commandID.LowerCaseEqualsLiteral("gethtml")) {
     rv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
-  bool restricted = commandID.LowerCaseEqualsLiteral("paste");
-  if (restricted && !nsContentUtils::PrincipalHasPermission(&aSubjectPrincipal,
-                                                            nsGkAtoms::clipboardRead)) {
+  if (isPaste && !nsContentUtils::PrincipalHasPermission(&aSubjectPrincipal,
+                                                         nsGkAtoms::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);
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -272,8 +272,9 @@ skip-if = os == 'android'
 [test_spellcheck_pref.html]
 skip-if = toolkit == 'android'
 [test_backspace_vs.html]
 [test_css_chrome_load_access.html]
 skip-if = toolkit == 'android' # chrome urls not available due to packaging
 [test_selection_move_commands.html]
 [test_pasteImgTextarea.html]
 skip-if = toolkit == 'android' # bug 1299578
+[test_execCommandPaste_noTarget.html]
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_execCommandPaste_noTarget.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+
+  add_task(async function() {
+    let seenPaste = false;
+    let seenCopy = false;
+    document.addEventListener("copy", function oncpy(e) {
+      document.removeEventListener("copy", oncpy);
+      e.clipboardData.setData("text/plain", "my text");
+      e.preventDefault();
+      seenCopy = true;
+    });
+    document.addEventListener("paste", function onpst(e) {
+      document.removeEventListener("paste", onpst);
+      is(e.clipboardData.getData("text/plain"), "my text",
+         "The correct text was read from the clipboard");
+      e.preventDefault();
+      seenPaste = true;
+    });
+
+    ok(SpecialPowers.wrap(document).execCommand("copy"),
+       "Call should succeed");
+    ok(seenCopy, "Successfully copied the text to the clipboard");
+    ok(SpecialPowers.wrap(document).execCommand("paste"),
+       "Call should succeed");
+    ok(seenPaste, "Successfully read text from the clipboard");
+
+    // Check that reading text from the clipboard in non-privileged contexts
+    // still doesn't work.
+    function onpstfail(e) {
+      ok(false, "Should not see paste event triggered by non-privileged call");
+    }
+    document.addEventListener("paste", onpstfail);
+    ok(!document.execCommand("paste"), "Call should fail");
+    document.removeEventListener("paste", onpstfail);
+  });
+
+</script>
+</body>
+</html>