Index: content/browser/fileapi/fileapi_message_filter.cc |
=================================================================== |
--- content/browser/fileapi/fileapi_message_filter.cc (revision 182366) |
+++ content/browser/fileapi/fileapi_message_filter.cc (working copy) |
@@ -106,6 +106,8 @@ |
blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); |
} |
+ in_transit_snapshot_files_.clear(); |
+ |
// Close all files that are previously OpenFile()'ed in this process. |
if (!open_filesystem_urls_.empty()) { |
DLOG(INFO) |
@@ -152,6 +154,10 @@ |
IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) |
IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
OnCreateSnapshotFile) |
+ IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, |
+ OnDidReceiveSnapshotFile) |
+ IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile_Deprecated, |
+ OnCreateSnapshotFile_Deprecated) |
IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) |
IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) |
IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, |
@@ -539,6 +545,34 @@ |
} |
void FileAPIMessageFilter::OnCreateSnapshotFile( |
+ int request_id, const GURL& path) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ FileSystemURL url(context_->CrackURL(path)); |
+ |
+ // Make sure if this file can be read by the renderer as this is |
+ // called when the renderer is about to create a new File object |
+ // (for reading the file). |
+ base::PlatformFileError error; |
+ if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) { |
+ Send(new FileSystemMsg_DidFail(request_id, error)); |
+ return; |
+ } |
+ |
+ FileSystemOperation* operation = GetNewOperation(url, request_id); |
+ if (!operation) |
+ return; |
+ operation->CreateSnapshotFile( |
+ url, |
+ base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, |
+ this, request_id, url)); |
+} |
+ |
+void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ in_transit_snapshot_files_.erase(request_id); |
+} |
+ |
+void FileAPIMessageFilter::OnCreateSnapshotFile_Deprecated( |
int request_id, const GURL& blob_url, const GURL& path) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
FileSystemURL url(context_->CrackURL(path)); |
@@ -560,7 +594,7 @@ |
return; |
operation->CreateSnapshotFile( |
url, |
- base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, |
+ base::Bind(&FileAPIMessageFilter::DidCreateSnapshot_Deprecated, |
this, request_id, register_file_callback)); |
} |
@@ -736,6 +770,57 @@ |
void FileAPIMessageFilter::DidCreateSnapshot( |
int request_id, |
+ const fileapi::FileSystemURL& url, |
+ base::PlatformFileError result, |
+ const base::PlatformFileInfo& info, |
+ const base::FilePath& platform_path, |
+ const scoped_refptr<webkit_blob::ShareableFileReference>& snapshot_file) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (result != base::PLATFORM_FILE_OK) { |
+ Send(new FileSystemMsg_DidFail(request_id, result)); |
+ return; |
+ } |
+ |
+ if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
+ process_id_, platform_path)) { |
+ // In order for the renderer to be able to read the file, it must be granted |
+ // read permission for the file's platform path. By now, it has already been |
+ // verified that the renderer has sufficient permissions to read the file. |
+ // It is still possible that ChildProcessSecurityPolicyImpl doesn't reflect |
+ // that the renderer can read the file's platform path. If this is the case |
+ // the renderer should be granted read permission for the file's platform |
+ // path. This can happen in the following situations: |
+ // - the file comes from sandboxed filesystem. Reading sandboxed files is |
+ // always permitted, but only implicitly. |
+ // - the underlying filesystem returned newly created snapshot file. |
+ // - the file comes from an external drive filesystem. The renderer has |
+ // already been granted read permission for the file's nominal path, but |
+ // for drive files, platform paths differ from the nominal paths. |
+ DCHECK(snapshot_file || |
+ fileapi::SandboxMountPointProvider::CanHandleType(url.type()) || |
+ url.type() == fileapi::kFileSystemTypeDrive); |
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
+ process_id_, platform_path); |
+ if (snapshot_file) { |
+ // This will revoke all permissions for the file when the last ref |
+ // of the file is dropped (assuming it's ok). |
+ snapshot_file->AddFinalReleaseCallback( |
+ base::Bind(&RevokeFilePermission, process_id_)); |
+ } |
+ } |
+ |
+ if (snapshot_file) { |
+ // This ref is held until OnDidReceiveSnapshotFile is called. |
+ in_transit_snapshot_files_[request_id] = snapshot_file; |
+ } |
+ |
+ // Return the file info and platform_path. |
+ Send(new FileSystemMsg_DidCreateSnapshotFile( |
+ request_id, info, platform_path)); |
+} |
+ |
+void FileAPIMessageFilter::DidCreateSnapshot_Deprecated( |
+ int request_id, |
const base::Callback<void(const base::FilePath&)>& register_file_callback, |
base::PlatformFileError result, |
const base::PlatformFileInfo& info, |