RESOLVED FIXED 217333
FileReader should transition to readyState DONE after last onprogress event
https://bugs.webkit.org/show_bug.cgi?id=217333
Summary FileReader should transition to readyState DONE after last onprogress event
Alex Christensen
Reported 2020-10-05 13:28:03 PDT
FileReader should transition to readyState DONE after last onprogress event
Attachments
Patch (5.59 KB, patch)
2020-10-05 13:28 PDT, Alex Christensen
no flags
Patch (6.28 KB, patch)
2020-10-05 14:10 PDT, Alex Christensen
no flags
Patch (10.66 KB, patch)
2020-10-05 15:20 PDT, Alex Christensen
ews-feeder: commit-queue-
Patch (15.58 KB, patch)
2020-10-05 16:50 PDT, Alex Christensen
no flags
Patch (15.81 KB, patch)
2020-10-06 08:35 PDT, Alex Christensen
no flags
Patch (15.86 KB, patch)
2020-10-06 09:00 PDT, Alex Christensen
no flags
Alex Christensen
Comment 1 2020-10-05 13:28:51 PDT
Alex Christensen
Comment 2 2020-10-05 14:10:26 PDT
Chris Dumez
Comment 3 2020-10-05 14:25:18 PDT
Comment on attachment 410555 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=410555&action=review > Source/WebCore/ChangeLog:8 > + This matches the behavior of Chrome and Firefox. This does not quite match Chrome I think. In particular, Chrome has a separate m_loadingState flag so that if abort() gets called in the progress event, it is a no-op. With your change, I do not believe it would be a no-op.
Chris Dumez
Comment 4 2020-10-05 14:30:33 PDT
(In reply to Chris Dumez from comment #3) > Comment on attachment 410555 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=410555&action=review > > > Source/WebCore/ChangeLog:8 > > + This matches the behavior of Chrome and Firefox. > > This does not quite match Chrome I think. In particular, Chrome has a > separate m_loadingState flag so that if abort() gets called in the progress > event, it is a no-op. With your change, I do not believe it would be a no-op. You can see the Chromium logic is slightly different here: https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/fileapi/file_reader.cc
Alex Christensen
Comment 5 2020-10-05 15:20:33 PDT
EWS Watchlist
Comment 6 2020-10-05 15:21:23 PDT
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see https://trac.webkit.org/wiki/WPTExportProcess
Chris Dumez
Comment 7 2020-10-05 16:20:39 PDT
EWS seems unhappy.
Alex Christensen
Comment 8 2020-10-05 16:50:01 PDT
youenn fablet
Comment 9 2020-10-06 00:46:36 PDT
Comment on attachment 410589 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=410589&action=review > Source/WebCore/ChangeLog:8 > + I also bring the abort function in alignment with https://www.w3.org/TR/FileAPI/#abort Maybe point to the latest spec: https://w3c.github.io/FileAPI/#abort > Source/WebCore/fileapi/FileReader.cpp:157 > return; It seems the spec is firing the abort event even in case m_state is not loading. Can you clarify? > Source/WebCore/fileapi/FileReader.cpp:159 > // 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. This comment should be removed, we no longer schedule a task. The spec tells us to not enqueue a task to fire an event. Do we have coverage for that? We usually try to always enqueue a task to fire events. A test like the following might be good to add: let flag = true; reader.onabort = () => assert_true(flag); reader.abort(); flag = false; > Source/WebCore/fileapi/FileReader.cpp:167 > + fireEvent(eventNames().abortEvent); Previously, enqueueTask was protecting us from being collected. We should probably now protect ourselves since JS might free the FileReader object. > Source/WebCore/fileapi/FileReader.cpp:195 > enqueueTask([this] { If didFinishLoading is called, then abort is called before this enqueued task is executed, we might have some issues. It seems we could hit ASSERT(m_state != DONE); > Source/WebCore/fileapi/FileReader.cpp:207 > enqueueTask([this, errorCode] { Ditto here for aborting just after didFail enqueued this task.
Alex Christensen
Comment 10 2020-10-06 08:16:18 PDT
Comment on attachment 410589 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=410589&action=review >> Source/WebCore/fileapi/FileReader.cpp:159 >> // 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. > > This comment should be removed, we no longer schedule a task. > The spec tells us to not enqueue a task to fire an event. Do we have coverage for that? We usually try to always enqueue a task to fire events. > A test like the following might be good to add: > > let flag = true; > reader.onabort = () => assert_true(flag); > reader.abort(); > flag = false; fileReader.html already covered this. That's how I discovered that Chrome and Firefox fire synchronously. fileReader.abort(); fileReader.onabort = this.unreached_func("abort event should fire sync")
Alex Christensen
Comment 11 2020-10-06 08:35:27 PDT
youenn fablet
Comment 12 2020-10-06 08:43:53 PDT
Comment on attachment 410640 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=410640&action=review > Source/WebCore/ChangeLog:8 > + I also bring the abort function in alignment with https://www.w3.org/FileAPI/#abort Let's replace with https://w3c.github.io/FileAPI/. > Source/WebCore/fileapi/FileReader.cpp:160 > + ASSERT(m_state != DONE); ASSERT not needed anymore > Source/WebCore/fileapi/FileReader.cpp:168 > + fireEvent(eventNames().loadendEvent); The spec says: If context object's state is not "loading", fire a progress event called loadend at the context object. I do not really see how that could happen in practice. Maybe the spec could be simplified.
Chris Dumez
Comment 13 2020-10-06 08:58:35 PDT
Comment on attachment 410640 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=410640&action=review >> Source/WebCore/fileapi/FileReader.cpp:168 >> + fireEvent(eventNames().loadendEvent); > > The spec says: > If context object's state is not "loading", fire a progress event called loadend at the context object. > I do not really see how that could happen in practice. Maybe the spec could be simplified. Cannot the JS start loading again by reading again from its abort event listener?
Alex Christensen
Comment 14 2020-10-06 09:00:37 PDT
EWS
Comment 15 2020-10-06 09:45:30 PDT
Committed r268054: <https://trac.webkit.org/changeset/268054> All reviewed patches have been landed. Closing bug and clearing flags on attachment 410644 [details].
Radar WebKit Bug Importer
Comment 16 2020-10-06 09:46:24 PDT
Note You need to log in before you can comment on or make changes to this bug.