summaryrefslogtreecommitdiffstats
path: root/content/browser/indexed_db
diff options
context:
space:
mode:
authorjsbell <jsbell@chromium.org>2015-08-27 10:58:27 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-27 17:59:12 +0000
commit341d55881371d22a54560f045cf899034c6c6833 (patch)
tree17c58716c49160210ba68971053a9e72e04bc1f0 /content/browser/indexed_db
parent49fc7de366a895b19916c00ab5286be6ab1a569c (diff)
downloadchromium_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')
-rw-r--r--content/browser/indexed_db/indexed_db_browsertest.cc27
-rw-r--r--content/browser/indexed_db/indexed_db_class_factory.cc8
-rw-r--r--content/browser/indexed_db/indexed_db_class_factory.h10
-rw-r--r--content/browser/indexed_db/indexed_db_database.cc15
-rw-r--r--content/browser/indexed_db/indexed_db_database.h17
-rw-r--r--content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc26
-rw-r--r--content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h7
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,