Bug 1146116 - Clone File objects passed to mozSetFileArray into receiver's global. r=sicking, a=sledru
authorJed Davis <jld@mozilla.com>
Fri, 27 Mar 2015 08:41:00 -0400
changeset 258246 d3e9b16fc53f
parent 258245 a9d533ac9ff4
child 258247 ca8eaf3366e5
push id4627
push userryanvm@gmail.com
push date2015-04-03 19:22 +0000
treeherdermozilla-beta@5f5a4c5a7e02 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, sledru
bugs1146116
milestone38.0
Bug 1146116 - Clone File objects passed to mozSetFileArray into receiver's global. r=sicking, a=sledru
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
@@ -2327,19 +2327,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
@@ -182,16 +182,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]
 [test_base_attributes_reflection.html]
 [test_bug100533.html]
 [test_bug109445.html]
@@ -439,16 +440,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>