Bug 1146116 - Clone File objects passed to mozSetFileArray into receiver's global. r=sicking
authorJed Davis <jld@mozilla.com>
Fri, 27 Mar 2015 08:41:00 -0400
changeset 266689 8fff872add3102e966afd90517715447fb1afd6d
parent 266688 44495ed6c6188f209b86943f544e6d3b6bd604da
child 266690 db80ac5a48aaecc13b1b1e869b8d048b51a2af85
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1146116
milestone39.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 1146116 - Clone File objects passed to mozSetFileArray into receiver's global. r=sicking
dom/html/HTMLInputElement.cpp
dom/html/test/mochitest.ini
dom/html/test/simpleFileOpener.js
dom/html/test/test_bug1146116.html
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -2334,19 +2334,24 @@ HTMLInputElement::MozGetFileNameArray(ui
   *aFileNames = ret;
 
   return NS_OK;
 }
 
 void
 HTMLInputElement::MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles)
 {
+  nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
+  MOZ_ASSERT(global);
+  if (!global) {
+    return;
+  }
   nsTArray<nsRefPtr<File>> files;
   for (uint32_t i = 0; i < aFiles.Length(); ++i) {
-    files.AppendElement(aFiles[i]);
+    files.AppendElement(new File(global, aFiles[i].get()->Impl()));
   }
   SetFiles(files, true);
 }
 
 void
 HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames)
 {
   nsTArray<nsRefPtr<File>> files;
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -184,16 +184,17 @@ support-files =
   image.png
   image-allow-credentials.png
   image-allow-credentials.png^headers^
   nnc_lockup.gif
   reflect.js
   wakelock.ogg
   wakelock.ogv
   file_ignoreuserfocus.html
+  simpleFileOpener.js
 
 [test_a_text.html]
 [test_anchor_href_cache_invalidation.html]
 [test_applet_attributes_reflection.html]
 [test_audio_wakelock.html]
 skip-if = buildapp == 'mulet' # TC: Bug 1144079 - Re-enable Mulet mochitests and reftests taskcluster-specific disables.
 [test_base_attributes_reflection.html]
 [test_bug100533.html]
@@ -444,16 +445,17 @@ skip-if = (toolkit == 'gonk' && debug) |
 [test_bug879319.html]
 [test_bug885024.html]
 [test_bug893537.html]
 [test_bug95530.html]
 [test_bug969346.html]
 [test_bug982039.html]
 [test_bug1003539.html]
 [test_bug1045270.html]
+[test_bug1146116.html]
 [test_change_crossorigin.html]
 [test_checked.html]
 [test_dir_attributes_reflection.html]
 [test_dl_attributes_reflection.html]
 [test_element_prototype.html]
 [test_embed_attributes_reflection.html]
 [test_formData.html]
 [test_formSubmission.html]
new file mode 100644
--- /dev/null
+++ b/dom/html/test/simpleFileOpener.js
@@ -0,0 +1,32 @@
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+Cu.importGlobalProperties(["File"]);
+
+let file;
+
+addMessageListener("file.open", function (stem) {
+  try {
+    if (!file) {
+      file = Cc["@mozilla.org/file/directory_service;1"]
+               .getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
+      file.append(stem);
+      file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
+    }
+    sendAsyncMessage("file.opened", {
+      fullPath: file.path,
+      leafName: file.leafName,
+      domFile: new File(file),
+    });
+  } catch(e) {
+    sendAsyncMessage("fail", e.toString());
+  }
+});
+
+addMessageListener("file.remove", function () {
+  try {
+    file.remove(/* recursive: */ false);
+    file = undefined;
+    sendAsyncMessage("file.removed", null);
+  } catch(e) {
+    sendAsyncMessage("fail", e.toString());
+  }
+});
new file mode 100644
--- /dev/null
+++ b/dom/html/test/test_bug1146116.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1146116
+-->
+<head>
+  <title>Test for Bug 1146116</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1146116">Mozilla Bug 1146116</a>
+<p id="display">
+  <input type="file" id="file">
+</p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+/** Test for bug 1146116 **/
+
+SimpleTest.waitForExplicitFinish();
+
+const helperURL = SimpleTest.getTestFileURL("simpleFileOpener.js");
+const helper = SpecialPowers.loadChromeScript(helperURL);
+helper.addMessageListener("fail", function onFail(message) {
+  is(message, null, "chrome script failed");
+  SimpleTest.finish();
+});
+helper.addMessageListener("file.opened", onFileOpened);
+helper.sendAsyncMessage("file.open", "test_bug1146116.txt");
+
+function onFileOpened(message) {
+  const file = message.domFile;
+  const elem = document.getElementById("file");
+  isnot(SpecialPowers.Cu.getGlobalForObject(elem), window,
+        "File from MessageManager is wrapped");
+  SpecialPowers.wrap(elem).mozSetFileArray([file]);
+  is(SpecialPowers.unwrap(SpecialPowers.Cu.getGlobalForObject(elem.files[0])),
+     window, "File read back from input element is not wrapped");
+  helper.addMessageListener("file.removed", onFileRemoved);
+  helper.sendAsyncMessage("file.remove", null);
+}
+
+function onFileRemoved() {
+  helper.destroy();
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>