[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

jorlow at chromium.org jorlow at chromium.org
Wed Dec 22 14:57:53 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 2a9553e668c47e6797c87cf4d2f2c6d8314ed0fa
Author: jorlow at chromium.org <jorlow at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 26 17:03:59 2010 +0000

    2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
    
            Reviewed by Steve Block.
    
            Fix IndexedDB crashes
            https://bugs.webkit.org/show_bug.cgi?id=48266
    
            Test all the changes made in WebCore.
    
            * storage/indexeddb/constants-expected.txt:
            * storage/indexeddb/constants.html:
            * storage/indexeddb/database-quota-expected.txt:
            * storage/indexeddb/index-basics-expected.txt:
            * storage/indexeddb/index-basics.html:
            * storage/indexeddb/index-cursor-expected.txt:
            * storage/indexeddb/index-cursor.html:
            * storage/indexeddb/keyrange-expected.txt:
            * storage/indexeddb/keyrange.html:
            * storage/indexeddb/objectstore-basics-expected.txt:
            * storage/indexeddb/objectstore-basics.html:
            * storage/indexeddb/objectstore-cursor-expected.txt:
            * storage/indexeddb/objectstore-cursor.html:
            * storage/indexeddb/open-cursor-expected.txt:
            * storage/indexeddb/open-cursor.html:
    2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
    
            Reviewed by Steve Block.
            Fix IndexedDB crashes
            https://bugs.webkit.org/show_bug.cgi?id=48266
    
            If IDBKey returns null, type conversion failed. Handle this case
            in the bindings.
    
            Change UNKNOWN_ERR to be 1 since 0 is hard coded to mean no error.
            This is just a stop-gap move until we get it figured out in standards
            land.
    
            IDBObjectStore needs to handle null ranges.
    
            It's actually OK for m_transaction to be non-null when hitting the
            destructor. We just need to then remove it from the set of pending
            transactions.
    
            The transaction can become aborted in the middle of processing a
            list of tasks. Fix this.
    
            All changes (except the last 2 races) are tested in LayoutTests.
            I couldn't find a way to reliably reproduce the races.
    
            * bindings/scripts/CodeGeneratorV8.pm:
            * bindings/scripts/test/V8/V8TestObj.cpp:
            (WebCore::TestObjInternal::idbKeyCallback):
            * bindings/v8/IDBBindingUtilities.cpp:
            (WebCore::createIDBKeyFromValue):
            * storage/IDBDatabaseException.h:
            * storage/IDBDatabaseException.idl:
            * storage/IDBObjectStoreBackendImpl.cpp:
            (WebCore::IDBObjectStoreBackendImpl::openCursorInternal):
            * storage/IDBRequest.cpp:
            (WebCore::IDBRequest::~IDBRequest):
            (WebCore::IDBRequest::timerFired):
            * storage/IDBTransactionBackendImpl.cpp:
            (WebCore::IDBTransactionBackendImpl::taskTimerFired):
    2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
    
            Reviewed by Steve Block.
    
            Fix IndexedDB crashes
            https://bugs.webkit.org/show_bug.cgi?id=48266
    
            Make WebIDBObjectStoreImpl match the way that WebIDBIndexImpl passes
            in cursor parameters (which is the correct way). KeyRange knows how
            to convert itself to a WebCore type--even if the value is null.
    
            * src/WebIDBObjectStoreImpl.cpp:
            (WebKit::WebIDBObjectStoreImpl::openCursor):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70531 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7119778..e3b3e09 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,28 @@
+2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
+
+        Reviewed by Steve Block.
+
+        Fix IndexedDB crashes
+        https://bugs.webkit.org/show_bug.cgi?id=48266
+
+        Test all the changes made in WebCore.
+
+        * storage/indexeddb/constants-expected.txt:
+        * storage/indexeddb/constants.html:
+        * storage/indexeddb/database-quota-expected.txt:
+        * storage/indexeddb/index-basics-expected.txt:
+        * storage/indexeddb/index-basics.html:
+        * storage/indexeddb/index-cursor-expected.txt:
+        * storage/indexeddb/index-cursor.html:
+        * storage/indexeddb/keyrange-expected.txt:
+        * storage/indexeddb/keyrange.html:
+        * storage/indexeddb/objectstore-basics-expected.txt:
+        * storage/indexeddb/objectstore-basics.html:
+        * storage/indexeddb/objectstore-cursor-expected.txt:
+        * storage/indexeddb/objectstore-cursor.html:
+        * storage/indexeddb/open-cursor-expected.txt:
+        * storage/indexeddb/open-cursor.html:
+
 2010-10-26  Adam Roben  <aroben at apple.com>
 
         Land expected Windows results for new vertical text tests
diff --git a/LayoutTests/storage/indexeddb/constants-expected.txt b/LayoutTests/storage/indexeddb/constants-expected.txt
index 15a2df7..8f53b56 100644
--- a/LayoutTests/storage/indexeddb/constants-expected.txt
+++ b/LayoutTests/storage/indexeddb/constants-expected.txt
@@ -8,7 +8,7 @@ PASS webkitIDBKeyRange.LEFT_OPEN is 1
 PASS webkitIDBKeyRange.RIGHT_OPEN is 2
 PASS webkitIDBKeyRange.LEFT_BOUND is 4
 PASS webkitIDBKeyRange.RIGHT_BOUND is 8
-PASS webkitIDBDatabaseException.UNKNOWN_ERR is 0
+PASS webkitIDBDatabaseException.UNKNOWN_ERR is 1
 PASS webkitIDBDatabaseException.NON_TRANSIENT_ERR is 1
 PASS webkitIDBDatabaseException.NOT_FOUND_ERR is 2
 PASS webkitIDBDatabaseException.CONSTRAINT_ERR is 3
diff --git a/LayoutTests/storage/indexeddb/constants.html b/LayoutTests/storage/indexeddb/constants.html
index 813fe7a..9cdf4c4 100644
--- a/LayoutTests/storage/indexeddb/constants.html
+++ b/LayoutTests/storage/indexeddb/constants.html
@@ -22,7 +22,7 @@ function test()
     shouldBe("webkitIDBKeyRange.LEFT_BOUND", "4");
     shouldBe("webkitIDBKeyRange.RIGHT_BOUND", "8");
 
-    shouldBe("webkitIDBDatabaseException.UNKNOWN_ERR", "0");
+    shouldBe("webkitIDBDatabaseException.UNKNOWN_ERR", "1");
     shouldBe("webkitIDBDatabaseException.NON_TRANSIENT_ERR", "1");
     shouldBe("webkitIDBDatabaseException.NOT_FOUND_ERR", "2");
     shouldBe("webkitIDBDatabaseException.CONSTRAINT_ERR", "3");
diff --git a/LayoutTests/storage/indexeddb/database-quota-expected.txt b/LayoutTests/storage/indexeddb/database-quota-expected.txt
index 6c245d4..91d3ac7 100644
--- a/LayoutTests/storage/indexeddb/database-quota-expected.txt
+++ b/LayoutTests/storage/indexeddb/database-quota-expected.txt
@@ -68,7 +68,7 @@ trans = db.transaction()
 Creating 'data' which contains 64K of data
 PASS data.length is 65536
 store = trans.objectStore('test123')
-Error function called: (0) Error writing data to stable storage.
+Error function called: (1) Error writing data to stable storage.
 Error event fired:
 PASS 'result' in event is false
 PASS 'code' in event is true
diff --git a/LayoutTests/storage/indexeddb/index-basics-expected.txt b/LayoutTests/storage/indexeddb/index-basics-expected.txt
index 0869d95..f886a19 100644
--- a/LayoutTests/storage/indexeddb/index-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/index-basics-expected.txt
@@ -300,6 +300,10 @@ PASS 'readyState' in event.target is true
 PASS event.target.readyState is event.target.DONE
 
 PASS event.result === null is true
+Passing an invalid key into indexObject.get().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into indexObject.getKey().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/index-basics.html b/LayoutTests/storage/indexeddb/index-basics.html
index f7257f1..7a16c3a 100644
--- a/LayoutTests/storage/indexeddb/index-basics.html
+++ b/LayoutTests/storage/indexeddb/index-basics.html
@@ -219,6 +219,21 @@ function last()
     verifySuccessEvent(event);
     shouldBeTrue("event.result === null");
 
+    try {
+        debug("Passing an invalid key into indexObject.get().");
+        indexObject.get([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into indexObject.getKey().");
+        indexObject.getKey([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
     done();
 }
 
diff --git a/LayoutTests/storage/indexeddb/index-cursor-expected.txt b/LayoutTests/storage/indexeddb/index-cursor-expected.txt
index 88b96ff..bc01070 100644
--- a/LayoutTests/storage/indexeddb/index-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/index-cursor-expected.txt
@@ -2058,6 +2058,44 @@ PASS event.result.key is testData[7]
 PASS event.result.value is expectedIndex
 PASS event.result.key is testData[6]
 PASS event.result is null
+
+Next test: null key path sorted ascending.
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[0]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[1]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[2]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[3]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[4]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[5]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[6]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[7]
+PASS event.result is null
+
+Next test: null key path sorted descending.
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[7]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[6]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[5]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[4]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[3]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[2]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[1]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[0]
+PASS event.result is null
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/index-cursor.html b/LayoutTests/storage/indexeddb/index-cursor.html
index 5aab4f8..6a9d1ac 100644
--- a/LayoutTests/storage/indexeddb/index-cursor.html
+++ b/LayoutTests/storage/indexeddb/index-cursor.html
@@ -107,7 +107,7 @@ function scheduleTests()
 function runNextTest()
 {
     if (!scheduledTests.length) {
-        done();
+        testNullKeyRange();
         return;
     }
  
@@ -226,6 +226,38 @@ function cursorIteration()
     event.result.continue();
 }
  
+window.nullKeyRangeStep = 0;
+function testNullKeyRange()
+{
+    window.lower = 0;
+    window.lowerIsOpen = false;
+    window.upper = testData.length-1;
+    window.upperIsOpen = false;
+
+    str = "Next test: null key path ";
+    if (window.nullKeyRangeStep == 0) {
+        str += "sorted ascending.";
+        window.ascending = true;
+        window.expectedIndex = lower;
+        window.nullKeyRangeStep = 1;
+    } else if (window.nullKeyRangeStep == 1) {
+        str += "sorted descending.";
+        window.ascending = false;
+        window.expectedIndex = upper;
+        window.nullKeyRangeStep = 2;
+    } else {
+        done();
+        return;
+    }
+
+    debug("");
+    debug(str);
+ 
+    var request = indexObject.openKeyCursor(null, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
+    request.onsuccess = cursorIteration;
+    request.onerror = unexpectedErrorCallback;
+}
+ 
 openDatabase(); // The first step.
 var successfullyParsed = true;
  
diff --git a/LayoutTests/storage/indexeddb/keyrange-expected.txt b/LayoutTests/storage/indexeddb/keyrange-expected.txt
index 8d6bf86..1a7dfff 100644
--- a/LayoutTests/storage/indexeddb/keyrange-expected.txt
+++ b/LayoutTests/storage/indexeddb/keyrange-expected.txt
@@ -141,6 +141,18 @@ PASS keyRange.left is 'aaf'
 PASS keyRange.right is 'abf'
 PASS leftFlags is keyRange.LEFT_OPEN | keyRange.LEFT_BOUND
 PASS rightFlags is keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND
+Passing an invalid key into only([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into rightBound([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into leftBound([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound(null, [])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound([],null)
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound([], [])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/keyrange.html b/LayoutTests/storage/indexeddb/keyrange.html
index c3885fc..48708d9 100644
--- a/LayoutTests/storage/indexeddb/keyrange.html
+++ b/LayoutTests/storage/indexeddb/keyrange.html
@@ -112,6 +112,53 @@ function test()
     checkBoundKeyRange("'aae'", "'abe'", true, false);
     checkBoundKeyRange("'aaf'", "'abf'", true, true);
 
+    try {
+        debug("Passing an invalid key into only([])");
+        webkitIDBKeyRange.only([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into rightBound([])");
+        webkitIDBKeyRange.rightBound([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+ 
+    try {
+        debug("Passing an invalid key into leftBound([])");
+        webkitIDBKeyRange.leftBound([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into bound(null, [])");
+        webkitIDBKeyRange.bound(null, []);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into bound([],null)");
+        webkitIDBKeyRange.bound([], null);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into bound([], [])");
+        webkitIDBKeyRange.bound([], []);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
 }
 
 test();
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
index d22e6f0..a097ccf 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
@@ -176,6 +176,15 @@ PASS 'readyState' in event.target is true
 PASS event.target.readyState is event.target.DONE
 
 PASS event.result is null
+store = event.source
+Passing an invalid key into store.get().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.remove().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.add().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.put().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics.html b/LayoutTests/storage/indexeddb/objectstore-basics.html
index 957dfaa..99edc84 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics.html
+++ b/LayoutTests/storage/indexeddb/objectstore-basics.html
@@ -47,7 +47,7 @@ function setVersionSuccess()
 
 function createObjectStore()
 {
-    debug("creatObjectStore():");
+    debug("createObjectStore():");
     window.store = evalAndLog("store = db.createObjectStore('storeName', null)");
     var storeNames = evalAndLog("storeNames = db.objectStores");
 
@@ -195,6 +195,40 @@ function removeSuccess()
     debug("removeSuccess():");
     verifySuccessEvent(event);
     shouldBeNull("event.result");
+    var store = evalAndLog("store = event.source");
+
+    try {
+        debug("Passing an invalid key into store.get().");
+        store.get([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into store.remove().");
+        store.remove([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into store.add().");
+        store.add(null, []);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
+    try {
+        debug("Passing an invalid key into store.put().");
+        store.put(null, []);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+
     done();
 }
 
diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt b/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
index 881fe92..1493a80 100644
--- a/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
@@ -854,6 +854,26 @@ PASS event.result is null
 Next test: lower bound is 6; upper bound is 6; sorted descending.
 PASS event.result.key is testData[6]
 PASS event.result is null
+
+Next test: null key path sorted ascending.
+PASS event.result.key is testData[0]
+PASS event.result.key is testData[1]
+PASS event.result.key is testData[2]
+PASS event.result.key is testData[3]
+PASS event.result.key is testData[4]
+PASS event.result.key is testData[5]
+PASS event.result.key is testData[6]
+PASS event.result is null
+
+Next test: null key path sorted descending.
+PASS event.result.key is testData[6]
+PASS event.result.key is testData[5]
+PASS event.result.key is testData[4]
+PASS event.result.key is testData[3]
+PASS event.result.key is testData[2]
+PASS event.result.key is testData[1]
+PASS event.result.key is testData[0]
+PASS event.result is null
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor.html b/LayoutTests/storage/indexeddb/objectstore-cursor.html
index d9ad805..d0d786b 100644
--- a/LayoutTests/storage/indexeddb/objectstore-cursor.html
+++ b/LayoutTests/storage/indexeddb/objectstore-cursor.html
@@ -105,7 +105,7 @@ function scheduleTests()
 function runNextTest()
 {
     if (!scheduledTests.length) {
-        done();
+        testNullKeyRange();
         return;
     }
  
@@ -164,8 +164,7 @@ function runNextTest()
     else
         keyRange = webkitIDBKeyRange.rightBound(testData[upper], upperIsOpen);
  
-    // FIXME: Should be webkitIDBCursor.NEXT : webkitIDBCursor.PREV, but we can't do that yet.
-    var request = objectStore.openCursor(keyRange, ascending ? 0 : 2);
+    var request = objectStore.openCursor(keyRange, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
     request.onsuccess = cursorIteration;
     request.onerror = unexpectedErrorCallback;
 }
@@ -204,6 +203,38 @@ function cursorIteration()
     event.result.continue();
 }
  
+window.nullKeyRangeStep = 0;
+function testNullKeyRange()
+{
+    window.lower = 0;
+    window.lowerIsOpen = false;
+    window.upper = testData.length-1;
+    window.upperIsOpen = false;
+
+    str = "Next test: null key path ";
+    if (window.nullKeyRangeStep == 0) {
+        str += "sorted ascending.";
+        window.ascending = true;
+        window.expectedIndex = lower;
+        window.nullKeyRangeStep = 1;
+    } else if (window.nullKeyRangeStep == 1) {
+        str += "sorted descending.";
+        window.ascending = false;
+        window.expectedIndex = upper;
+        window.nullKeyRangeStep = 2;
+    } else {
+        done();
+        return;
+    }
+
+    debug("");
+    debug(str);
+ 
+    var request = objectStore.openCursor(null, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
+    request.onsuccess = cursorIteration;
+    request.onerror = unexpectedErrorCallback;
+}
+ 
 openDatabase(); // The first step.
 var successfullyParsed = true;
  
diff --git a/LayoutTests/storage/indexeddb/open-cursor-expected.txt b/LayoutTests/storage/indexeddb/open-cursor-expected.txt
index 1bca527..c3c1a8d 100644
--- a/LayoutTests/storage/indexeddb/open-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/open-cursor-expected.txt
@@ -72,6 +72,9 @@ PASS event.result.direction is 0
 PASS event.result.key is 'myKey'
 PASS event.result.value is 'myValue'
 
+Passing an invalid key into .continue().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+
 Opening an empty cursor.
 objectStore.openCursor(keyRange)
 PASS 'onsuccess' in result is true
diff --git a/LayoutTests/storage/indexeddb/open-cursor.html b/LayoutTests/storage/indexeddb/open-cursor.html
index ec62f2c..815c01b 100644
--- a/LayoutTests/storage/indexeddb/open-cursor.html
+++ b/LayoutTests/storage/indexeddb/open-cursor.html
@@ -41,6 +41,14 @@ function cursorSuccess()
     shouldBe("event.result.key", "'myKey'");
     shouldBe("event.result.value", "'myValue'");
     debug("");
+    try {
+        debug("Passing an invalid key into .continue().");
+        event.result.continue([]);
+        testFailed("No exception thrown");
+    } catch (e) {
+        testPassed("Caught exception: " + e.toString());
+    }
+    debug("");
     openEmptyCursor();
 }
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index cfbe3ea..9578d73 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,43 @@
+2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
+
+        Reviewed by Steve Block.
+        Fix IndexedDB crashes
+        https://bugs.webkit.org/show_bug.cgi?id=48266
+
+        If IDBKey returns null, type conversion failed. Handle this case
+        in the bindings.
+
+        Change UNKNOWN_ERR to be 1 since 0 is hard coded to mean no error.
+        This is just a stop-gap move until we get it figured out in standards
+        land.
+
+        IDBObjectStore needs to handle null ranges.
+
+        It's actually OK for m_transaction to be non-null when hitting the
+        destructor. We just need to then remove it from the set of pending
+        transactions.
+
+        The transaction can become aborted in the middle of processing a
+        list of tasks. Fix this.
+
+        All changes (except the last 2 races) are tested in LayoutTests.
+        I couldn't find a way to reliably reproduce the races.
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        * bindings/scripts/test/V8/V8TestObj.cpp:
+        (WebCore::TestObjInternal::idbKeyCallback):
+        * bindings/v8/IDBBindingUtilities.cpp:
+        (WebCore::createIDBKeyFromValue):
+        * storage/IDBDatabaseException.h:
+        * storage/IDBDatabaseException.idl:
+        * storage/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::openCursorInternal):
+        * storage/IDBRequest.cpp:
+        (WebCore::IDBRequest::~IDBRequest):
+        (WebCore::IDBRequest::timerFired):
+        * storage/IDBTransactionBackendImpl.cpp:
+        (WebCore::IDBTransactionBackendImpl::taskTimerFired):
+
 2010-10-25  Andrey Kosyakov  <caseq at chromium.org>
 
         Reviewed by Pavel Feldman.
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 46d9cfa..423cc6b 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -3012,6 +3012,7 @@ sub TypeCanFailConversion
     $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
     return 1 if $type eq "Attr";
     return 1 if $type eq "VoidCallback";
+    return 1 if $type eq "IDBKey";
     return BasicTypeCanFailConversion($signature);
 }
 
diff --git a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
index 44f0d3e..4be1177 100644
--- a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
+++ b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
@@ -678,9 +678,19 @@ static v8::Handle<v8::Value> idbKeyCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.TestObj.idbKey");
     TestObj* imp = V8TestObj::toNative(args.Holder());
-    EXCEPTION_BLOCK(RefPtr<IDBKey>, key, createIDBKeyFromValue(args[0]));
+    ExceptionCode ec = 0;
+    {
+    RefPtr<IDBKey> key = createIDBKeyFromValue(args[0]);
+    if (UNLIKELY(!key)) {
+        ec = TYPE_MISMATCH_ERR;
+        goto fail;
+    }
     imp->idbKey(key);
     return v8::Handle<v8::Value>();
+    }
+    fail:
+    V8Proxy::setDOMException(ec);
+    return v8::Handle<v8::Value>();
 }
 
 static v8::Handle<v8::Value> methodWithExceptionCallback(const v8::Arguments& args)
diff --git a/WebCore/bindings/v8/IDBBindingUtilities.cpp b/WebCore/bindings/v8/IDBBindingUtilities.cpp
index 4a58853..123b15c 100644
--- a/WebCore/bindings/v8/IDBBindingUtilities.cpp
+++ b/WebCore/bindings/v8/IDBBindingUtilities.cpp
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "IDBDatabaseException.h"
 #include "IDBKey.h"
 #include "IDBKeyPath.h"
 #include "SerializedScriptValue.h"
@@ -45,7 +46,8 @@ PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value)
     if (value->IsString())
         return IDBKey::create(v8ValueToWebCoreString(value));
     // FIXME: Implement dates.
-    return 0;
+
+    return 0; // Signals type error.
 }
 
 template<typename T>
diff --git a/WebCore/storage/IDBDatabaseException.h b/WebCore/storage/IDBDatabaseException.h
index 251cfc9..945773c 100644
--- a/WebCore/storage/IDBDatabaseException.h
+++ b/WebCore/storage/IDBDatabaseException.h
@@ -42,9 +42,8 @@ public:
     }
     ~IDBDatabaseException() { }
 
-    // Keep in sync with what's in the .idl file.
     enum ErrorCode {
-        UNKNOWN_ERR = 0,
+        UNKNOWN_ERR = 1,
         NON_TRANSIENT_ERR = 1,
         NOT_FOUND_ERR = 2,
         CONSTRAINT_ERR = 3,
diff --git a/WebCore/storage/IDBDatabaseException.idl b/WebCore/storage/IDBDatabaseException.idl
index 88e6e7e..1f15fc0 100644
--- a/WebCore/storage/IDBDatabaseException.idl
+++ b/WebCore/storage/IDBDatabaseException.idl
@@ -28,7 +28,8 @@ module storage {
     interface [
         Conditional=INDEXED_DATABASE
     ] IDBDatabaseException {
-        const unsigned short UNKNOWN_ERR = 0;
+        // FIXME: These error codes conflict with others.
+        const unsigned short UNKNOWN_ERR = 1;
         const unsigned short NON_TRANSIENT_ERR = 1;
         const unsigned short NOT_FOUND_ERR = 2;
         const unsigned short CONSTRAINT_ERR = 3;
diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
index fe68ebf..4892556 100644
--- a/WebCore/storage/IDBObjectStoreBackendImpl.cpp
+++ b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
@@ -394,11 +394,14 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, uns
 
 void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
 {
+    bool leftBound = range && (range->flags() & IDBKeyRange::LEFT_BOUND || range->flags() == IDBKeyRange::SINGLE);
+    bool rightBound = range && (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE);
+
     // Several files depend on this order of selects.
     String sql = "SELECT id, keyString, keyDate, keyNumber, value FROM ObjectStoreData WHERE ";
-    if (range->flags() & IDBKeyRange::LEFT_BOUND || range->flags() == IDBKeyRange::SINGLE)
+    if (leftBound)
         sql += range->left()->leftCursorWhereFragment(range->leftWhereClauseComparisonOperator());
-    if (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE)
+    if (rightBound)
         sql += range->right()->rightCursorWhereFragment(range->rightWhereClauseComparisonOperator());
     sql += "objectStoreId = ? ORDER BY ";
 
@@ -413,9 +416,9 @@ void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, Pass
     ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
 
     int currentColumn = 1;
-    if (range->flags() & IDBKeyRange::LEFT_BOUND || range->flags() == IDBKeyRange::SINGLE)
+    if (leftBound)
         currentColumn += range->left()->bind(*query, currentColumn);
-    if (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE)
+    if (rightBound)
         currentColumn += range->right()->bind(*query, currentColumn);
     query->bindInt64(currentColumn, objectStore->id());
 
diff --git a/WebCore/storage/IDBRequest.cpp b/WebCore/storage/IDBRequest.cpp
index c67e379..cbd635c 100644
--- a/WebCore/storage/IDBRequest.cpp
+++ b/WebCore/storage/IDBRequest.cpp
@@ -59,15 +59,6 @@ IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> sourc
 
 IDBRequest::~IDBRequest()
 {
-    // The transaction pointer is used to notify the transaction once the JS events were
-    // dispatched by this request object. If no new tasks were added by the event JS callbacks,
-    // the transaction can commit. Otherwise, it can continue executing the new tasks.
-    // It is important to guarantee that the transaction is notified after the events are
-    // dispatched, as the transaction cannot commit or execute new tasks in the absence
-    // of these notifications. We clear the transaction pointer once the events have dispatched,
-    // so having a non-zero pointer at IDBRequest destruction time shows that the events have not
-    // yet fired and there is a transaction waiting to be notified. This is an error.
-    ASSERT(!m_transaction);
 }
 
 bool IDBRequest::resetReadyState(IDBTransactionBackendInterface* transaction)
@@ -159,6 +150,7 @@ void IDBRequest::timerFired(Timer<IDBRequest>*)
 {
     ASSERT(m_selfRef);
     ASSERT(m_pendingEvents.size());
+    // FIXME: We should handle the stop event and stop any timers when we see it. We can then assert here that scriptExecutionContext is non-null.
 
     // We need to keep self-referencing ourself, otherwise it's possible we'll be deleted.
     // But in some cases, suspend() could be called while we're dispatching an event, so we
@@ -172,6 +164,10 @@ void IDBRequest::timerFired(Timer<IDBRequest>*)
     Vector<PendingEvent> pendingEvents;
     pendingEvents.swap(m_pendingEvents);
     for (size_t i = 0; i < pendingEvents.size(); ++i) {
+        // It's possible we've navigated in which case we'll crash.
+        if (!scriptExecutionContext())
+            return;
+
         if (pendingEvents[i].m_error) {
             ASSERT(!pendingEvents[i].m_result);
             dispatchEvent(IDBErrorEvent::create(m_source, *pendingEvents[i].m_error));
diff --git a/WebCore/storage/IDBTransactionBackendImpl.cpp b/WebCore/storage/IDBTransactionBackendImpl.cpp
index 5016a3f..2b1f732 100644
--- a/WebCore/storage/IDBTransactionBackendImpl.cpp
+++ b/WebCore/storage/IDBTransactionBackendImpl.cpp
@@ -147,7 +147,7 @@ void IDBTransactionBackendImpl::taskTimerFired(Timer<IDBTransactionBackendImpl>*
 
     TaskQueue queue;
     queue.swap(m_taskQueue);
-    while (!queue.isEmpty()) {
+    while (!queue.isEmpty() && m_state != Finished) {
         OwnPtr<ScriptExecutionContext::Task> task(queue.first().release());
         queue.removeFirst();
         m_pendingEvents++;
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index a549e7a..a46f186 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,17 @@
+2010-10-26  Jeremy Orlow  <jorlow at chromium.org>
+
+        Reviewed by Steve Block.
+
+        Fix IndexedDB crashes
+        https://bugs.webkit.org/show_bug.cgi?id=48266
+
+        Make WebIDBObjectStoreImpl match the way that WebIDBIndexImpl passes
+        in cursor parameters (which is the correct way). KeyRange knows how
+        to convert itself to a WebCore type--even if the value is null.
+
+        * src/WebIDBObjectStoreImpl.cpp:
+        (WebKit::WebIDBObjectStoreImpl::openCursor):
+
 2010-10-26  Satish Sampath  <satish at chromium.org>
 
         Reviewed by Steve Block.
diff --git a/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp
index 96495fe..5dd2652 100755
--- a/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp
+++ b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp
@@ -104,7 +104,7 @@ void WebIDBObjectStoreImpl::removeIndex(const WebString& name, const WebIDBTrans
 
 void WebIDBObjectStoreImpl::openCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction, WebExceptionCode& ec)
 {
-    m_objectStore->openCursor(IDBKeyRange::create(keyRange.left(), keyRange.right(), keyRange.flags()), direction, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface(), ec);
+    m_objectStore->openCursor(keyRange, direction, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface(), ec);
 }
 
 } // namespace WebCore

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list