зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1198095 - FileReader should dispatch an error if the blob changes size in the meantime the read is executed, r=bz
This commit is contained in:
Родитель
17ff0fc26a
Коммит
0b049e8333
|
@ -275,7 +275,6 @@ nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
|
|||
nsAString& aSuccessEvent,
|
||||
nsAString& aTerminationEvent)
|
||||
{
|
||||
|
||||
// Make sure we drop all the objects that could hold files open now.
|
||||
nsCOMPtr<nsIAsyncInputStream> stream;
|
||||
mAsyncStream.swap(stream);
|
||||
|
@ -283,25 +282,34 @@ nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
|
|||
RefPtr<Blob> blob;
|
||||
mBlob.swap(blob);
|
||||
|
||||
aSuccessEvent = NS_LITERAL_STRING(LOAD_STR);
|
||||
aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR);
|
||||
|
||||
// Clear out the data if necessary
|
||||
if (NS_FAILED(aStatus)) {
|
||||
FreeFileData();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// In case we read a different number of bytes, we can assume that the
|
||||
// underlying storage has changed. We should not continue.
|
||||
if (mDataLen != mTotal) {
|
||||
DispatchError(NS_ERROR_FAILURE, aTerminationEvent);
|
||||
FreeFileData();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aSuccessEvent = NS_LITERAL_STRING(LOAD_STR);
|
||||
aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
switch (mDataFormat) {
|
||||
case FILE_AS_ARRAYBUFFER: {
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(mozilla::DOMEventTargetHelper::GetParentObject()))) {
|
||||
FreeFileData();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RootResultArrayBuffer();
|
||||
mResultArrayBuffer = JS_NewArrayBufferWithContents(jsapi.cx(), mTotal, mFileData);
|
||||
mResultArrayBuffer = JS_NewArrayBufferWithContents(jsapi.cx(), mDataLen, mFileData);
|
||||
if (!mResultArrayBuffer) {
|
||||
JS_ClearPendingException(jsapi.cx());
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -343,8 +351,7 @@ nsDOMFileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount)
|
|||
if (mDataFormat == FILE_AS_BINARY) {
|
||||
//Continuously update our binary string as data comes in
|
||||
uint32_t oldLen = mResult.Length();
|
||||
NS_ASSERTION(mResult.Length() == mDataLen,
|
||||
"unexpected mResult length");
|
||||
NS_ASSERTION(mResult.Length() == mDataLen, "unexpected mResult length");
|
||||
if (uint64_t(oldLen) + aCount > UINT32_MAX)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
char16_t *buf = nullptr;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.importGlobalProperties(["File"]);
|
||||
|
||||
function createFileWithData(message) {
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
testFile.append("fileAPItestfileBug1198095");
|
||||
|
||||
var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
|
||||
outStream.write(message, message.length);
|
||||
outStream.close();
|
||||
|
||||
var domFile = new File(testFile);
|
||||
return domFile;
|
||||
}
|
||||
|
||||
addMessageListener("file.open", function (message) {
|
||||
sendAsyncMessage("file.opened", createFileWithData(message));
|
||||
});
|
||||
|
||||
addMessageListener("file.modify", function (message) {
|
||||
sendAsyncMessage("file.modified", createFileWithData(message));
|
||||
});
|
|
@ -257,6 +257,7 @@ support-files =
|
|||
referrer_change_server.sjs
|
||||
file_change_policy_redirect.html
|
||||
empty_worker.js
|
||||
file_bug1198095.js
|
||||
|
||||
[test_anonymousContent_api.html]
|
||||
[test_anonymousContent_append_after_reflow.html]
|
||||
|
@ -860,3 +861,4 @@ skip-if = e10s || os != 'linux' || buildapp != 'browser'
|
|||
skip-if = buildapp == 'b2g' #no ssl support
|
||||
[test_document.all_iteration.html]
|
||||
[test_performance_translate.html]
|
||||
[test_bug1198095.html]
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1198095
|
||||
-->
|
||||
<title>Test for Bug 1198095</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=1198095">Mozilla Bug 1198095</a>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var fileData1 = '1234567890';
|
||||
var fileData2 = '43210';
|
||||
var r, firstBlob;
|
||||
|
||||
var openerURL = SimpleTest.getTestFileURL("file_bug1198095.js");
|
||||
|
||||
var opener = SpecialPowers.loadChromeScript(openerURL);
|
||||
opener.addMessageListener("file.opened", onFileOpened);
|
||||
opener.addMessageListener("file.modified", onFileModified);
|
||||
opener.sendAsyncMessage("file.open", fileData1);
|
||||
|
||||
function onLoadEnd1(e) {
|
||||
e.target.removeEventListener('loadend', onLoadEnd1);
|
||||
|
||||
is(e.target, r, "Target and r are ok");
|
||||
ok(e.target.readyState, FileReader.DONE, "The file has been read.");
|
||||
ok(e.target.result instanceof ArrayBuffer, "The result is an ArrayBuffer");
|
||||
|
||||
var view = new Uint8Array(e.target.result);
|
||||
is(view.length, fileData1.length, "File data length matches");
|
||||
for (var i = 0; i < fileData1.length; ++i) {
|
||||
is(String.fromCharCode(view[i]), fileData1[i], "Byte matches");
|
||||
}
|
||||
|
||||
opener.sendAsyncMessage("file.modify", fileData2);
|
||||
}
|
||||
|
||||
function onLoadEnd2(e) {
|
||||
e.target.removeEventListener('loadend', onLoadEnd2);
|
||||
ok(false, "This method should not be called - loadEnd2!");
|
||||
}
|
||||
|
||||
function onError1(e) {
|
||||
ok(false, "This method should not be called - error1!");
|
||||
}
|
||||
|
||||
function onError2(e) {
|
||||
e.target.removeEventListener('error', onError2);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function onFileOpened(blob) {
|
||||
firstBlob = blob;
|
||||
r = new FileReader();
|
||||
r.addEventListener("loadend", onLoadEnd1, false);
|
||||
r.addEventListener("error", onError1, false);
|
||||
r.readAsArrayBuffer(firstBlob);
|
||||
}
|
||||
|
||||
function onFileModified(blob) {
|
||||
r.addEventListener("loadend", onLoadEnd2, false);
|
||||
r.removeEventListener('error', onError1);
|
||||
r.addEventListener("error", onError2, false);
|
||||
r.readAsArrayBuffer(firstBlob);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body> </html>
|
Загрузка…
Ссылка в новой задаче