diff options
author | jsbell <jsbell@chromium.org> | 2015-08-27 10:58:27 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-27 17:59:12 +0000 |
commit | 341d55881371d22a54560f045cf899034c6c6833 (patch) | |
tree | 17c58716c49160210ba68971053a9e72e04bc1f0 /content/browser/indexed_db | |
parent | 49fc7de366a895b19916c00ab5286be6ab1a569c (diff) | |
download | chromium_src-341d55881371d22a54560f045cf899034c6c6833.zip chromium_src-341d55881371d22a54560f045cf899034c6c6833.tar.gz chromium_src-341d55881371d22a54560f045cf899034c6c6833.tar.bz2 |
IndexedDB: Make getAll() requests fail if result exceeds IPC limits
The (experimental) IDBObjectStore/IDBIndex.getAll()/getAllKeys()
methods can return an arbitrary number of results. When the resulting
payload would exceed the IPC message, fail the request with an
UnknownError per discussion w/ Moz.
BUG=478949
R=cmumford@chromium.org
Review URL: https://codereview.chromium.org/1321583002
Cr-Commit-Position: refs/heads/master@{#345920}
Diffstat (limited to 'content/browser/indexed_db')
7 files changed, 89 insertions, 21 deletions
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index b0097ed..ff400ec 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc @@ -187,6 +187,16 @@ class IndexedDBBrowserTest : public ContentBrowserTest { DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); }; +class IndexedDBBrowserTestWithExperimentalAPIs + : public IndexedDBBrowserTest, + public ::testing::WithParamInterface<const char*> { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); + } +}; + IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) { SimpleTest(GetTestUrl("indexeddb", "cursor_test.html")); } @@ -232,6 +242,11 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CallbackAccounting) { SimpleTest(GetTestUrl("indexeddb", "callback_accounting.html")); } +IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithExperimentalAPIs, + GetAllMaxMessageSize) { + SimpleTest(GetTestUrl("indexeddb", "getall_max_message_size.html")); +} + IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DoesntHangTest) { SimpleTest(GetTestUrl("indexeddb", "transaction_run_forever.html")); CrashTab(shell()->web_contents()); @@ -679,16 +694,8 @@ static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( } // namespace -class IndexedDBBrowserCorruptionTest - : public IndexedDBBrowserTest, - public ::testing::WithParamInterface<const char*> { - public: - void SetUpCommandLine(base::CommandLine* command_line) override { - // Experimental for IDBObjectStore.getAll() - command_line->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - } -}; +// Experimental for IDBObjectStore.getAll() +using IndexedDBBrowserCorruptionTest = IndexedDBBrowserTestWithExperimentalAPIs; IN_PROC_BROWSER_TEST_P(IndexedDBBrowserCorruptionTest, OperationOnCorruptedOpenDatabase) { diff --git a/content/browser/indexed_db/indexed_db_class_factory.cc b/content/browser/indexed_db/indexed_db_class_factory.cc index 284b40c..cb77cca 100644 --- a/content/browser/indexed_db/indexed_db_class_factory.cc +++ b/content/browser/indexed_db/indexed_db_class_factory.cc @@ -24,6 +24,14 @@ IndexedDBClassFactory* IndexedDBClassFactory::Get() { return s_factory.Pointer(); } +IndexedDBDatabase* IndexedDBClassFactory::CreateIndexedDBDatabase( + const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const IndexedDBDatabase::Identifier& unique_identifier) { + return new IndexedDBDatabase(name, backing_store, factory, unique_identifier); +} + IndexedDBTransaction* IndexedDBClassFactory::CreateIndexedDBTransaction( int64 id, scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, diff --git a/content/browser/indexed_db/indexed_db_class_factory.h b/content/browser/indexed_db/indexed_db_class_factory.h index 2fe0089..b2d2026 100644 --- a/content/browser/indexed_db/indexed_db_class_factory.h +++ b/content/browser/indexed_db/indexed_db_class_factory.h @@ -10,6 +10,7 @@ #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" +#include "content/browser/indexed_db/indexed_db_database.h" #include "content/common/content_export.h" #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" @@ -19,8 +20,9 @@ class Iterator; namespace content { -class IndexedDBDatabase; +class IndexedDBBackingStore; class IndexedDBDatabaseCallbacks; +class IndexedDBFactory; class IndexedDBTransaction; class LevelDBDatabase; class LevelDBIteratorImpl; @@ -36,6 +38,12 @@ class CONTENT_EXPORT IndexedDBClassFactory { static void SetIndexedDBClassFactoryGetter(GetterCallback* cb); + virtual IndexedDBDatabase* CreateIndexedDBDatabase( + const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const IndexedDBDatabase::Identifier& unique_identifier); + virtual IndexedDBTransaction* CreateIndexedDBTransaction( int64 id, scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 8628768..31d0e69 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc @@ -132,7 +132,8 @@ scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( const Identifier& unique_identifier, leveldb::Status* s) { scoped_refptr<IndexedDBDatabase> database = - new IndexedDBDatabase(name, backing_store, factory, unique_identifier); + IndexedDBClassFactory::Get()->CreateIndexedDBDatabase( + name, backing_store, factory, unique_identifier); *s = database->OpenInternal(); if (s->ok()) return database; @@ -227,6 +228,10 @@ IndexedDBDatabase::~IndexedDBDatabase() { DCHECK(pending_delete_calls_.empty()); } +size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { + return kMaxIDBMessageSizeInBytes; +} + scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, int child_process_id) { @@ -853,9 +858,11 @@ void IndexedDBDatabase::GetAllOperation( response_size += return_key.size_estimate(); else response_size += return_value.SizeEstimate(); - if (response_size > IPC::Channel::kMaximumMessageSize) { - // TODO(cmumford): Reach this limit more gracefully (crbug.com/478949) - break; + if (response_size > GetMaxMessageSizeInBytes()) { + callbacks->OnError( + IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, + "Maximum IPC message size exceeded.")); + return; } if (cursor_type == indexed_db::CURSOR_KEY_ONLY) diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index d9e7f66..66bfe5d 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h @@ -235,8 +235,19 @@ class CONTENT_EXPORT IndexedDBDatabase scoped_refptr<IndexedDBCallbacks> callbacks, IndexedDBTransaction* transaction); + protected: + IndexedDBDatabase(const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const Identifier& unique_identifier); + virtual ~IndexedDBDatabase(); + + // May be overridden in tests. + virtual size_t GetMaxMessageSizeInBytes() const; + private: friend class base::RefCounted<IndexedDBDatabase>; + friend class IndexedDBClassFactory; class PendingDeleteCall; class PendingSuccessCall; @@ -247,12 +258,6 @@ class CONTENT_EXPORT IndexedDBDatabase typedef std::list<PendingDeleteCall*> PendingDeleteCallList; typedef list_set<IndexedDBConnection*> ConnectionSet; - IndexedDBDatabase(const base::string16& name, - IndexedDBBackingStore* backing_store, - IndexedDBFactory* factory, - const Identifier& unique_identifier); - ~IndexedDBDatabase(); - bool IsOpenConnectionBlocked() const; leveldb::Status OpenInternal(); void RunVersionChangeTransaction(scoped_refptr<IndexedDBCallbacks> callbacks, diff --git a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc index 4349ee2..dc02ff7 100644 --- a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc +++ b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc @@ -41,6 +41,22 @@ class FunctionTracer { namespace content { +class IndexedDBTestDatabase : public IndexedDBDatabase { + public: + IndexedDBTestDatabase(const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const IndexedDBDatabase::Identifier& unique_identifier) + : IndexedDBDatabase(name, backing_store, factory, unique_identifier) {} + + protected: + ~IndexedDBTestDatabase() override {} + + size_t GetMaxMessageSizeInBytes() const override { + return 10 * 1024 * 1024; // 10MB + } +}; + class IndexedDBTestTransaction : public IndexedDBTransaction { public: IndexedDBTestTransaction( @@ -234,6 +250,16 @@ MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory() MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() { } +IndexedDBDatabase* +MockBrowserTestIndexedDBClassFactory::CreateIndexedDBDatabase( + const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const IndexedDBDatabase::Identifier& unique_identifier) { + return new IndexedDBTestDatabase(name, backing_store, factory, + unique_identifier); +} + IndexedDBTransaction* MockBrowserTestIndexedDBClassFactory::CreateIndexedDBTransaction( int64 id, diff --git a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h index 1ce5c0e..1b77071 100644 --- a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h +++ b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" +#include "content/browser/indexed_db/indexed_db_database.h" #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" namespace content { @@ -36,6 +37,12 @@ class MockBrowserTestIndexedDBClassFactory : public IndexedDBClassFactory { public: MockBrowserTestIndexedDBClassFactory(); ~MockBrowserTestIndexedDBClassFactory() override; + + IndexedDBDatabase* CreateIndexedDBDatabase( + const base::string16& name, + IndexedDBBackingStore* backing_store, + IndexedDBFactory* factory, + const IndexedDBDatabase::Identifier& unique_identifier) override; IndexedDBTransaction* CreateIndexedDBTransaction( int64 id, scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, |