diff options
-rw-r--r-- | chrome/common/pepper_file_messages.cc | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper_file_message_filter.cc | 91 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper_file_message_filter.h | 10 | ||||
-rw-r--r-- | ppapi/c/private/ppb_flash_file.h | 64 | ||||
-rw-r--r-- | webkit/plugins/ppapi/file_path.cc | 4 | ||||
-rw-r--r-- | webkit/plugins/ppapi/file_path.h | 2 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_module.cc | 2 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_flash_file_impl.cc | 102 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_flash_file_impl.h | 6 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_request_info_impl.cc | 1 |
10 files changed, 228 insertions, 56 deletions
diff --git a/chrome/common/pepper_file_messages.cc b/chrome/common/pepper_file_messages.cc index 83a933c..c4bd665 100644 --- a/chrome/common/pepper_file_messages.cc +++ b/chrome/common/pepper_file_messages.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/content/browser/renderer_host/pepper_file_message_filter.cc b/content/browser/renderer_host/pepper_file_message_filter.cc index fc551df..2a1e5d8 100644 --- a/content/browser/renderer_host/pepper_file_message_filter.cc +++ b/content/browser/renderer_host/pepper_file_message_filter.cc @@ -7,12 +7,13 @@ #include "base/callback.h" #include "base/file_path.h" #include "base/file_util.h" +#include "base/platform_file.h" #include "base/process_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" -#include "chrome/common/child_process_host.h" #include "chrome/common/pepper_file_messages.h" #include "content/browser/browser_thread.h" +#include "content/browser/child_process_security_policy.h" #include "ipc/ipc_platform_file.h" #include "webkit/plugins/ppapi/file_path.h" @@ -20,31 +21,23 @@ #include "base/file_descriptor_posix.h" #endif -namespace { - -FilePath ConvertPepperFilePath( - const webkit::ppapi::PepperFilePath& pepper_path) { - FilePath file_path; - switch(pepper_path.domain()) { - case webkit::ppapi::PepperFilePath::DOMAIN_ABSOLUTE: - NOTIMPLEMENTED(); - break; - case webkit::ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: - if (!pepper_path.path().IsAbsolute() && - !pepper_path.path().ReferencesParent()) - file_path = pepper_path.path(); - break; - default: - NOTREACHED(); - break; - } - return file_path; -} - -} // namespace - -PepperFileMessageFilter::PepperFileMessageFilter( - int child_id, Profile* profile) { +// Used to check if the renderer has permission for the requested operation. +// TODO(viettrungluu): Verify these. They don't necessarily quite make sense, +// but it seems to be approximately what the file system code does. +const int kReadPermissions = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_READ | + base::PLATFORM_FILE_EXCLUSIVE_READ; +const int kWritePermissions = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_CREATE | + base::PLATFORM_FILE_CREATE_ALWAYS | + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_EXCLUSIVE_WRITE | + base::PLATFORM_FILE_TRUNCATE | + base::PLATFORM_FILE_WRITE_ATTRIBUTES; + +PepperFileMessageFilter::PepperFileMessageFilter(int child_id, + Profile* profile) + : child_id_(child_id) { pepper_path_ = profile->GetPath().Append(FILE_PATH_LITERAL("Pepper Data")); } @@ -85,7 +78,7 @@ void PepperFileMessageFilter::OnOpenFile( int flags, base::PlatformFileError* error, IPC::PlatformFileForTransit* file) { - FilePath full_path = ConvertPepperFilePath(path); + FilePath full_path = ValidateAndConvertPepperFilePath(path, flags); if (full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; *file = IPC::InvalidPlatformFileForTransit(); @@ -128,8 +121,10 @@ void PepperFileMessageFilter::OnRenameFile( const webkit::ppapi::PepperFilePath& from_path, const webkit::ppapi::PepperFilePath& to_path, base::PlatformFileError* error) { - FilePath from_full_path = ConvertPepperFilePath(from_path); - FilePath to_full_path = ConvertPepperFilePath(to_path); + FilePath from_full_path = ValidateAndConvertPepperFilePath(from_path, + kWritePermissions); + FilePath to_full_path = ValidateAndConvertPepperFilePath(to_path, + kWritePermissions); if (from_full_path.empty() || to_full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; return; @@ -144,7 +139,8 @@ void PepperFileMessageFilter::OnDeleteFileOrDir( const webkit::ppapi::PepperFilePath& path, bool recursive, base::PlatformFileError* error) { - FilePath full_path = ConvertPepperFilePath(path); + FilePath full_path = ValidateAndConvertPepperFilePath(path, + kWritePermissions); if (full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; return; @@ -158,7 +154,8 @@ void PepperFileMessageFilter::OnDeleteFileOrDir( void PepperFileMessageFilter::OnCreateDir( const webkit::ppapi::PepperFilePath& path, base::PlatformFileError* error) { - FilePath full_path = ConvertPepperFilePath(path); + FilePath full_path = ValidateAndConvertPepperFilePath(path, + kWritePermissions); if (full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; return; @@ -173,7 +170,7 @@ void PepperFileMessageFilter::OnQueryFile( const webkit::ppapi::PepperFilePath& path, base::PlatformFileInfo* info, base::PlatformFileError* error) { - FilePath full_path = ConvertPepperFilePath(path); + FilePath full_path = ValidateAndConvertPepperFilePath(path, kReadPermissions); if (full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; return; @@ -188,7 +185,7 @@ void PepperFileMessageFilter::OnGetDirContents( const webkit::ppapi::PepperFilePath& path, webkit::ppapi::DirContents* contents, base::PlatformFileError* error) { - FilePath full_path = ConvertPepperFilePath(path); + FilePath full_path = ValidateAndConvertPepperFilePath(path, kReadPermissions); if (full_path.empty()) { *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; return; @@ -215,3 +212,31 @@ void PepperFileMessageFilter::OnGetDirContents( *error = base::PLATFORM_FILE_OK; } + +FilePath PepperFileMessageFilter::ValidateAndConvertPepperFilePath( + const webkit::ppapi::PepperFilePath& pepper_path, int flags) { + FilePath file_path; // Empty path returned on error. + switch(pepper_path.domain()) { + case webkit::ppapi::PepperFilePath::DOMAIN_ABSOLUTE: +// TODO(viettrungluu): This could be dangerous if not 100% right, so let's be +// conservative and only enable it when requested. +#if defined(ENABLE_FLAPPER_HACKS) + if (pepper_path.path().IsAbsolute() && + ChildProcessSecurityPolicy::GetInstance()->HasPermissionsForFile( + child_id(), pepper_path.path(), flags)) + file_path = pepper_path.path(); +#else + NOTIMPLEMENTED(); +#endif // ENABLE_FLAPPER_HACKS + break; + case webkit::ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: + if (!pepper_path.path().IsAbsolute() && + !pepper_path.path().ReferencesParent()) + file_path = pepper_path.path(); + break; + default: + NOTREACHED(); + break; + } + return file_path; +} diff --git a/content/browser/renderer_host/pepper_file_message_filter.h b/content/browser/renderer_host/pepper_file_message_filter.h index 530d9c6..7fa0212 100644 --- a/content/browser/renderer_host/pepper_file_message_filter.h +++ b/content/browser/renderer_host/pepper_file_message_filter.h @@ -38,6 +38,8 @@ class PepperFileMessageFilter : public BrowserMessageFilter { bool* message_was_ok); virtual void OnDestruct() const; + int child_id() const { return child_id_; } + private: friend class BrowserThread; friend class DeleteTask<PepperFileMessageFilter>; @@ -63,6 +65,14 @@ class PepperFileMessageFilter : public BrowserMessageFilter { webkit::ppapi::DirContents* contents, base::PlatformFileError* error); + // Validate and convert the Pepper file path to a "real" |FilePath|. Returns + // an empty |FilePath| on error. + FilePath ValidateAndConvertPepperFilePath( + const webkit::ppapi::PepperFilePath& pepper_path, int flags); + + // The ID of the child process. + const int child_id_; + // The channel associated with the renderer connection. This pointer is not // owned by this class. IPC::Channel* channel_; diff --git a/ppapi/c/private/ppb_flash_file.h b/ppapi/c/private/ppb_flash_file.h index 8e1f291..9e2def9 100644 --- a/ppapi/c/private/ppb_flash_file.h +++ b/ppapi/c/private/ppb_flash_file.h @@ -38,45 +38,45 @@ struct PP_DirContents_Dev { #define PPB_FLASH_FILE_MODULELOCAL_INTERFACE "PPB_Flash_File_ModuleLocal;1" +// This interface provides (for Flash) synchronous access to module-local files. +// Module-local file paths are '/'-separated UTF-8 strings, relative to a +// module-specific root. struct PPB_Flash_File_ModuleLocal { - // Opens a module-local file, returning a file descriptor (posix) or a HANDLE - // (win32) into file. Module-local file paths (here and below) are - // '/'-separated UTF-8 strings, relative to a module-specific root. The return - // value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in case - // of failure. + // Opens a file, returning a file descriptor (posix) or a HANDLE (win32) into + // file. The return value is the ppapi error, PP_OK if success, one of the + // PP_ERROR_* in case of failure. int32_t (*OpenFile)(PP_Instance instance, const char* path, int32_t mode, PP_FileHandle* file); - // Renames a module-local file. The return value is the ppapi error, PP_OK if - // success, one of the PP_ERROR_* in case of failure. + // Renames a file. The return value is the ppapi error, PP_OK if success, one + // of the PP_ERROR_* in case of failure. int32_t (*RenameFile)(PP_Instance instance, const char* path_from, const char* path_to); - // Deletes a module-local file or directory. If recursive is set and the path - // points to a directory, deletes all the contents of the directory. The - // return value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in - // case of failure. + // Deletes a file or directory. If recursive is set and the path points to a + // directory, deletes all the contents of the directory. The return value is + // the ppapi error, PP_OK if success, one of the PP_ERROR_* in case of + // failure. int32_t (*DeleteFileOrDir)(PP_Instance instance, const char* path, PP_Bool recursive); - // Creates a module-local directory. The return value is the ppapi error, - // PP_OK if success, one of the PP_ERROR_* in case of failure. + // Creates a directory. The return value is the ppapi error, PP_OK if success, + // one of the PP_ERROR_* in case of failure. int32_t (*CreateDir)(PP_Instance instance, const char* path); - // Queries information about a module-local file. The return value is the - // ppapi error, PP_OK if success, one of the PP_ERROR_* in case of failure. + // Queries information about a file. The return value is the ppapi error, + // PP_OK if success, one of the PP_ERROR_* in case of failure. int32_t (*QueryFile)(PP_Instance instance, const char* path, struct PP_FileInfo_Dev* info); - // Gets the list of files contained in a module-local directory. The return - // value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in case - // of failure. If non-NULL, the returned contents should be freed with - // FreeDirContents. + // Gets the list of files contained in a directory. The return value is the + // ppapi error, PP_OK if success, one of the PP_ERROR_* in case of failure. If + // non-NULL, the returned contents should be freed with FreeDirContents. int32_t (*GetDirContents)(PP_Instance instance, const char* path, struct PP_DirContents_Dev** contents); @@ -86,4 +86,30 @@ struct PPB_Flash_File_ModuleLocal { struct PP_DirContents_Dev* contents); }; +// PPB_Flash_File_FileRef ------------------------------------------------------ + +#define PPB_FLASH_FILE_FILEREF_INTERFACE "PPB_Flash_File_FileRef;1" + +// This interface provides (for Flash) synchronous access to files whose paths +// are given by a Pepper FileRef. Such FileRefs are typically obtained via the +// Pepper file chooser. +struct PPB_Flash_File_FileRef { + // The functions below correspond exactly to the ones in the module-local file + // interface (except in taking FileRefs instead of paths, of course). + int32_t (*OpenFile)(PP_Resource file_ref_id, + int32_t mode, + PP_FileHandle* file); + int32_t (*RenameFile)(PP_Resource from_file_ref_id, + PP_Resource to_file_ref_id); + int32_t (*DeleteFileOrDir)(PP_Resource file_ref_id, + PP_Bool recursive); + int32_t (*CreateDir)(PP_Resource file_ref_id); + int32_t (*QueryFile)(PP_Resource file_ref_id, + struct PP_FileInfo_Dev* info); + int32_t (*GetDirContents)(PP_Resource file_ref_id, + struct PP_DirContents_Dev** contents); + void (*FreeDirContents)(PP_Instance instance, + struct PP_DirContents_Dev* contents); +}; + #endif // PPAPI_C_PRIVATE_PPB_FLASH_FILE_H_ diff --git a/webkit/plugins/ppapi/file_path.cc b/webkit/plugins/ppapi/file_path.cc index a7ed447..95408c2 100644 --- a/webkit/plugins/ppapi/file_path.cc +++ b/webkit/plugins/ppapi/file_path.cc @@ -39,8 +39,8 @@ PepperFilePath::PepperFilePath(Domain domain, FilePath path) } // static -PepperFilePath PepperFilePath::MakeAbsolute(const char* utf8_path) { - return PepperFilePath(DOMAIN_ABSOLUTE, GetFilePathFromUTF8(utf8_path)); +PepperFilePath PepperFilePath::MakeAbsolute(const FilePath& path) { + return PepperFilePath(DOMAIN_ABSOLUTE, path); } // static diff --git a/webkit/plugins/ppapi/file_path.h b/webkit/plugins/ppapi/file_path.h index 6d6f4dc..8a3851e 100644 --- a/webkit/plugins/ppapi/file_path.h +++ b/webkit/plugins/ppapi/file_path.h @@ -32,7 +32,7 @@ class PepperFilePath { PepperFilePath(); PepperFilePath(Domain d, FilePath p); - static PepperFilePath MakeAbsolute(const char* utf8_path); + static PepperFilePath MakeAbsolute(const FilePath& path); static PepperFilePath MakeModuleLocal(PluginModule* module, const char* utf8_path); diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index 2f155c6..8faa492 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -250,6 +250,8 @@ const void* GetInterface(const char* name) { return PluginInstance::GetFindInterface(); if (strcmp(name, PPB_FLASH_INTERFACE) == 0) return PPB_Flash_Impl::GetInterface(); + if (strcmp(name, PPB_FLASH_FILE_FILEREF_INTERFACE) == 0) + return PPB_Flash_File_FileRef_Impl::GetInterface(); if (strcmp(name, PPB_FLASH_FILE_MODULELOCAL_INTERFACE) == 0) return PPB_Flash_File_ModuleLocal_Impl::GetInterface(); if (strcmp(name, PPB_FLASH_MENU_INTERFACE) == 0) diff --git a/webkit/plugins/ppapi/ppb_flash_file_impl.cc b/webkit/plugins/ppapi/ppb_flash_file_impl.cc index bbd7f97..098f233 100644 --- a/webkit/plugins/ppapi/ppb_flash_file_impl.cc +++ b/webkit/plugins/ppapi/ppb_flash_file_impl.cc @@ -222,5 +222,107 @@ const PPB_Flash_File_ModuleLocal* return &ppb_flash_file_modulelocal; } +// PPB_Flash_File_FileRef_Impl ------------------------------------------------- + +namespace { + +int32_t OpenFileRefFile(PP_Resource file_ref_id, + int32_t mode, + PP_FileHandle* file) { + int flags = 0; + if (!ConvertFromPPFileOpenFlags(mode, &flags) || !file) + return PP_ERROR_BADARGUMENT; + + scoped_refptr<PPB_FileRef_Impl> file_ref( + Resource::GetAs<PPB_FileRef_Impl>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + PluginInstance* instance = file_ref->instance(); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFile base_file; + base::PlatformFileError result = instance->delegate()->OpenFile( + PepperFilePath::MakeAbsolute(file_ref->GetSystemPath()), + flags, + &base_file); + *file = base_file; + return PlatformFileErrorToPepperError(result); +} + +int32_t RenameFileRefFile(PP_Resource from_file_ref_id, + PP_Resource to_file_ref_id) { + // If it proves necessary, it's easy enough to implement. + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; +} + +int32_t DeleteFileRefFileOrDir(PP_Resource file_ref_id, + PP_Bool recursive) { + // If it proves necessary, it's easy enough to implement. + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; +} + +int32_t CreateFileRefDir(PP_Resource file_ref_id) { + // If it proves necessary, it's easy enough to implement. + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; +} + +int32_t QueryFileRefFile(PP_Resource file_ref_id, + PP_FileInfo_Dev* info) { + scoped_refptr<PPB_FileRef_Impl> file_ref( + Resource::GetAs<PPB_FileRef_Impl>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + PluginInstance* instance = file_ref->instance(); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFileInfo file_info; + base::PlatformFileError result = instance->delegate()->QueryFile( + PepperFilePath::MakeAbsolute(file_ref->GetSystemPath()), + &file_info); + if (result == base::PLATFORM_FILE_OK) { + info->size = file_info.size; + info->creation_time = file_info.creation_time.ToDoubleT(); + info->last_access_time = file_info.last_accessed.ToDoubleT(); + info->last_modified_time = file_info.last_modified.ToDoubleT(); + info->system_type = PP_FILESYSTEMTYPE_EXTERNAL; + if (file_info.is_directory) + info->type = PP_FILETYPE_DIRECTORY; + else + info->type = PP_FILETYPE_REGULAR; + } + return PlatformFileErrorToPepperError(result); +} + +int32_t GetFileRefDirContents(PP_Resource file_ref_id, + PP_DirContents_Dev** contents) { + // If it proves necessary, it's easy enough to implement. + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; +} + +const PPB_Flash_File_FileRef ppb_flash_file_fileref = { + &OpenFileRefFile, + &RenameFileRefFile, + &DeleteFileRefFileOrDir, + &CreateFileRefDir, + &QueryFileRefFile, + &GetFileRefDirContents, + &FreeDirContents, +}; + +} // namespace + +// static +const PPB_Flash_File_FileRef* PPB_Flash_File_FileRef_Impl::GetInterface() { + return &ppb_flash_file_fileref; +} + } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_flash_file_impl.h b/webkit/plugins/ppapi/ppb_flash_file_impl.h index 2de7512..ddfba9d 100644 --- a/webkit/plugins/ppapi/ppb_flash_file_impl.h +++ b/webkit/plugins/ppapi/ppb_flash_file_impl.h @@ -5,6 +5,7 @@ #ifndef WEBKIT_PLUGINS_PPAPI_PPB_FLASH_FILE_IMPL_H_ #define WEBKIT_PLUGINS_PPAPI_PPB_FLASH_FILE_IMPL_H_ +struct PPB_Flash_File_FileRef; struct PPB_Flash_File_ModuleLocal; namespace webkit { @@ -15,6 +16,11 @@ class PPB_Flash_File_ModuleLocal_Impl { static const PPB_Flash_File_ModuleLocal* GetInterface(); }; +class PPB_Flash_File_FileRef_Impl { + public: + static const PPB_Flash_File_FileRef* GetInterface(); +}; + } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc index 897bbb4..f7b472e 100644 --- a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc @@ -278,6 +278,7 @@ WebURLRequest PPB_URLRequestInfo_Impl::ToWebURLRequest(WebFrame* frame) const { web_request.initialize(); web_request.setURL(frame->document().completeURL(WebString::fromUTF8(url_))); web_request.setDownloadToFile(stream_to_file_); + web_request.setReportUploadProgress(record_upload_progress()); if (!method_.empty()) web_request.setHTTPMethod(WebString::fromUTF8(method_)); |