Commit 2a06f9c2 authored by Neil Deakin's avatar Neil Deakin Committed by Georg Koppen
Browse files

Bug 1249522, when a file is present, only specify file type, r=smaug

parent 9526ffb8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+59 −0
Original line number Diff line number Diff line
// 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);
});
+37 −0
Original line number Diff line number Diff line
<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>
+36 −24
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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,
Loading