Open Bug 1424689 Opened 7 years ago Updated 3 days ago

File objects get from FileSystemDirectoryEntry and then FileSystemFileEntry has type ""

Categories

(Core :: DOM: Core & HTML, defect, P3)

58 Branch
defect

Tracking

()

People

(Reporter: danny0838, Unassigned, NeedInfo)

Details

Attachments

(1 file)

Attached file FileSystemFileBug.html
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Build ID: 20171024165158 Steps to reproduce: 1. Download the test file and open it in the Firefox browser. 2. Drop a directory containing "somefilename.html". 3. See the browser console for the File objects retrieved from the drop event. Actual results: The File object got from FileSystemDirectoryEntry and then FileSystemFileEntry always has type "". Expected results: The File object got from FileSystemDirectoryEntry and then FileSystemFileEntry should have type corresponding with its file extension. Note: if drop a file "somefilename.html", the File object got from FileSystemFileEntry.file() has correct type.
Version: 56 Branch → 58 Branch
Component: Untriaged → DOM
Product: Firefox → Core
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P3
Component: DOM → DOM: Core & HTML

I've started debugging this. This is the first time I've worked in this codebase so my terminology might be wrong, also the details below might not be 100% correct (but it should be roughly correct).

For the drag-and-drop of single files the main process reads the actual file, creates a StreamBlobImpl and sends it to the child/tab process over IPC. The content-type (and file size) are "lazily set", i.e. they are unset until someone actually wants to read them. Either during IPC serialization or earlier these values are read and set, and then the IPCBlob (which now has content-type set) is sent to the child/tab process.

For drag-and-drop of a directory the process is a bit more complex. The same thing as above happens at first but only for the directory file. When the child process has received the directory file it sends a message back to the main process (GetDirectoryListingTask) - the main process traverse the directory and creates FileBlobImpl objects for each file in the directory which is finally sent back to the child process. However, and this is what I think the problem is, during IPC seralization when it tries to read and set content-type the executing thread is neither the NS main thread nor does it have a "CurrentThreadWorkerPrivate" available (gdb says we are in the IPDL Background thread), so it's hitting this block: https://hg.mozilla.org/mozilla-unified/file/tip/dom/file/FileBlobImpl.cpp#l203 - essentially giving up and setting content-type to an empty string.

Now, I would like to write a patch for this issue but my lack of knowledge of this codebase and threads/thread-safety makes it a bit hard. Maybe it's easy to dispatch a task for setting the content-type from the correct thread? I'm not sure.

Thanks for the debugging! Do you have a stack of the GetTypeInternal call?

Olli / Andrea, perhaps you can help out Simon to say what the right approach to fix it is?

Flags: needinfo?(bugs)
Flags: needinfo?(amarchesini)

Yes:

(gdb) bt
#0  mozilla::dom::FileBlobImpl::GetTypeInternal(nsTSubstring<char16_t>&, mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) (this=0x7fff9c1a4010, aType=..., aProofOfLock=...)
    at /home/simon/private/firefox/mozilla-unified/dom/file/FileBlobImpl.cpp:194
#1  0x00007fffe826ac72 in mozilla::dom::FileBlobImpl::GetType(nsTSubstring<char16_t>&) (this=0x7fff9c1a4010, aType=...)
    at /home/simon/private/firefox/mozilla-unified/dom/file/FileBlobImpl.cpp:189
#2  0x00007fffe829c74b in mozilla::dom::IPCBlobUtils::SerializeInternal<mozilla::ipc::PBackgroundParent>(mozilla::dom::BlobImpl*, mozilla::ipc::PBackgroundParent*, mozilla::dom::IPCBlob&)
    (aBlobImpl=0x7fff9c1a4010, aManager=0x7fff9bf4a300, aIPCBlob=...) at /home/simon/private/firefox/mozilla-unified/dom/file/ipc/IPCBlobUtils.cpp:85
#3  0x00007fffe828abd5 in mozilla::dom::IPCBlobUtils::Serialize(mozilla::dom::BlobImpl*, mozilla::ipc::PBackgroundParent*, mozilla::dom::IPCBlob&)
    (aBlobImpl=0x7fff9c1a4010, aManager=0x7fff9bf4a300, aIPCBlob=...) at /home/simon/private/firefox/mozilla-unified/dom/file/ipc/IPCBlobUtils.cpp:160
#4  0x00007fffe82ce8a9 in mozilla::dom::GetDirectoryListingTaskParent::GetSuccessRequestResult(mozilla::ErrorResult&) const (this=0x7fff9bfa9300, aRv=...)
    at /home/simon/private/firefox/mozilla-unified/dom/filesystem/GetDirectoryListingTask.cpp:242
#5  0x00007fffe82cd11f in mozilla::dom::FileSystemTaskParentBase::GetRequestResult() const (this=0x7fff9bfa9300)
    at /home/simon/private/firefox/mozilla-unified/dom/filesystem/FileSystemTaskBase.cpp:213
#6  0x00007fffe82ccf8e in mozilla::dom::FileSystemTaskParentBase::HandleResult() (this=0x7fff9bfa9300)
    at /home/simon/private/firefox/mozilla-unified/dom/filesystem/FileSystemTaskBase.cpp:201
#7  0x00007fffe82cd33c in mozilla::dom::FileSystemTaskParentBase::Run() (this=0x7fff9bfa9300) at /home/simon/private/firefox/mozilla-unified/dom/filesystem/FileSystemTaskBase.cpp:250
#8  0x00007fffe392d2f8 in nsThread::ProcessNextEvent(bool, bool*) (this=0x7fffd6798b70, aMayWait=true, aResult=0x7fffba9f99f7)
    at /home/simon/private/firefox/mozilla-unified/xpcom/threads/nsThread.cpp:1168
#9  0x00007fffe3933393 in NS_ProcessNextEvent(nsIThread*, bool) (aThread=0x7fffd6798b70, aMayWait=true) at /home/simon/private/firefox/mozilla-unified/xpcom/threads/nsThreadUtils.cpp:467
#10 0x00007fffe484aeaa in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) (this=0x7fffbd6df5c0, aDelegate=0x7fffba9f9be8)
    at /home/simon/private/firefox/mozilla-unified/ipc/glue/MessagePump.cpp:330
#11 0x00007fffe4714928 in MessageLoop::RunInternal() (this=0x7fffba9f9be8) at /home/simon/private/firefox/mozilla-unified/ipc/chromium/src/base/message_loop.cc:331
#12 0x00007fffe47148a5 in MessageLoop::RunHandler() (this=0x7fffba9f9be8) at /home/simon/private/firefox/mozilla-unified/ipc/chromium/src/base/message_loop.cc:324
#13 0x00007fffe471485d in MessageLoop::Run() (this=0x7fffba9f9be8) at /home/simon/private/firefox/mozilla-unified/ipc/chromium/src/base/message_loop.cc:306
#14 0x00007fffe3929023 in nsThread::ThreadFunc(void*) (aArg=0x7fffbd6de120) at /home/simon/private/firefox/mozilla-unified/xpcom/threads/nsThread.cpp:390
#15 0x00007ffff6f76576 in _pt_root (arg=0x7fffd72d15e0) at /home/simon/private/firefox/mozilla-unified/nsprpub/pr/src/pthreads/ptthread.c:201
#16 0x00007ffff7f85eae in start_thread (arg=0x7fffba9fa640) at pthread_create.c:463
#17 0x00007ffff7b44a5f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) info thread 60
  Id   Target Id                                            Frame 
* 60   Thread 0x7fffba9fa640 (LWP 198997) "IPDL Background" mozilla::dom::FileBlobImpl::GetTypeInternal (this=0x7fff9c1a4010, aType=..., aProofOfLock=...)
    at /home/simon/private/firefox/mozilla-unified/dom/file/FileBlobImpl.cpp:194

Again, I'm new to the codebase so I don't have a very good idea of how all of this works. But, from looking at the FileBlobImpl::GetTypeInternal code I guess there are two scenarios where we can fetch the MIME type:

  1. We are in the NS main thread, so we are able to simply ask the MIME service for the file's MIME type
  2. We have a worker thread / worker threads available, so we can dispatch the fetch to a worker thread. The runnable simply calls GetTypeInternal, so I assume that dispatching a runnable to a worker thread makes it run in the NS main thread?

Questions:

  1. Why isn't there a worker thread / worker threads available in this context? Is it because the IPDL Background thread doesn't have any worker threads or is it because the main/parent process doesn't have any worker threads?
  2. Does child processes have access to the MIME service? If so, would a solution be to let the main/parent process hit this block and send an empty type, and then later on let the child process fetch the MIME type? Is there a NS main thread in the child processes as well and/or are there worker threads available there?
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: