Diff
Modified: trunk/Source/WebCore/ChangeLog (109824 => 109825)
--- trunk/Source/WebCore/ChangeLog 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebCore/ChangeLog 2012-03-06 01:33:34 UTC (rev 109825)
@@ -1,3 +1,22 @@
+2012-03-05 Joshua Bell <jsb...@chromium.org>
+
+ IndexedDB: Handle LevelDB database corruption
+ https://bugs.webkit.org/show_bug.cgi?id=79413
+
+ Add LevelDBDatabase::destroy() method so that clients can retry if open() fails.
+
+ Reviewed by Tony Chang.
+
+ Test: webkit_unit_tests --gtest_filter='LevelDBDatabaseTest.CorruptionTest'
+
+ * Modules/indexeddb/IDBLevelDBBackingStore.cpp: Implement open/destroy/open strategy.
+ (WebCore::IDBLevelDBBackingStore::open):
+ * platform/leveldb/LevelDBDatabase.cpp:
+ (WebCore::LevelDBDatabase::destroy):
+ (WebCore):
+ * platform/leveldb/LevelDBDatabase.h:
+ (LevelDBDatabase):
+
2012-03-05 Stephen Chenney <schen...@chromium.org>
[Chromium] SVG Composite of Offset crashes
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp (109824 => 109825)
--- trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp 2012-03-06 01:33:34 UTC (rev 109825)
@@ -150,6 +150,22 @@
String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb");
db = LevelDBDatabase::open(path, comparator.get());
+
+ if (!db) {
+ LOG_ERROR("IndexedDB backing store open failed, attempting cleanup");
+ bool success = LevelDBDatabase::destroy(path);
+ if (!success) {
+ LOG_ERROR("IndexedDB backing store cleanup failed");
+ return PassRefPtr<IDBBackingStore>();
+ }
+
+ LOG_ERROR("IndexedDB backing store cleanup succeeded, reopening");
+ db = LevelDBDatabase::open(path, comparator.get());
+ if (!db) {
+ LOG_ERROR("IndexedDB backing store reopen after recovery failed");
+ return PassRefPtr<IDBBackingStore>();
+ }
+ }
}
if (!db)
Modified: trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp (109824 => 109825)
--- trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp 2012-03-06 01:33:34 UTC (rev 109825)
@@ -112,6 +112,13 @@
return leveldb::DB::Open(options, path.utf8().data(), db);
}
+bool LevelDBDatabase::destroy(const String& fileName)
+{
+ leveldb::Options options;
+ const leveldb::Status s = leveldb::DestroyDB(fileName.utf8().data(), options);
+ return s.ok();
+}
+
PassOwnPtr<LevelDBDatabase> LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator)
{
OwnPtr<ComparatorAdapter> comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator));
Modified: trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.h (109824 => 109825)
--- trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.h 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.h 2012-03-06 01:33:34 UTC (rev 109825)
@@ -50,6 +50,7 @@
public:
static PassOwnPtr<LevelDBDatabase> open(const String& fileName, const LevelDBComparator*);
static PassOwnPtr<LevelDBDatabase> openInMemory(const LevelDBComparator*);
+ static bool destroy(const String& fileName);
~LevelDBDatabase();
bool put(const LevelDBSlice& key, const Vector<char>& value);
Modified: trunk/Source/WebKit/chromium/ChangeLog (109824 => 109825)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-03-06 01:33:34 UTC (rev 109825)
@@ -1,3 +1,19 @@
+2012-03-05 Joshua Bell <jsb...@chromium.org>
+
+ IndexedDB: Handle LevelDB database corruption
+ https://bugs.webkit.org/show_bug.cgi?id=79413
+
+ Reviewed by Tony Chang.
+
+ * WebKit.gypi:
+ * tests/LevelDBTest.cpp: Added.
+ (WebCore):
+ (SimpleComparator):
+ (WebCore::SimpleComparator::compare):
+ (WebCore::SimpleComparator::name):
+ (WebCore::encodeString):
+ (WebCore::TEST):
+
2012-03-05 Min Qin <qin...@google.com>
Enable context menu on android
Modified: trunk/Source/WebKit/chromium/WebKit.gypi (109824 => 109825)
--- trunk/Source/WebKit/chromium/WebKit.gypi 2012-03-06 01:18:42 UTC (rev 109824)
+++ trunk/Source/WebKit/chromium/WebKit.gypi 2012-03-06 01:33:34 UTC (rev 109825)
@@ -105,6 +105,7 @@
'tests/KURLTest.cpp',
'tests/LayerChromiumTest.cpp',
'tests/LayerTextureUpdaterTest.cpp',
+ 'tests/LevelDBTest.cpp',
'tests/PaintAggregatorTest.cpp',
'tests/PODArenaTest.cpp',
'tests/PODIntervalTreeTest.cpp',
Added: trunk/Source/WebKit/chromium/tests/LevelDBTest.cpp (0 => 109825)
--- trunk/Source/WebKit/chromium/tests/LevelDBTest.cpp (rev 0)
+++ trunk/Source/WebKit/chromium/tests/LevelDBTest.cpp 2012-03-06 01:33:34 UTC (rev 109825)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(LEVELDB)
+
+#include "FileSystem.h"
+#include "LevelDBComparator.h"
+#include "LevelDBDatabase.h"
+#include "LevelDBSlice.h"
+#include <gtest/gtest.h>
+#include <webkit/support/webkit_support.h>
+#include <wtf/Vector.h>
+
+using namespace WebCore;
+
+namespace {
+
+class SimpleComparator : public LevelDBComparator {
+public:
+ virtual int compare(const LevelDBSlice& a, const LevelDBSlice& b) const OVERRIDE
+ {
+ size_t len = std::min(a.end() - a.begin(), b.end() - b.begin());
+ return memcmp(a.begin(), b.begin(), len);
+ }
+ virtual const char* name() const OVERRIDE { return "temp_comparator"; }
+};
+
+Vector<char> encodeString(const std::string& s)
+{
+ Vector<char> ret(s.size());
+ for (size_t i = 0; i < s.size(); ++i)
+ ret.append(s[i]);
+ return ret;
+}
+
+TEST(LevelDBDatabaseTest, CorruptionTest)
+{
+ OwnPtr<webkit_support::ScopedTempDirectory> tempDirectory = adoptPtr(webkit_support::CreateScopedTempDirectory());
+ tempDirectory->CreateUniqueTempDir();
+ const char* path = tempDirectory->path().c_str();
+
+ const Vector<char> key = encodeString("key");
+ const Vector<char> putValue = encodeString("value");
+ Vector<char> gotValue;
+ SimpleComparator comparator;
+
+ OwnPtr<LevelDBDatabase> leveldb = LevelDBDatabase::open(path, &comparator);
+ EXPECT_TRUE(leveldb);
+ bool success = leveldb->put(key, putValue);
+ EXPECT_TRUE(success);
+ leveldb.release();
+ EXPECT_FALSE(leveldb);
+
+ leveldb = LevelDBDatabase::open(path, &comparator);
+ EXPECT_TRUE(leveldb);
+ success = leveldb->get(key, gotValue);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(putValue, gotValue);
+ leveldb.release();
+ EXPECT_FALSE(leveldb);
+
+ String filepath = pathByAppendingComponent(path, "CURRENT");
+ PlatformFileHandle handle = openFile(filepath, OpenForWrite);
+ truncateFile(handle, 0);
+ closeFile(handle);
+
+ leveldb = LevelDBDatabase::open(path, &comparator);
+ EXPECT_FALSE(leveldb);
+
+ bool destroyed = LevelDBDatabase::destroy(path);
+ EXPECT_TRUE(destroyed);
+
+ leveldb = LevelDBDatabase::open(path, &comparator);
+ EXPECT_TRUE(leveldb);
+ success = leveldb->get(key, gotValue);
+ EXPECT_FALSE(success);
+}
+
+} // namespace
+
+#endif // USE(LEVELDB)