mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 923310 - Crash in HTMLInputElement in B2G, r=jwatt
This commit is contained in:
parent
2e504006a1
commit
89d6130ac5
@ -163,7 +163,10 @@ nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
|
||||
{
|
||||
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||
if (!mIsFile) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aFileName.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -529,6 +529,12 @@ private:
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
|
||||
};
|
||||
|
||||
/**
|
||||
* This may return nullptr if aDomFile's implementation of
|
||||
* nsIDOMFile::mozFullPathInternal does not successfully return a non-empty
|
||||
* string that is a valid path. This can happen on Firefox OS, for example,
|
||||
* where the file picker can create Blobs.
|
||||
*/
|
||||
static already_AddRefed<nsIFile>
|
||||
DOMFileToLocalFile(nsIDOMFile* aDomFile)
|
||||
{
|
||||
@ -630,10 +636,12 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
|
||||
|
||||
// Store the last used directory using the content pref service:
|
||||
nsCOMPtr<nsIFile> file = DOMFileToLocalFile(newFiles[0]);
|
||||
nsCOMPtr<nsIFile> lastUsedDir;
|
||||
file->GetParent(getter_AddRefs(lastUsedDir));
|
||||
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
|
||||
mInput->OwnerDoc(), lastUsedDir);
|
||||
if (file) {
|
||||
nsCOMPtr<nsIFile> lastUsedDir;
|
||||
file->GetParent(getter_AddRefs(lastUsedDir));
|
||||
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
|
||||
mInput->OwnerDoc(), lastUsedDir);
|
||||
}
|
||||
|
||||
// The text control frame (if there is one) isn't going to send a change
|
||||
// event because it will think this is done by a script.
|
||||
|
@ -386,3 +386,4 @@ support-files =
|
||||
[test_ul_attributes_reflection.html]
|
||||
[test_undoManager.html]
|
||||
[test_video_wakelock.html]
|
||||
[test_input_files_not_nsIFile.html]
|
||||
|
48
content/html/content/test/test_input_files_not_nsIFile.html
Normal file
48
content/html/content/test/test_input_files_not_nsIFile.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for <input type='file'> handling when its "files" do not implement nsIFile</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="content">
|
||||
<input id='a' type='file'>
|
||||
</div>
|
||||
<button id='b' onclick="document.getElementById('a').click();">Show Filepicker</button>
|
||||
|
||||
<input type="file" id="file" />
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var MockFilePicker = SpecialPowers.MockFilePicker;
|
||||
MockFilePicker.init(window);
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
MockFilePicker.useBlobFile();
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
|
||||
var b = document.getElementById('b');
|
||||
b.focus(); // Be sure the element is visible.
|
||||
|
||||
document.getElementById('a').addEventListener("change", function(aEvent) {
|
||||
ok(true, "change event correctly sent");
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
MockFilePicker.cleanup();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}, false);
|
||||
|
||||
b.click();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -48,7 +48,11 @@ this.MockFilePicker = {
|
||||
filterAudio: Ci.nsIFilePicker.filterAudio,
|
||||
filterVideo: Ci.nsIFilePicker.filterVideo,
|
||||
|
||||
window: null,
|
||||
|
||||
init: function(window) {
|
||||
this.window = window;
|
||||
|
||||
this.reset();
|
||||
this.factory = newFactory(window);
|
||||
if (!registrar.isCIDRegistered(newClassID)) {
|
||||
@ -86,6 +90,22 @@ this.MockFilePicker = {
|
||||
var file = FileUtils.getFile("TmpD", ["testfile"]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
|
||||
this.returnFiles = [file];
|
||||
},
|
||||
|
||||
useBlobFile: function() {
|
||||
var blob = new this.window.Blob([]);
|
||||
var file = new this.window.File(blob, { name: 'helloworld.txt', type: 'plain/text' });
|
||||
this.returnFiles = [file];
|
||||
},
|
||||
|
||||
isNsIFile: function(aFile) {
|
||||
let ret = false;
|
||||
try {
|
||||
if (aFile.QueryInterface(Ci.nsIFile))
|
||||
ret = true;
|
||||
} catch(e) {}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
@ -113,12 +133,21 @@ MockFilePickerInstance.prototype = {
|
||||
filterIndex: 0,
|
||||
displayDirectory: null,
|
||||
get file() {
|
||||
if (MockFilePicker.returnFiles.length >= 1)
|
||||
if (MockFilePicker.returnFiles.length >= 1 &&
|
||||
// window.File does not implement nsIFile
|
||||
MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
|
||||
return MockFilePicker.returnFiles[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
get domfile() {
|
||||
if (MockFilePicker.returnFiles.length >= 1) {
|
||||
// window.File does not implement nsIFile
|
||||
if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
|
||||
return MockFilePicker.returnFiles[0];
|
||||
}
|
||||
|
||||
let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
|
||||
@ -126,8 +155,12 @@ MockFilePickerInstance.prototype = {
|
||||
return null;
|
||||
},
|
||||
get fileURL() {
|
||||
if (MockFilePicker.returnFiles.length >= 1)
|
||||
if (MockFilePicker.returnFiles.length >= 1 &&
|
||||
// window.File does not implement nsIFile
|
||||
MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
|
||||
return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
get files() {
|
||||
@ -138,13 +171,17 @@ MockFilePickerInstance.prototype = {
|
||||
return this.index < MockFilePicker.returnFiles.length;
|
||||
},
|
||||
getNext: function() {
|
||||
// window.File does not implement nsIFile
|
||||
if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
|
||||
return null;
|
||||
}
|
||||
return MockFilePicker.returnFiles[this.index++];
|
||||
}
|
||||
};
|
||||
},
|
||||
get domfiles() {
|
||||
let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
return {
|
||||
index: 0,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
|
||||
@ -152,6 +189,10 @@ MockFilePickerInstance.prototype = {
|
||||
return this.index < MockFilePicker.returnFiles.length;
|
||||
},
|
||||
getNext: function() {
|
||||
// window.File does not implement nsIFile
|
||||
if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
|
||||
return MockFilePicker.returnFiles[this.index++];
|
||||
}
|
||||
return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user