Title: [104310] branches/chromium/963
- Revision
- 104310
- Author
- [email protected]
- Date
- 2012-01-06 11:53:50 -0800 (Fri, 06 Jan 2012)
Log Message
Merge 104252 - Source/WebCore: IndexedDB: fix cursor prefetch crash
http://crbug.com/108071
https://bugs.webkit.org/show_bug.cgi?id=75596
Reviewed by Tony Chang.
Test: storage/indexeddb/prefetch-bugfix-108071.html
Note: DumpRenderTree doesn't exercise the bug, it only occurs in
multi-process chromium. The layout test will soon be run as a
chromium ui test: http://codereview.chromium.org/9108004
* storage/IDBCursorBackendImpl.cpp:
(WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl):
(WebCore::IDBCursorBackendImpl::~IDBCursorBackendImpl): Destroy
cursors before their objectstores.
(WebCore::IDBCursorBackendImpl::prefetchReset): Don't run continue if
the cursor is closed.
(WebCore::IDBCursorBackendImpl::close): Set a closed flag.
* storage/IDBCursorBackendImpl.h:
LayoutTests: IndexedDB: fix cursor prefetch crash
https://bugs.webkit.org/show_bug.cgi?id=75596
Reviewed by Tony Chang.
* storage/indexeddb/prefetch-bugfix-108071-expected.txt: Added.
* storage/indexeddb/prefetch-bugfix-108071.html: Added.
[email protected]
Review URL: http://codereview.chromium.org/9121008
Modified Paths
Added Paths
Diff
Copied: branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071-expected.txt (from rev 104252, trunk/LayoutTests/storage/indexeddb/prefetch-bugfix-108071-expected.txt) (0 => 104310)
--- branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071-expected.txt (rev 0)
+++ branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071-expected.txt 2012-01-06 19:53:50 UTC (rev 104310)
@@ -0,0 +1,54 @@
+Test for crbug.com/108071
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
+PASS indexedDB == null is false
+indexedDB.deleteDatabase(DBNAME)
+indexedDB.open(DBNAME)
+db = event.target.result
+db.setVersion('new version')
+setVersionSuccess():
+trans = event.target.result
+PASS trans !== null is true
+objectStore = db.createObjectStore('store', {keyPath: 'id'})
+
+resetObjectStore():
+objectStore.clear()
+objectStore.add({id: 0, name: "Alpha"})
+objectStore.add({id: 1, name: "Bravo"})
+objectStore.add({id: 2, name: "Charlie"})
+objectStore.add({id: 3, name: "Delta"})
+objectStore.add({id: 4, name: "Echo"})
+
+iterateAndDeleteFirstElement():
+trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
+trans.objectStore('store').openCursor()
+0: Alpha
+trans.objectStore('store').delete(0)
+1: Bravo
+2: Charlie
+3: Delta
+4: Echo
+
+resetObjectStore():
+objectStore.clear()
+objectStore.add({id: 0, name: "Alpha"})
+objectStore.add({id: 1, name: "Bravo"})
+objectStore.add({id: 2, name: "Charlie"})
+objectStore.add({id: 3, name: "Delta"})
+objectStore.add({id: 4, name: "Echo"})
+
+prefetchAndAbort():
+trans.objectStore('store').openCursor()
+0: Alpha
+1: Bravo
+2: Charlie
+3: Delta
+trans.abort()
+PASS Transaction aborted as expected
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071.html (from rev 104252, trunk/LayoutTests/storage/indexeddb/prefetch-bugfix-108071.html) (0 => 104310)
--- branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071.html (rev 0)
+++ branches/chromium/963/LayoutTests/storage/indexeddb/prefetch-bugfix-108071.html 2012-01-06 19:53:50 UTC (rev 104310)
@@ -0,0 +1,130 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("Test for crbug.com/108071");
+
+// Have to be at least 5 here: 1 initial, 3 continues to trigger prefetch and 1
+// post-abort outstanding continue.
+var names = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo'];
+
+function test()
+{
+ indexedDB = evalAndLog("indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;");
+ shouldBeFalse("indexedDB == null");
+ DBNAME = 'prefetch-bugfix-108071';
+ request = evalAndLog("indexedDB.deleteDatabase(DBNAME)");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onblocked_ = unexpectedBlockedCallback;
+ request._onsuccess_ = function (e) {
+ request = evalAndLog("indexedDB.open(DBNAME)");
+ request._onsuccess_ = openSuccess;
+ request._onerror_ = unexpectedErrorCallback;
+ };
+}
+
+function openSuccess()
+{
+ var db = evalAndLog("db = event.target.result");
+
+ request = evalAndLog("db.setVersion('new version')");
+ request._onsuccess_ = setVersionSuccess;
+ request._onerror_ = unexpectedErrorCallback;
+}
+
+function setVersionSuccess()
+{
+ debug("setVersionSuccess():");
+ window.trans = evalAndLog("trans = event.target.result");
+ shouldBeTrue("trans !== null");
+ trans._onabort_ = unexpectedAbortCallback;
+ trans._oncomplete_ = iterateAndDeleteFirstElement;
+
+ var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})");
+ resetObjectStore();
+}
+
+function resetObjectStore()
+{
+ debug("\nresetObjectStore():");
+
+ objectStore = trans.objectStore('store');
+ evalAndLog("objectStore.clear()");
+ for (i = 0; i < names.length; i++) {
+ request = evalAndLog("objectStore.add({id: " + i + ", name: \"" + names[i] + "\"})");
+ request._onerror_ = unexpectedErrorCallback;
+ }
+
+ debug("");
+}
+
+function iterateAndDeleteFirstElement()
+{
+ debug("iterateAndDeleteFirstElement():");
+
+ evalAndLog("trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");
+ trans._onabort_ = transactionAborted;
+ trans._oncomplete_ = unexpectedCompleteCallback;
+
+ // Create the cursor and iterate over the whole thing.
+ request = evalAndLog("trans.objectStore('store').openCursor()");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = function () {
+ var cursor = event.target.result;
+ if (cursor == null) {
+ resetObjectStore();
+ prefetchAndAbort();
+ return;
+ }
+
+ debug(cursor.value.id + ": " + cursor.value.name);
+
+ if (cursor.value.id == 0) {
+ // Delete the first element when we see it.
+ request = evalAndLog("trans.objectStore('store').delete(0)");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = function() { cursor.continue(); };
+ } else {
+ cursor.continue();
+ }
+ }
+}
+
+function prefetchAndAbort()
+{
+ debug("prefetchAndAbort():");
+
+ request = evalAndLog("trans.objectStore('store').openCursor()");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = function () {
+ var cursor = event.target.result;
+ debug(cursor.value.id + ": " + cursor.value.name);
+ // Have to iterate to 3 in order to prefetch, but can't iterate past 3
+ // so that there will be a continue remaining.
+ if (cursor.value.id == 3) {
+ evalAndLog("trans.abort()");
+ } else {
+ cursor.continue();
+ }
+ }
+}
+
+function transactionAborted()
+{
+ testPassed("Transaction aborted as expected");
+ finishJSTest();
+}
+
+var jsTestIsAsync = true;
+test();
+
+</script>
+<script src=""
+</body>
+</html>
Modified: branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.cpp (104309 => 104310)
--- branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.cpp 2012-01-06 19:52:18 UTC (rev 104309)
+++ branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.cpp 2012-01-06 19:53:50 UTC (rev 104310)
@@ -47,6 +47,7 @@
, m_cursorType(cursorType)
, m_transaction(transaction)
, m_objectStore(objectStore)
+ , m_closed(false)
{
m_transaction->registerOpenCursor(this);
}
@@ -54,6 +55,11 @@
IDBCursorBackendImpl::~IDBCursorBackendImpl()
{
m_transaction->unregisterOpenCursor(this);
+ // Order is important, the cursors have to be destructed before the objectStore.
+ m_cursor.clear();
+ m_savedCursor.clear();
+
+ m_objectStore.clear();
}
unsigned short IDBCursorBackendImpl::direction() const
@@ -174,6 +180,8 @@
m_cursor = m_savedCursor;
m_savedCursor = 0;
+ if (m_closed)
+ return;
if (m_cursor) {
for (int i = 0; i < usedPrefetches; ++i) {
bool ok = m_cursor->continueFunction();
@@ -184,6 +192,7 @@
void IDBCursorBackendImpl::close()
{
+ m_closed = true;
if (m_cursor)
m_cursor->close();
}
Modified: branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.h (104309 => 104310)
--- branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.h 2012-01-06 19:52:18 UTC (rev 104309)
+++ branches/chromium/963/Source/WebCore/storage/IDBCursorBackendImpl.h 2012-01-06 19:53:50 UTC (rev 104310)
@@ -78,6 +78,8 @@
CursorType m_cursorType;
RefPtr<IDBTransactionBackendInterface> m_transaction;
RefPtr<IDBObjectStoreBackendInterface> m_objectStore;
+
+ bool m_closed;
};
} // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes