diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 08:09:45 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 08:09:45 +0000 |
commit | 0a1a4543882c0cf8b73a44d4d79f36c4e6d77fe9 (patch) | |
tree | fcf3bff8df2138387cb0ad397460216fc05a66dc /chrome | |
parent | 28dd598b6433c08e58e261538af94b8aa5edff60 (diff) | |
download | chromium_src-0a1a4543882c0cf8b73a44d4d79f36c4e6d77fe9.zip chromium_src-0a1a4543882c0cf8b73a44d4d79f36c4e6d77fe9.tar.gz chromium_src-0a1a4543882c0cf8b73a44d4d79f36c4e6d77fe9.tar.bz2 |
Reland 43183. Block database access on allowDatabase instead of databaseOpenFile. BUG=36435 TEST=Set cookie settings to ASK and open a page with web databases. Review URL: http://codereview.chromium.org/1338001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43185 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
19 files changed, 204 insertions, 256 deletions
diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm index d99ea38..563f786 100644 --- a/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm +++ b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm @@ -94,8 +94,8 @@ TEST_F(CookiePromptWindowControllerTest, CreateForCookie) { TEST_F(CookiePromptWindowControllerTest, CreateForDatabase) { GURL url("http://google.com"); string16 databaseName(base::SysNSStringToUTF16(@"some database")); - scoped_ptr<CookiePromptModalDialog> dialog( - new CookiePromptModalDialog(NULL, NULL, url, databaseName, NULL)); + scoped_ptr<CookiePromptModalDialog> dialog(new CookiePromptModalDialog( + NULL, NULL, url, databaseName, databaseName, 1, NULL)); scoped_nsobject<CookiePromptWindowController> controller( [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]); EXPECT_TRUE(controller.get()); diff --git a/chrome/browser/cookie_modal_dialog.cc b/chrome/browser/cookie_modal_dialog.cc index 45347dc..4435bcb 100644 --- a/chrome/browser/cookie_modal_dialog.cc +++ b/chrome/browser/cookie_modal_dialog.cc @@ -50,12 +50,16 @@ CookiePromptModalDialog::CookiePromptModalDialog( HostContentSettingsMap* host_content_settings_map, const GURL& origin, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, CookiePromptModalDialogDelegate* delegate) : AppModalDialog(tab_contents, std::wstring()), host_content_settings_map_(host_content_settings_map), dialog_type_(DIALOG_TYPE_DATABASE), origin_(origin), database_name_(database_name), + display_name_(display_name), + estimated_size_(estimated_size), delegate_(delegate) { } diff --git a/chrome/browser/cookie_modal_dialog.h b/chrome/browser/cookie_modal_dialog.h index 793c587..bfc2b67 100644 --- a/chrome/browser/cookie_modal_dialog.h +++ b/chrome/browser/cookie_modal_dialog.h @@ -52,6 +52,8 @@ class CookiePromptModalDialog : public AppModalDialog { HostContentSettingsMap* host_content_settings_map, const GURL& origin, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, CookiePromptModalDialogDelegate* delegate); CookiePromptModalDialog(TabContents* tab_contents, HostContentSettingsMap* host_content_settings_map, @@ -80,6 +82,8 @@ class CookiePromptModalDialog : public AppModalDialog { const string16& local_storage_key() const { return local_storage_key_; } const string16& local_storage_value() const { return local_storage_value_; } const string16& database_name() const { return database_name_; } + const string16& display_name() const { return display_name_; } + unsigned long estimated_size() const { return estimated_size_; } const GURL& appcache_manifest_url() const { return appcache_manifest_url_; } TabContents* tab_contents() const { return tab_contents_; } @@ -114,6 +118,8 @@ class CookiePromptModalDialog : public AppModalDialog { const string16 local_storage_key_; const string16 local_storage_value_; const string16 database_name_; + const string16 display_name_; + unsigned long estimated_size_; const GURL appcache_manifest_url_; // The caller should provide a delegate in order to receive results diff --git a/chrome/browser/cookie_modal_dialog_gtk.cc b/chrome/browser/cookie_modal_dialog_gtk.cc index 700236a..c7d7f16 100644 --- a/chrome/browser/cookie_modal_dialog_gtk.cc +++ b/chrome/browser/cookie_modal_dialog_gtk.cc @@ -118,7 +118,9 @@ NativeDialog CookiePromptModalDialog::CreateNativeDialog() { gtk_chrome_cookie_view_display_database_accessed( cookie_view, origin().host(), - database_name()); + database_name(), + display_name(), + estimated_size()); } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) { gtk_chrome_cookie_view_display_appcache_created( cookie_view, diff --git a/chrome/browser/gtk/gtk_chrome_cookie_view.cc b/chrome/browser/gtk/gtk_chrome_cookie_view.cc index 94bb9c1..57f7737 100644 --- a/chrome/browser/gtk/gtk_chrome_cookie_view.cc +++ b/chrome/browser/gtk/gtk_chrome_cookie_view.cc @@ -101,6 +101,10 @@ void InitStyles(GtkChromeCookieView *self) { dialog_style); InitBrowserDetailStyle(self->database_accessed_name_entry_, label_style, dialog_style); + InitBrowserDetailStyle(self->database_accessed_description_entry_, + label_style, dialog_style); + InitBrowserDetailStyle(self->database_accessed_size_entry_, label_style, + dialog_style); // AppCache created item. InitBrowserDetailStyle(self->appcache_created_manifest_entry_, label_style, @@ -152,6 +156,8 @@ void SetDatabaseAccessedSensitivity(GtkChromeCookieView* self, gboolean enabled) { gtk_widget_set_sensitive(self->database_accessed_origin_entry_, enabled); gtk_widget_set_sensitive(self->database_accessed_name_entry_, enabled); + gtk_widget_set_sensitive(self->database_accessed_description_entry_, enabled); + gtk_widget_set_sensitive(self->database_accessed_size_entry_, enabled); } void SetAppCacheCreatedSensitivity(GtkChromeCookieView* self, @@ -333,6 +339,12 @@ static void gtk_chrome_cookie_view_init(GtkChromeCookieView *self) { InitDetailRow(row++, IDS_COOKIES_WEB_DATABASE_NAME, self->database_accessed_table_, &self->database_accessed_name_entry_); + InitDetailRow(row++, IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL, + self->database_accessed_table_, + &self->database_accessed_description_entry_); + InitDetailRow(row++, IDS_COOKIES_SIZE_LABEL, + self->database_accessed_table_, + &self->database_accessed_size_entry_); // AppCache created prompt. self->appcache_created_table_ = gtk_table_new(1, 2, FALSE); @@ -495,13 +507,22 @@ void gtk_chrome_cookie_view_display_local_storage_item( void gtk_chrome_cookie_view_display_database_accessed( GtkChromeCookieView* self, const std::string& host, - const string16& database_name) { + const string16& database_name, + const string16& display_name, + unsigned long estimated_size) { UpdateVisibleDetailedInfo(self, self->database_accessed_table_); gtk_entry_set_text(GTK_ENTRY(self->database_accessed_origin_entry_), host.c_str()); gtk_entry_set_text(GTK_ENTRY(self->database_accessed_name_entry_), UTF16ToUTF8(database_name).c_str()); + gtk_entry_set_text(GTK_ENTRY(self->database_accessed_description_entry_), + UTF16ToUTF8(display_name).c_str()); + gtk_entry_set_text(GTK_ENTRY(self->database_accessed_size_entry_), + WideToUTF8(FormatBytes( + estimated_size, + GetByteDisplayUnits(estimated_size), + true)).c_str()); SetDatabaseAccessedSensitivity(self, TRUE); } diff --git a/chrome/browser/gtk/gtk_chrome_cookie_view.h b/chrome/browser/gtk/gtk_chrome_cookie_view.h index 73706f3..e729b04 100644 --- a/chrome/browser/gtk/gtk_chrome_cookie_view.h +++ b/chrome/browser/gtk/gtk_chrome_cookie_view.h @@ -95,6 +95,8 @@ typedef struct { GtkWidget* database_accessed_table_; GtkWidget* database_accessed_origin_entry_; GtkWidget* database_accessed_name_entry_; + GtkWidget* database_accessed_description_entry_; + GtkWidget* database_accessed_size_entry_; // The appcache created widgets. GtkWidget* appcache_created_table_; @@ -157,7 +159,9 @@ void gtk_chrome_cookie_view_display_local_storage_item( void gtk_chrome_cookie_view_display_database_accessed( GtkChromeCookieView* self, const std::string& host, - const string16& database_name); + const string16& database_name, + const string16& display_name, + unsigned long estimated_size); void gtk_chrome_cookie_view_display_appcache_created( GtkChromeCookieView* self, diff --git a/chrome/browser/message_box_handler.cc b/chrome/browser/message_box_handler.cc index e004a0e..1350c5c 100644 --- a/chrome/browser/message_box_handler.cc +++ b/chrome/browser/message_box_handler.cc @@ -70,10 +70,13 @@ void RunDatabasePrompt( HostContentSettingsMap* host_content_settings_map, const GURL& origin, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, CookiePromptModalDialogDelegate* delegate) { Singleton<AppModalDialogQueue>()->AddDialog( new CookiePromptModalDialog(tab_contents, host_content_settings_map, - origin, database_name, delegate)); + origin, database_name, display_name, + estimated_size, delegate)); } void RunAppCachePrompt( diff --git a/chrome/browser/message_box_handler.h b/chrome/browser/message_box_handler.h index be821f7..7a66902 100644 --- a/chrome/browser/message_box_handler.h +++ b/chrome/browser/message_box_handler.h @@ -69,6 +69,8 @@ void RunDatabasePrompt( HostContentSettingsMap* host_content_settings_map, const GURL& origin, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, CookiePromptModalDialogDelegate* delegate); // This will display a modal dialog box with the |manifest_url| and ask the diff --git a/chrome/browser/renderer_host/database_dispatcher_host.cc b/chrome/browser/renderer_host/database_dispatcher_host.cc index e7734ac..4c56f3b 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.cc +++ b/chrome/browser/renderer_host/database_dispatcher_host.cc @@ -97,6 +97,7 @@ bool DatabaseDispatcherHost::OnMessageReceived( IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseOpened, OnDatabaseOpened) IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseModified, OnDatabaseModified) IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseClosed, OnDatabaseClosed) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_AllowDatabase, OnAllowDatabase) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() return handled; @@ -107,11 +108,18 @@ void DatabaseDispatcherHost::ReceivedBadMessage(uint32 msg_type) { msg_type, process_handle_); } -// Scheduled by the file thread on the IO thread. -// Sends back to the renderer process the given message. -void DatabaseDispatcherHost::SendMessage(IPC::Message* message) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); - if (!shutdown_) +void DatabaseDispatcherHost::Send(IPC::Message* message) { + if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { + if (!ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(this, + &DatabaseDispatcherHost::Send, + message))) + delete message; + return; + } + + if (!shutdown_ && resource_message_filter_) resource_message_filter_->Send(message); else delete message; @@ -127,55 +135,13 @@ void DatabaseDispatcherHost::OnDatabaseOpenFile(const string16& vfs_file_name, NewRunnableMethod(this, &DatabaseDispatcherHost::AddObserver)); } - // Only ask permission on the main database file in read/write mode. - if (!VfsBackend::FileTypeIsMainDB(desired_flags) || - !VfsBackend::OpenTypeIsReadWrite(desired_flags)) { - OnDatabaseOpenFileAllowed(vfs_file_name, desired_flags, message_id); - return; - } - - string16 origin_identifier; - string16 database_name; - bool ok = DatabaseUtil::CrackVfsFileName(vfs_file_name, - &origin_identifier, - &database_name, - NULL); - DCHECK(ok); // Should we assume this is an attack and kill the renderer? - if (!ok) { - OnDatabaseOpenFileBlocked(message_id); - return; - } - - // TODO(jorlow): createFromDatabaseIdentifier should not return a pointer. - scoped_ptr<WebSecurityOrigin> security_origin( - WebSecurityOrigin::createFromDatabaseIdentifier(origin_identifier)); - string16 origin(security_origin->toString()); - GURL url = GURL(origin); - - HostContentSettingsMap* host_content_settings_map = resource_message_filter_-> - GetRequestContextForURL(url)->host_content_settings_map(); - ContentSetting content_setting = host_content_settings_map->GetContentSetting( - url.host(), CONTENT_SETTINGS_TYPE_COOKIES); - - if (content_setting == CONTENT_SETTING_ASK) { - // Create a task for each possible outcome. - scoped_ptr<Task> on_allow(NewRunnableMethod( - this, &DatabaseDispatcherHost::OnDatabaseOpenFileAllowed, - vfs_file_name, desired_flags, message_id)); - scoped_ptr<Task> on_block(NewRunnableMethod( - this, &DatabaseDispatcherHost::OnDatabaseOpenFileBlocked, message_id)); - // And then let the permission request object do the rest. - scoped_refptr<DatabasePermissionRequest> request( - new DatabasePermissionRequest(url, database_name, on_allow.release(), - on_block.release(), - host_content_settings_map)); - request->RequestPermission(); - } else if (content_setting == CONTENT_SETTING_ALLOW) { - OnDatabaseOpenFileAllowed(vfs_file_name, desired_flags, message_id); - } else { - DCHECK(content_setting == CONTENT_SETTING_BLOCK); - OnDatabaseOpenFileBlocked(message_id); - } + ChromeThread::PostTask( + ChromeThread::FILE, FROM_HERE, + NewRunnableMethod(this, + &DatabaseDispatcherHost::DatabaseOpenFile, + vfs_file_name, + desired_flags, + message_id)); } static void SetOpenFileResponseParams( @@ -220,12 +186,7 @@ void DatabaseDispatcherHost::DatabaseOpenFile(const string16& vfs_file_name, ViewMsg_DatabaseOpenFileResponse_Params response_params; SetOpenFileResponseParams(&response_params, target_handle, target_dir_handle); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseOpenFileResponse( - message_id, response_params))); + Send(new ViewMsg_DatabaseOpenFileResponse(message_id, response_params)); } void DatabaseDispatcherHost::OnDatabaseDeleteFile(const string16& vfs_file_name, @@ -273,12 +234,7 @@ void DatabaseDispatcherHost::DatabaseDeleteFile(const string16& vfs_file_name, } } - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseDeleteFileResponse( - message_id, error_code))); + Send(new ViewMsg_DatabaseDeleteFileResponse(message_id, error_code)); } void DatabaseDispatcherHost::OnDatabaseGetFileAttributes( @@ -305,12 +261,7 @@ void DatabaseDispatcherHost::DatabaseGetFileAttributes( DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); if (!db_file.empty()) attributes = VfsBackend::GetFileAttributes(db_file); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseGetFileAttributesResponse( - message_id, attributes))); + Send(new ViewMsg_DatabaseGetFileAttributesResponse(message_id, attributes)); } void DatabaseDispatcherHost::OnDatabaseGetFileSize( @@ -335,12 +286,7 @@ void DatabaseDispatcherHost::DatabaseGetFileSize(const string16& vfs_file_name, DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); if (!db_file.empty()) size = VfsBackend::GetFileSize(db_file); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseGetFileSizeResponse( - message_id, size))); + Send(new ViewMsg_DatabaseGetFileSizeResponse(message_id, size)); } void DatabaseDispatcherHost::OnDatabaseOpened(const string16& origin_identifier, @@ -367,13 +313,8 @@ void DatabaseDispatcherHost::DatabaseOpened(const string16& origin_identifier, database_connections_.AddConnection(origin_identifier, database_name); db_tracker_->DatabaseOpened(origin_identifier, database_name, description, estimated_size, &database_size, &space_available); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseUpdateSize( - origin_identifier, database_name, - database_size, space_available))); + Send(new ViewMsg_DatabaseUpdateSize(origin_identifier, database_name, + database_size, space_available)); } void DatabaseDispatcherHost::OnDatabaseModified( @@ -409,6 +350,49 @@ void DatabaseDispatcherHost::OnDatabaseClosed(const string16& origin_identifier, database_name)); } +void DatabaseDispatcherHost::OnAllowDatabase(const std::string& origin_url, + const string16& name, + const string16& display_name, + unsigned long estimated_size, + IPC::Message* reply_msg) { + GURL url = GURL(origin_url); + HostContentSettingsMap* host_content_settings_map = resource_message_filter_-> + GetRequestContextForURL(url)->host_content_settings_map(); + ContentSetting content_setting = host_content_settings_map->GetContentSetting( + url.host(), CONTENT_SETTINGS_TYPE_COOKIES); + + if (content_setting == CONTENT_SETTING_ASK) { + // Create a task for each possible outcome. + scoped_ptr<Task> on_allow(NewRunnableMethod( + this, &DatabaseDispatcherHost::AllowDatabaseResponse, + reply_msg, CONTENT_SETTING_ALLOW)); + scoped_ptr<Task> on_block(NewRunnableMethod( + this, &DatabaseDispatcherHost::AllowDatabaseResponse, + reply_msg, CONTENT_SETTING_BLOCK)); + // And then let the permission request object do the rest. + scoped_refptr<DatabasePermissionRequest> request( + new DatabasePermissionRequest(url, name, display_name, estimated_size, + on_allow.release(), on_block.release(), + host_content_settings_map)); + request->RequestPermission(); + + // Tell the renderer that it needs to run a nested message loop. + Send(new ViewMsg_SignalCookiePromptEvent()); + return; + } + + AllowDatabaseResponse(reply_msg, content_setting); +} + +void DatabaseDispatcherHost::AllowDatabaseResponse( + IPC::Message* reply_msg, ContentSetting content_setting) { + DCHECK((content_setting == CONTENT_SETTING_ALLOW) || + (content_setting == CONTENT_SETTING_BLOCK)); + ViewHostMsg_AllowDatabase::WriteReplyParams( + reply_msg, content_setting == CONTENT_SETTING_ALLOW); + Send(reply_msg); +} + void DatabaseDispatcherHost::DatabaseClosed(const string16& origin_identifier, const string16& database_name) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); @@ -429,13 +413,8 @@ void DatabaseDispatcherHost::OnDatabaseSizeChanged( int64 space_available) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); if (database_connections_.IsOriginUsed(origin_identifier)) { - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseUpdateSize( - origin_identifier, database_name, - database_size, space_available))); + Send(new ViewMsg_DatabaseUpdateSize(origin_identifier, database_name, + database_size, space_available)); } } @@ -443,40 +422,5 @@ void DatabaseDispatcherHost::OnDatabaseScheduledForDeletion( const string16& origin_identifier, const string16& database_name) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::SendMessage, - new ViewMsg_DatabaseCloseImmediately( - origin_identifier, database_name))); -} - -void DatabaseDispatcherHost::OnDatabaseOpenFileAllowed( - const string16& vfs_file_name, int desired_flags, int32 message_id) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); - if (shutdown_) - return; - - ChromeThread::PostTask( - ChromeThread::FILE, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::DatabaseOpenFile, - vfs_file_name, - desired_flags, - message_id)); -} - -void DatabaseDispatcherHost::OnDatabaseOpenFileBlocked(int32 message_id) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); - if (shutdown_) - return; - - // This will result in failed transactions NOT a failed window.openDatabase - // call. - ViewMsg_DatabaseOpenFileResponse_Params response_params; - SetOpenFileResponseParams(&response_params, - base::kInvalidPlatformFileValue, - base::kInvalidPlatformFileValue); - SendMessage(new ViewMsg_DatabaseOpenFileResponse(message_id, - response_params)); + Send(new ViewMsg_DatabaseCloseImmediately(origin_identifier, database_name)); } diff --git a/chrome/browser/renderer_host/database_dispatcher_host.h b/chrome/browser/renderer_host/database_dispatcher_host.h index 4c16d06..251bc5b 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.h +++ b/chrome/browser/renderer_host/database_dispatcher_host.h @@ -14,6 +14,9 @@ #include "webkit/database/database_connections.h" #include "webkit/database/database_tracker.h" +class GURL; +class HostContentSettingsMap; +class Receiver; class ResourceMessageFilter; class DatabaseDispatcherHost @@ -48,6 +51,11 @@ class DatabaseDispatcherHost const string16& database_name); void OnDatabaseClosed(const string16& origin_identifier, const string16& database_name); + void OnAllowDatabase(const std::string& origin_url, + const string16& name, + const string16& display_name, + unsigned long estimated_size, + IPC::Message* reply_msg); // DatabaseTracker::Observer callbacks (file thread) virtual void OnDatabaseSizeChanged(const string16& origin_identifier, @@ -57,12 +65,15 @@ class DatabaseDispatcherHost virtual void OnDatabaseScheduledForDeletion(const string16& origin_identifier, const string16& database_name); + void Send(IPC::Message* message); + private: + class PromptDelegate; + void AddObserver(); void RemoveObserver(); void ReceivedBadMessage(uint32 msg_type); - void SendMessage(IPC::Message* message); // VFS message handlers (file thread) void DatabaseOpenFile(const string16& vfs_file_name, @@ -87,11 +98,9 @@ class DatabaseDispatcherHost void DatabaseClosed(const string16& origin_identifier, const string16& database_name); - // Called once we decide whether to allow or block an open file request. - void OnDatabaseOpenFileAllowed(const string16& vfs_file_name, - int desired_flags, - int32 message_id); - void OnDatabaseOpenFileBlocked(int32 message_id); + // CookiePromptModalDialog response handler (io thread) + void AllowDatabaseResponse(IPC::Message* reply_msg, + ContentSetting content_setting); // The database tracker for the current profile. scoped_refptr<webkit_database::DatabaseTracker> db_tracker_; diff --git a/chrome/browser/renderer_host/database_permission_request.cc b/chrome/browser/renderer_host/database_permission_request.cc index 5efb567..fb417e7 100644 --- a/chrome/browser/renderer_host/database_permission_request.cc +++ b/chrome/browser/renderer_host/database_permission_request.cc @@ -13,11 +13,15 @@ DatabasePermissionRequest::DatabasePermissionRequest( const GURL& url, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, Task* on_allow, Task* on_block, HostContentSettingsMap* settings_map) : url_(url), database_name_(database_name), + display_name_(display_name), + estimated_size_(estimated_size), on_allow_(on_allow), on_block_(on_block), host_content_settings_map_(settings_map) { @@ -55,7 +59,8 @@ void DatabasePermissionRequest::RequestPermission() { // Will call either AllowSiteData or BlockSiteData which will NULL out our // self reference. RunDatabasePrompt(browser->GetSelectedTabContents(), - host_content_settings_map_, url_, database_name_, this); + host_content_settings_map_, url_, database_name_, + display_name_, estimated_size_, this); } void DatabasePermissionRequest::AllowSiteData(bool session_expire) { diff --git a/chrome/browser/renderer_host/database_permission_request.h b/chrome/browser/renderer_host/database_permission_request.h index 8b3f033..7ad09b5e 100644 --- a/chrome/browser/renderer_host/database_permission_request.h +++ b/chrome/browser/renderer_host/database_permission_request.h @@ -22,6 +22,8 @@ class DatabasePermissionRequest public: DatabasePermissionRequest(const GURL& url, const string16& database_name, + const string16& display_name, + unsigned long estimated_size, Task* on_allow, Task* on_block, HostContentSettingsMap* settings_map); @@ -29,6 +31,8 @@ class DatabasePermissionRequest const GURL& url() const { return url_; } const string16& database_name() const { return database_name_; } + const string16& display_name() const { return display_name_; } + unsigned long estimated_size() const { return estimated_size_; } // Start the permission request process. void RequestPermission(); @@ -43,6 +47,8 @@ class DatabasePermissionRequest // The URL to get permission for. const GURL url_; const string16 database_name_; + const string16 display_name_; + unsigned long estimated_size_; // Set on IO, possibly release()ed on UI, destroyed on IO or UI. scoped_ptr<Task> on_allow_; diff --git a/chrome/browser/views/cookie_prompt_view.cc b/chrome/browser/views/cookie_prompt_view.cc index f89724ad..b2b2a5f 100644 --- a/chrome/browser/views/cookie_prompt_view.cc +++ b/chrome/browser/views/cookie_prompt_view.cc @@ -240,7 +240,9 @@ void CookiePromptView::Init() { DatabaseOpenInfoView* view = new DatabaseOpenInfoView(); layout->AddView(view, 1, 1, GridLayout::FILL, GridLayout::CENTER); view->SetFields(parent_->origin().host(), - parent_->database_name()); + parent_->database_name(), + parent_->display_name(), + parent_->estimated_size()); info_view_ = view; } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) { static const int kAppCacheInfoLabels[] = { diff --git a/chrome/browser/views/database_open_info_view.cc b/chrome/browser/views/database_open_info_view.cc index a670776..1e0fbc2 100644 --- a/chrome/browser/views/database_open_info_view.cc +++ b/chrome/browser/views/database_open_info_view.cc @@ -4,103 +4,37 @@ #include "chrome/browser/views/database_open_info_view.h" -#include <algorithm> - #include "app/l10n_util.h" -#include "base/i18n/time_formatting.h" #include "base/utf_string_conversions.h" -#include "gfx/color_utils.h" #include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" -static const int kDatabaseOpenInfoViewBorderSize = 1; -static const int kDatabaseOpenInfoViewInsetSize = 3; +namespace { +const int kInfoLabelIds[] = { + IDS_COOKIES_COOKIE_DOMAIN_LABEL, + IDS_COOKIES_WEB_DATABASE_NAME, + IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL, + IDS_COOKIES_SIZE_LABEL +}; +} // namespace /////////////////////////////////////////////////////////////////////////////// // DatabaseOpenInfoView, public: DatabaseOpenInfoView::DatabaseOpenInfoView() - : host_value_field_(NULL), - database_name_value_field_(NULL) { -} - -DatabaseOpenInfoView::~DatabaseOpenInfoView() { + : GenericInfoView(ARRAYSIZE(kInfoLabelIds), kInfoLabelIds) { } void DatabaseOpenInfoView::SetFields(const std::string& host, - const string16& database_name) { - host_value_field_->SetText(UTF8ToWide(host)); - database_name_value_field_->SetText(database_name); - EnableDisplay(true); -} - -void DatabaseOpenInfoView::EnableDisplay(bool enabled) { - host_value_field_->SetEnabled(enabled); - database_name_value_field_->SetEnabled(enabled); -} - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseOpenInfoView, views::View overrides: - -void DatabaseOpenInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseOpenInfoView, private: - -void DatabaseOpenInfoView::Init() { - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kDatabaseOpenInfoViewBorderSize, border_color); - set_border(border); - - views::Label* host_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_DOMAIN_LABEL)); - host_value_field_ = new views::Textfield; - views::Label* database_name_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_NAME)); - database_name_value_field_ = new views::Textfield; - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kDatabaseOpenInfoViewInsetSize, - kDatabaseOpenInfoViewInsetSize, - kDatabaseOpenInfoViewInsetSize, - kDatabaseOpenInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, three_column_layout_id); - layout->AddView(host_label); - layout->AddView(host_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(database_name_label); - layout->AddView(database_name_value_field_); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - host_value_field_->SetReadOnly(true); - host_value_field_->RemoveBorder(); - host_value_field_->SetBackgroundColor(text_area_background); - database_name_value_field_->SetReadOnly(true); - database_name_value_field_->RemoveBorder(); - database_name_value_field_->SetBackgroundColor(text_area_background); + const string16& database_name, + const string16& display_name, + unsigned long estimated_size) { + string16 url = UTF8ToUTF16(host); + string16 size = FormatBytes(estimated_size, + GetByteDisplayUnits(estimated_size), + true); + int row = 0; + SetValue(row++, url); + SetValue(row++, database_name); + SetValue(row++, display_name); + SetValue(row++, size); } - diff --git a/chrome/browser/views/database_open_info_view.h b/chrome/browser/views/database_open_info_view.h index 84954f5..63d24e2 100644 --- a/chrome/browser/views/database_open_info_view.h +++ b/chrome/browser/views/database_open_info_view.h @@ -5,47 +5,25 @@ #ifndef CHROME_BROWSER_VIEWS_DATABASE_OPEN_INFO_VIEW_H_ #define CHROME_BROWSER_VIEWS_DATABASE_OPEN_INFO_VIEW_H_ -#include <string> -#include <vector> - #include "base/string16.h" -#include "views/view.h" - -namespace views { -class Label; -class Textfield; -} +#include "chrome/browser/views/generic_info_view.h" /////////////////////////////////////////////////////////////////////////////// // DatabaseOpenInfoView // // Responsible for displaying a tabular grid of Database information when // prompting for permission to open a new database. -class DatabaseOpenInfoView : public views::View { +class DatabaseOpenInfoView : public GenericInfoView { public: DatabaseOpenInfoView(); - virtual ~DatabaseOpenInfoView(); // Update the display from the specified Database data. void SetFields(const std::string& host, - const string16& database_name); - - // Enables or disables the local storate property text fields. - void EnableDisplay(bool enabled); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); + const string16& database_name, + const string16& display_name, + unsigned long estimated_size); private: - // Set up the view layout - void Init(); - - // Individual property labels - views::Textfield* host_value_field_; - views::Textfield* database_name_value_field_; - DISALLOW_COPY_AND_ASSIGN(DatabaseOpenInfoView); }; diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 41c8f4d..67fc00f 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -2115,6 +2115,15 @@ IPC_BEGIN_MESSAGES(ViewHost) // ViewMsg_CSSInsertRequest message and css has been inserted into the frame. IPC_MESSAGE_ROUTED0(ViewHostMsg_OnCSSInserted) + // Sent by the renderer process to check whether access to web databases is + // granted by content settings. This may block and trigger a cookie prompt. + IPC_SYNC_MESSAGE_ROUTED4_1(ViewHostMsg_AllowDatabase, + std::string /* origin_url */, + string16 /* database name */, + string16 /* database display name */, + unsigned long /* estimated size */, + bool /* result */) + // Asks the browser process to open a DB file with the given name IPC_MESSAGE_CONTROL3(ViewHostMsg_DatabaseOpenFile, string16 /* vfs file name */, diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index 81636c7..c40ef64 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -313,6 +313,7 @@ bool RenderThread::Send(IPC::Message* msg) { case ViewHostMsg_GetRawCookies::ID: case ViewHostMsg_DOMStorageSetItem::ID: case ViewHostMsg_SyncLoad::ID: + case ViewHostMsg_AllowDatabase::ID: may_show_cookie_prompt = true; pumping_events = true; break; diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index d8506c3..6c8b8a2 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2936,6 +2936,21 @@ bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) { return false; // Other protocols fall through here. } +bool RenderView::allowDatabase( + WebFrame* frame, const WebString& name, const WebString& display_name, + unsigned long estimated_size) { + WebSecurityOrigin origin = frame->securityOrigin(); + if (origin.isEmpty()) + return false; // Uninitialized document? + + bool result; + if (!Send(new ViewHostMsg_AllowDatabase(routing_id_, + origin.toString().utf8(), name, display_name, estimated_size, &result))) + return false; + if (!result) + DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES); + return result; +} void RenderView::didNotAllowScript(WebKit::WebFrame* frame) { DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT); } diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 370b92d..b057a9a 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -375,6 +375,9 @@ class RenderView : public RenderWidget, virtual void didRunInsecureContent( WebKit::WebFrame* frame, const WebKit::WebSecurityOrigin& origin); virtual bool allowScript(WebKit::WebFrame* frame, bool enabled_per_settings); + virtual bool allowDatabase( + WebKit::WebFrame* frame, const WebKit::WebString& name, + const WebKit::WebString& display_name, unsigned long estimated_size); virtual void didNotAllowScript(WebKit::WebFrame* frame); virtual void didNotAllowPlugins(WebKit::WebFrame* frame); virtual void didExhaustMemoryAvailableForScript(WebKit::WebFrame* frame); |