Loading browser/base/content/test/general/browser.ini +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ support-files = bug792517.html bug792517.sjs bug839103.css clipboard_pastefile.html discovery.html domplate_test.js download_page.html Loading Loading @@ -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 Loading browser/base/content/test/general/browser_clipboard_pastefile.js 0 → 100644 +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); }); browser/base/content/test/general/clipboard_pastefile.html 0 → 100644 +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> dom/events/DataTransfer.cpp +36 −24 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 && Loading @@ -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(); Loading Loading @@ -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 Loading dom/events/DataTransfer.h +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
browser/base/content/test/general/browser.ini +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ support-files = bug792517.html bug792517.sjs bug839103.css clipboard_pastefile.html discovery.html domplate_test.js download_page.html Loading Loading @@ -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 Loading
browser/base/content/test/general/browser_clipboard_pastefile.js 0 → 100644 +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); });
browser/base/content/test/general/clipboard_pastefile.html 0 → 100644 +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>
dom/events/DataTransfer.cpp +36 −24 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 && Loading @@ -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(); Loading Loading @@ -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 Loading
dom/events/DataTransfer.h +2 −1 Original line number Diff line number Diff line Loading @@ -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