[tbb-commits] [tor-browser/tor-browser-45.4.0esr-6.5-1] Bug 1249522, when a file is present, only specify file type, r=smaug

gk at torproject.org gk at torproject.org
Fri Oct 28 07:03:33 UTC 2016


commit 3bfc8bc8ea3a87010c2203f752af19b29bf4c0b2
Author: Neil Deakin <neil at mozilla.com>
Date:   Wed May 11 10:04:19 2016 -0400

    Bug 1249522, when a file is present, only specify file type, r=smaug
---
 browser/base/content/test/general/browser.ini      |  2 +
 .../test/general/browser_clipboard_pastefile.js    | 59 +++++++++++++++++++++
 .../content/test/general/clipboard_pastefile.html  | 37 +++++++++++++
 dom/events/DataTransfer.cpp                        | 60 +++++++++++++---------
 dom/events/DataTransfer.h                          |  3 +-
 .../mochitest/chrome/test_sanityChromeUtils.xul    |  4 +-
 6 files changed, 139 insertions(+), 26 deletions(-)

diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini
index 44e5d15..3224ce5 100644
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -25,6 +25,7 @@ support-files =
   bug792517.html
   bug792517.sjs
   bug839103.css
+  clipboard_pastefile.html
   discovery.html
   domplate_test.js
   download_page.html
@@ -283,6 +284,7 @@ skip-if = os == 'win' || e10s # Bug 1159268 - Need a content-process safe versio
 [browser_canonizeURL.js]
 skip-if = e10s # Bug 1094510 - test hits the network in e10s mode only
 [browser_clipboard.js]
+[browser_clipboard_pastefile.js]
 [browser_contentAreaClick.js]
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the network in e10s, causing next test to crash
diff --git a/browser/base/content/test/general/browser_clipboard_pastefile.js b/browser/base/content/test/general/browser_clipboard_pastefile.js
new file mode 100644
index 0000000..094628f
--- /dev/null
+++ b/browser/base/content/test/general/browser_clipboard_pastefile.js
@@ -0,0 +1,59 @@
+// This test is used to check that pasting files removes all non-file data from
+// event.clipboardData.
+
+add_task(function*() {
+  var searchbar = document.getElementById("searchbar");
+
+  searchbar.focus();
+  searchbar.value = "Text";
+  searchbar.select();
+
+  yield new Promise((resolve, reject) => {
+    searchbar.addEventListener("copy", function copyEvent(event) {
+      searchbar.removeEventListener("copy", copyEvent, true);
+      event.clipboardData.setData("text/plain", "Alternate");
+      // For this test, it doesn't matter that the file isn't actually a file.
+      event.clipboardData.setData("application/x-moz-file", "Sample");
+      event.preventDefault();
+      resolve();
+    }, true)
+
+    EventUtils.synthesizeKey("c", { accelKey: true });
+  });
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
+              "https://example.com/browser/browser/base/content/test/general/clipboard_pastefile.html");
+  let browser = tab.linkedBrowser;
+
+  yield ContentTask.spawn(browser, { }, function* (arg) {
+    content.document.getElementById("input").focus();
+  });
+
+  yield BrowserTestUtils.synthesizeKey("v", { accelKey: true }, browser);
+
+  let output = yield ContentTask.spawn(browser, { }, function* (arg) {
+    return content.document.getElementById("output").textContent;
+  });
+  is (output, "Passed", "Paste file");
+
+  searchbar.focus();
+
+  yield new Promise((resolve, reject) => {
+    searchbar.addEventListener("paste", function copyEvent(event) {
+      searchbar.removeEventListener("paste", copyEvent, true);
+
+      let dt = event.clipboardData;
+      is(dt.types.length, 3, "number of types");
+      ok(dt.types.contains("text/plain"), "text/plain exists in types");
+      ok(dt.mozTypesAt(0).contains("text/plain"), "text/plain exists in mozTypesAt");
+      is(dt.getData("text/plain"), "Alternate", "text/plain returned in getData");
+      is(dt.mozGetDataAt("text/plain", 0), "Alternate", "text/plain returned in mozGetDataAt");
+
+      resolve();
+    }, true);
+
+    EventUtils.synthesizeKey("v", { accelKey: true });
+  });
+
+  yield BrowserTestUtils.removeTab(tab);
+});
diff --git a/browser/base/content/test/general/clipboard_pastefile.html b/browser/base/content/test/general/clipboard_pastefile.html
new file mode 100644
index 0000000..fcbf60e
--- /dev/null
+++ b/browser/base/content/test/general/clipboard_pastefile.html
@@ -0,0 +1,37 @@
+<html><body>
+<script>
+function checkPaste(event)
+{
+  let output = document.getElementById("output");
+  output.textContent = checkPasteHelper(event);
+}
+
+function checkPasteHelper(event)
+{
+  let dt = event.clipboardData;
+  if (dt.types.length != 2)
+    return "Wrong number of types; got " + dt.types.length;
+
+  for (let type of dt.types) {
+    if (type != "Files" && type != "application/x-moz-file")
+      return "Invalid type for types; got" + type;
+  }
+
+  for (let type of dt.mozTypesAt(0)) {
+    if (type != "Files" && type != "application/x-moz-file")
+      return "Invalid type for mozTypesAt; got" + type;
+  }
+
+  if (dt.getData("text/plain"))
+    return "text/plain found with getData";
+  if (dt.mozGetDataAt("text/plain", 0))
+    return "text/plain found with mozGetDataAt";
+
+  return "Passed";
+}
+</script>
+
+<input id="input" onpaste="checkPaste(event)">
+<div id="output"></div>
+
+</body></html>
diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp
index 2ad0eff..a6c9342 100644
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -359,25 +359,8 @@ DataTransfer::GetFiles(nsIDOMFileList** aFileList)
 already_AddRefed<DOMStringList>
 DataTransfer::Types()
 {
-  RefPtr<DOMStringList> types = new DOMStringList();
-  if (mItems.Length()) {
-    bool addFile = false;
-    const nsTArray<TransferItem>& item = mItems[0];
-    for (uint32_t i = 0; i < item.Length(); i++) {
-      const nsString& format = item[i].mFormat;
-      types->Add(format);
-      if (!addFile) {
-        addFile = format.EqualsASCII(kFileMime) ||
-                  format.EqualsASCII("application/x-moz-file-promise");
-      }
-    }
-
-    if (addFile) {
-      types->Add(NS_LITERAL_STRING("Files"));
-    }
-  }
-
-  return types.forget();
+  ErrorResult rv;
+  return MozTypesAt(0, rv);
 }
 
 NS_IMETHODIMP
@@ -545,7 +528,7 @@ DataTransfer::GetMozSourceNode(nsIDOMNode** aSourceNode)
 }
 
 already_AddRefed<DOMStringList>
-DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
+DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv) const
 {
   // Only the first item is valid for clipboard events
   if (aIndex > 0 &&
@@ -557,10 +540,28 @@ DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
 
   RefPtr<DOMStringList> types = new DOMStringList();
   if (aIndex < mItems.Length()) {
+    bool addFile = false;
     // note that you can retrieve the types regardless of their principal
-    nsTArray<TransferItem>& item = mItems[aIndex];
-    for (uint32_t i = 0; i < item.Length(); i++)
-      types->Add(item[i].mFormat);
+    const nsTArray<TransferItem>& item = mItems[aIndex];
+    for (uint32_t i = 0; i < item.Length(); i++) {
+      const nsString& format = item[i].mFormat;
+      types->Add(format);
+      if (!addFile) {
+        addFile = format.EqualsASCII(kFileMime);
+      }
+    }
+
+    if (addFile) {
+      // If this is a content caller, and a file is in the data transfer, remove
+      // the non-file types. This prevents alternate text forms of the file
+      // from being returned.
+      if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
+        types->Clear();
+        types->Add(NS_LITERAL_STRING(kFileMime));
+      }
+
+      types->Add(NS_LITERAL_STRING("Files"));
+    }
   }
 
   return types.forget();
@@ -602,12 +603,23 @@ DataTransfer::GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
-
   nsAutoString format;
   GetRealFormat(aFormat, format);
 
   nsTArray<TransferItem>& item = mItems[aIndex];
 
+  // If this is a content caller, and a file is in the data transfer, only
+  // return the file type.
+  if (!format.EqualsLiteral(kFileMime) &&
+      !nsContentUtils::IsSystemPrincipal(aSubjectPrincipal)) {
+    uint32_t count = item.Length();
+    for (uint32_t i = 0; i < count; i++) {
+      if (item[i].mFormat.EqualsLiteral(kFileMime)) {
+        return NS_OK;
+      }
+    }
+  }
+
   // Check if the caller is allowed to access the drag data. Callers with
   // chrome privileges can always read the data. During the
   // drop event, allow retrieving the data except in the case where the
diff --git a/dom/events/DataTransfer.h b/dom/events/DataTransfer.h
index 2b1f90a..48fbac9 100644
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -165,7 +165,8 @@ public:
     }
   }
   already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex,
-                                             mozilla::ErrorResult& aRv);
+                                             mozilla::ErrorResult& aRv) const;
+
   void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
                       mozilla::ErrorResult& aRv);
   void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
diff --git a/testing/mochitest/chrome/test_sanityChromeUtils.xul b/testing/mochitest/chrome/test_sanityChromeUtils.xul
index ca1915b..f3ac45d 100644
--- a/testing/mochitest/chrome/test_sanityChromeUtils.xul
+++ b/testing/mochitest/chrome/test_sanityChromeUtils.xul
@@ -65,7 +65,9 @@
     var dragfile = [[
       { type    : "application/x-moz-file",
         data    : testFile,
-        eqTest  : function(actualData, expectedData) {return expectedData.equals(actualData);} }
+        eqTest  : function(actualData, expectedData) {return expectedData.equals(actualData);} },
+      { type    : "Files",
+        data    : null }
     ]];
     
     function doOnDrop(aEvent) {





More information about the tbb-commits mailing list