summaryrefslogtreecommitdiffstats
path: root/widget/tests/test_bug1123480.xhtml
diff options
context:
space:
mode:
Diffstat (limited to 'widget/tests/test_bug1123480.xhtml')
-rw-r--r--widget/tests/test_bug1123480.xhtml155
1 files changed, 155 insertions, 0 deletions
diff --git a/widget/tests/test_bug1123480.xhtml b/widget/tests/test_bug1123480.xhtml
new file mode 100644
index 0000000000..18a40202fd
--- /dev/null
+++ b/widget/tests/test_bug1123480.xhtml
@@ -0,0 +1,155 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1123480
+-->
+<window title="Mozilla Bug 1123480"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="RunTest();">
+ <title>nsTransferable PBM Overflow Selection Test</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <script type="application/javascript">
+ <![CDATA[
+ // Create over 1 MB of sample garbage text. JavaScript strings are represented by
+ // UTF16 strings, so the size is twice as much as the actual string length.
+ // This value is chosen such that the size of the memory for the string exceeds
+ // the kLargeDatasetSize threshold in nsTransferable.h.
+ // It is also not a round number to reduce the odds of having an accidental
+ // collisions with another file (since the test below looks at the file size
+ // to identify the file).
+ var Ipsum = "0123456789".repeat(1234321);
+ var IpsumByteLength = Ipsum.length * 2;
+ var SHORT_STRING_NO_CACHE = "short string that will never be cached to the disk";
+
+ function isWindows() {
+ const {AppConstants} = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+ );
+ return AppConstants.platform === 'win';
+ }
+
+ // Get a list of open file descriptors that refer to a file with the same size as
+ // the expected data (and assume that any mutations in file descriptor counts
+ // are caused by our test).
+ function getClipboardCacheFDCount() {
+ var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ if (isWindows()) {
+ // On Windows, nsAnonymousTemporaryFile does not immediately delete the file.
+ // Instead, the Windows-specific FILE_FLAG_DELETE_ON_CLOSE flag is used,
+ // which means that the file is deleted when the last handle is closed.
+ // Apparently, this flag is unreliable (e.g. when the application crashes),
+ // so nsAnonymousTemporaryFile stores the temporary files in a subdirectory,
+ // which is cleaned up some time after start-up.
+
+ // This is just a test, and during the test we deterministically close the
+ // handles, so if FILE_FLAG_DELETE_ON_CLOSE does the thing it promises, the
+ // file is actually removed when the handle is closed.
+
+ // Path from nsAnonymousTemporaryFile.cpp, GetTempDir.
+ dir.initWithPath(PathUtils.join(PathUtils.tempDir, "mozilla-temp-files"));
+ } else {
+ dir.initWithPath("/dev/fd");
+ }
+ var count = 0;
+ for (var de = dir.directoryEntries; de.hasMoreElements(); ) {
+ var fdFile = de.nextFile;
+ var fileSize;
+ try {
+ fileSize = fdFile.fileSize;
+ } catch (e) {
+ // This can happen on macOS.
+ continue;
+ }
+ if (fileSize === IpsumByteLength) {
+ // Assume that the file was created by us if the size matches.
+ ++count;
+ }
+ }
+ return count;
+ }
+
+ async function RunTest() {
+ SimpleTest.waitForExplicitFinish();
+ const gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+
+ // Sanitize environment
+ gClipboardHelper.copyString(SHORT_STRING_NO_CACHE);
+ await new Promise(resolve => setTimeout(resolve, 0));
+
+ var initialFdCount = getClipboardCacheFDCount();
+
+ // Overflow a nsTransferable region by using the clipboard helper
+ gClipboardHelper.copyString(Ipsum);
+
+ // gClipboardHelper.copyString also puts the data on the selection
+ // clipboard if the platform supports it.
+ var expectedFdDelta = Services.clipboard.isClipboardTypeSupported(Services.clipboard.kSelectionClipboard) ? 2 : 1;
+ // Undefined private browsing mode should cache to disk
+ is(getClipboardCacheFDCount(), initialFdCount + expectedFdDelta, "should cache to disk when PBM is undefined");
+
+ // Sanitize environment again.
+ gClipboardHelper.copyString(SHORT_STRING_NO_CACHE);
+ await new Promise(resolve => setTimeout(resolve, 0));
+
+ is(getClipboardCacheFDCount(), initialFdCount, "should have cleared the clipboard data");
+
+ // Repeat procedure of plain text selection with private browsing
+ // disabled and enabled
+ const {PrivateBrowsingUtils} = ChromeUtils.importESModule(
+ "resource://gre/modules/PrivateBrowsingUtils.sys.mjs"
+ );
+ for (let private of [false, true]) {
+ var win = window.browsingContext.topChromeWindow.open("about:blank", "_blank", "chrome, width=500, height=200" + (private ? ", private" : ""));
+ ok(win, private ? "should open private window" : "should open non-private window");
+ is(PrivateBrowsingUtils.isContentWindowPrivate(win), private, "used correct window context");
+
+ // Select plaintext in private/non-private channel
+ const nsTransferable = Components.Constructor("@mozilla.org/widget/transferable;1", "nsITransferable");
+ const nsSupportsString = Components.Constructor("@mozilla.org/supports-string;1", "nsISupportsString");
+ var Loadctx = PrivateBrowsingUtils.privacyContextFromWindow(win);
+ var Transfer = nsTransferable();
+ var Suppstr = nsSupportsString();
+ Suppstr.data = Ipsum;
+ Transfer.init(Loadctx);
+ Transfer.addDataFlavor("text/plain");
+ Transfer.setTransferData("text/plain", Suppstr);
+
+ // Enabled private browsing mode should not cache any selection to disk; disabled should
+ if (private) {
+ is(getClipboardCacheFDCount(), initialFdCount, "did not violate private browsing mode");
+ } else {
+ is(getClipboardCacheFDCount(), initialFdCount + 1, "should save memory by caching non-private clipboard data to disk");
+ }
+
+ // Share the transferable with the system.
+ Services.clipboard.setData(Transfer, null, Services.clipboard.kGlobalClipboard);
+ if (private) {
+ is(getClipboardCacheFDCount(), initialFdCount, "did not violate private browsing mode");
+ } else {
+ is(getClipboardCacheFDCount(), initialFdCount + 1, "should save memory by caching non-private clipboard data to disk");
+ }
+
+ // Sanitize the environment.
+ Suppstr = nsSupportsString();
+ Suppstr.data = SHORT_STRING_NO_CACHE;
+ Transfer.setTransferData("text/plain", Suppstr);
+ await new Promise(resolve => setTimeout(resolve, 0));
+ is(getClipboardCacheFDCount(), initialFdCount, "should drop the cache file, if any.");
+
+ Services.clipboard.setData(Transfer, null, Services.clipboard.kGlobalClipboard);
+ is(getClipboardCacheFDCount(), initialFdCount, "should postsanitize the environment");
+ }
+
+ SimpleTest.finish();
+ }
+ ]]>
+ </script>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1123480"
+ target="_blank">Mozilla Bug 1123480</a>
+ </body>
+</window>