Open Bug 1752057 Opened 2 years ago Updated 2 years ago

File.text() provides updated file content on Gecko while Blink throws after file change

Categories

(Core :: DOM: File, defect)

Firefox 87
defect

Tracking

()

People

(Reporter: dev.lukaszpolowczyk, Assigned: saschanaz)

References

Details

Attachments

(1 file)

Attached file inputElTest.html

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0

Steps to reproduce:

  1. open the inputElTest.html from the attachment.
  2. Select the text file from disk, using the button.
  3. go to the NATIVE text editor on your computer, edit and save the file.
  4. after a while (setInterval 500 ms) the page itself will load the change in the file on disk.

Actual results:

I have a "watch changes" function for the selected file.
In Chrome the page only loads the file once.
In Chrome this is not the case, an error message appears in Chrome:
"Uncaught (in promise) DOMException: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired."

Expected results:

There are two solutions to choose from:

  1. Block re-loading the change in the file.
  2. Add an icon-button to Firefox, in the address bar, that WARNS that the selected file is being watched all the time. This button could have an action that when clicked, all input[type=file] clears.

I don't know if the first option wouldn't "break the internet".
On the other hand, this is blocked in Chrome and can be lived with.... But Chrome has a File System Access API that replaces this feature.

Component: Untriaged → DOM: File
Product: Firefox → Core

A browser behavior difference, so I'd say a defect.

Severity: -- → S4
Status: UNCONFIRMED → NEW
Type: enhancement → defect
Ever confirmed: true
Summary: Button for warning and clearing input [type = file] on the page → File.text() provides updated file content on Gecko while Blink throws after file change

It seems FileReader already errors in this case, as seen in the repro in bug 1461885. The spec doesn't say exactly what should happen, but Blink and WebKit (Gnome Web) also throw, so I think this is a safe way to go.

Anne, do you have any objection since you filed an issue to follow the old WebKit way at https://github.com/w3c/FileAPI/issues/47 ?

Edit: Per https://github.com/whatwg/fs/issues/14 I guess the new File System Standard is also blocked at the spec ambiguity.

Flags: needinfo?(annevk)
See Also: → 660148

I would be okay with invalidating Blob objects backed by a local file once that file changes. The specification issue I filed was mainly about getting the behavior defined as it currently does not deal with this scenario. I would also be okay with defining the Firefox behavior, though OP has an interesting point about it being a potential tracking vector.

(And in all fairness aligning with Chromium and WebKit is likely much more straightforward as opposed to getting them to change.)

Flags: needinfo?(annevk)

Thanks, will take a look.

Assignee: nobody → krosylight

I looked at our implementation, and it seems the timestamp check will require us an additional system call while the existing size check is just using the initial file size (transferred via IPCBlob and stored at StreamBlobImpl construction) and the size of the actual read data at the end of the read.

Theoretically it should be possible to do the IPC call for the new timestamp and the file read in parallel, but I feel it's too complex for this edge case.

Not sure what Chrome/WebKit exactly do to accomplish this, I'm trying to read their code.

For WebKit:

  1. Blob::text() calls [Blob::loadBlob()] which then calls BlobLoader::start() and then ultimately FileReaderLoader::start().
  2. It calls ThreadableBlobRegistry::registerBlobURL(), then BlobRegistryProxy::registerBlobURL(), which calls NetworkConnectionToWebProcess::registerFileBlobURL() via IPC layer.
  3. That calls BlobRegistryImpl::registerFileBlobURL(), then [registerBlobResourceHandleConstructor()[(https://webkit-search.igalia.com/webkit/rev/b3b97cf1cd97b5de7f659a4d09bd6b245ab80240/Source/WebCore/platform/network/BlobRegistryImpl.cpp#66), and then indirectly loadBlobResourceSynchronously() and the same named BlobResourceHandle method, which calls ::start() and then ::doStart().
  4. BlobResourceHandle::doStart() (called by start()) checks size with getSizeForNext(), which calls FileStream::GetSize.
  5. Finally, FileStream::getSize() calls FileSystem::fileModificationTime first before checking size and fails if it's different with the existing value.

To summarize, each blob read on WebKit does check timestamp at the start via system call. (Not sure exactly how the size clamping happens though.)

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: