Commit eb87d5e6 authored by jianli@chromium.org's avatar jianli@chromium.org
Browse files

Calling FileReader.abort during reading could cause crash

https://bugs.webkit.org/show_bug.cgi?id=48163

Reviewed by David Levin.

WebCore:

Test: fast/files/file-reader-abort.html

* fileapi/FileReader.cpp:
(WebCore::delayedAbort):
(WebCore::FileReader::abort): Schedule to do the abort later to work
around the case that abort() could be called from event handler.
(WebCore::FileReader::doAbort):
(WebCore::FileReader::didFail): Do not go with normal error handling
when we are in the process of aborting.
(WebCore::FileReader::failed):
(WebCore::FileReader::readyState):
* fileapi/FileReader.h:

LayoutTests:

* fast/files/file-reader-abort-expected.txt: Added.
* fast/files/file-reader-abort.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70484 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 13ab28d0
2010-10-25 Jian Li <jianli@chromium.org>
Reviewed by David Levin.
Calling FileReader.abort during reading could cause crash
https://bugs.webkit.org/show_bug.cgi?id=48163
* fast/files/file-reader-abort-expected.txt: Added.
* fast/files/file-reader-abort.html: Added.
2010-10-25 David Hyatt <hyatt@apple.com>
 
Reviewed by Dan Bernstein.
Test that FileReader.abort works.
Received loadstart event
Received error event: 3
Received abort event
Received loadend event
DONE
<!DOCTYPE html>
<html>
<body>
<input type="file" name="file" id="file" onchange="onInputFileChange()">
<pre id='console'></pre>
<script>
function log(message)
{
document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
}
function onInputFileChange()
{
log("Test that FileReader.abort works.");
var file = document.getElementById("file").files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onloadstart = function() {
log("Received loadstart event");
reader.abort();
};
reader.onload = function() {
log("Received load event");
};
reader.onloadend = function() {
log("Received loadend event");
log("DONE");
if (layoutTestController.notifyDone)
layoutTestController.notifyDone();
};
reader.onabort = function() {
log("Received abort event");
};
reader.onerror = function(event) {
log("Received error event: " + event.target.error.code);
};
}
function runTests()
{
eventSender.beginDragWithFiles(['resources/UTF8.txt']);
eventSender.mouseMoveTo(10, 10);
eventSender.mouseUp();
}
if (window.eventSender) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
window.onload = runTests;
}
</script>
</body>
</html>
2010-10-25 Jian Li <jianli@chromium.org>
Reviewed by David Levin.
Calling FileReader.abort during reading could cause crash
https://bugs.webkit.org/show_bug.cgi?id=48163
Test: fast/files/file-reader-abort.html
* fileapi/FileReader.cpp:
(WebCore::delayedAbort):
(WebCore::FileReader::abort): Schedule to do the abort later to work
around the case that abort() could be called from event handler.
(WebCore::FileReader::doAbort):
(WebCore::FileReader::didFail): Do not go with normal error handling
when we are in the process of aborting.
(WebCore::FileReader::failed):
(WebCore::FileReader::readyState):
* fileapi/FileReader.h:
2010-10-25 Patrick Gansterer <paroga@webkit.org>
 
Reviewed by Adam Roben.
......@@ -138,10 +138,25 @@ void FileReader::readInternal(Blob* blob, ReadType type)
m_state = Starting;
}
static void delayedAbort(ScriptExecutionContext*, FileReader* reader)
{
reader->doAbort();
}
void FileReader::abort()
{
LOG(FileAPI, "FileReader: aborting\n");
if (m_state == Aborting)
return;
m_state = Aborting;
// Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stack.
scriptExecutionContext()->postTask(createCallbackTask(&delayedAbort, this));
}
void FileReader::doAbort()
{
terminate();
m_builder.clear();
......@@ -247,6 +262,10 @@ void FileReader::didFinishLoading(unsigned long)
void FileReader::didFail(const ResourceError&)
{
// If we're aborting, do not proceed with normal error handling since it is covered in aborting code.
if (m_state == Aborting)
return;
// Treat as internal error.
failed(500);
}
......@@ -255,7 +274,7 @@ void FileReader::failed(int httpStatusCode)
{
m_state = Completed;
m_error = FileError::create(httpStatusCodeToErrorCode(httpStatusCode));
m_error = FileError::create(httpStatusCodeToErrorCode(httpStatusCode));
fireEvent(eventNames().errorEvent);
fireEvent(eventNames().loadendEvent);
......@@ -288,6 +307,7 @@ FileReader::ReadyState FileReader::readyState() const
return EMPTY;
case Opening:
case Reading:
case Aborting:
return LOADING;
case Completed:
return DONE;
......
......@@ -74,6 +74,7 @@ public:
void abort();
void start();
void doAbort();
ReadyState readyState() const;
PassRefPtr<FileError> error() { return m_error; }
......@@ -119,6 +120,7 @@ private:
Starting,
Opening,
Reading,
Aborting,
Completed
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment