Bug 618196 - 'IndexedDB: Error events and exceptions thrown during success events should abort transactions'. r=sicking, a=blocking.

This commit is contained in:
Ben Turner 2010-12-15 13:20:57 -08:00
Родитель a4c8b00d12
Коммит f1386fb91c
11 изменённых файлов: 367 добавлений и 16 удалений

Просмотреть файл

@ -1206,8 +1206,11 @@ found:
dispData->method, *typeData->iid);
} else if (useGenericInterface &&
aPusher->RePush(aCurrentTarget)) {
HandleEventSubType(ls, ls->mListener, *aDOMEvent,
aCurrentTarget, aFlags, aPusher);
if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
aCurrentTarget, aFlags,
aPusher))) {
aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
}
}
}
}

Просмотреть файл

@ -380,7 +380,22 @@ AsyncConnectionHelper::OnSuccess(nsIDOMEventTarget* aTarget)
}
PRBool dummy;
aTarget->DispatchEvent(event, &dummy);
rv = aTarget->DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
NS_ASSERTION(privateEvent, "This should always QI properly!");
nsEvent* internalEvent = privateEvent->GetInternalNSEvent();
NS_ASSERTION(internalEvent, "This should never be null!");
if ((internalEvent->flags & NS_EVENT_FLAG_EXCEPTION_THROWN) &&
mTransaction &&
mTransaction->TransactionIsOpen()) {
rv = mTransaction->Abort();
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
@ -397,8 +412,19 @@ AsyncConnectionHelper::OnError(nsIDOMEventTarget* aTarget,
return;
}
PRBool dummy;
aTarget->DispatchEvent(event, &dummy);
PRBool doDefault;
nsresult rv = aTarget->DispatchEvent(event, &doDefault);
if (NS_SUCCEEDED(rv)) {
if (doDefault &&
mTransaction &&
mTransaction->TransactionIsOpen() &&
NS_FAILED(mTransaction->Abort())) {
NS_WARNING("Failed to abort transaction!");
}
}
else {
NS_WARNING("DispatchEvent failed!");
}
}
nsresult

Просмотреть файл

@ -47,7 +47,9 @@ include $(topsrcdir)/config/rules.mk
TEST_FILES = \
bfcache_iframe1.html \
bfcache_iframe2.html \
error_events_abort_transactions_iframe.html \
event_propagation_iframe.html \
exceptions_in_success_events_iframe.html \
helpers.js \
test_add_twice_failure.html \
test_bad_keypath.html \
@ -58,8 +60,10 @@ TEST_FILES = \
test_cursors.html \
test_cursor_mutation.html \
test_cursor_update_updates_indexes.html \
test_error_events_abort_transactions.html \
test_event_propagation.html \
test_event_source.html \
test_exceptions_in_success_events.html \
test_getAll.html \
test_global_data.html \
test_index_getAll.html \

Просмотреть файл

@ -0,0 +1,146 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript;version=1.7">
let testGenerator = testSteps();
function ok(val, message) {
val = val ? "true" : "false";
window.parent.postMessage("SimpleTest.ok(" + val + ", '" + message +
"');", "*");
}
function is(a, b, message) {
ok(a == b, message);
}
function grabEventAndContinueHandler(event) {
testGenerator.send(event);
}
function errorHandler(event) {
ok(false, "indexedDB error (" + event.code + "): " + event.message);
finishTest();
}
function unexpectedSuccessHandler(event) {
ok(false, "got success when it was not expected!");
finishTest();
}
function finishTest() {
// Let window.onerror have a chance to fire
setTimeout(function() {
setTimeout(function() {
testGenerator.close();
window.parent.postMessage("SimpleTest.finish();", "*");
}, 0);
}, 0);
}
window.onerror = function(event) {
};
function testSteps() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
let uri = window.document.documentURIObject;
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(uri, "indexedDB",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
let request = moz_indexedDB.open(window.location.pathname);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
is(db.version, "", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
let request = db.setVersion("1");
request.onsuccess = grabEventAndContinueHandler;
request.onerror = errorHandler;
event = yield;
event.transaction.oncomplete = unexpectedSuccessHandler;
event.transaction.onabort = grabEventAndContinueHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
let objectStore = db.createObjectStore("foo", "");
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
request = objectStore.add({}, 1);
request.onsuccess = grabEventAndContinueHandler;
request.onerror = errorHandler;
event = yield;
request = objectStore.add({}, 1);
request.onsuccess = unexpectedSuccessHandler;
request.onerror = function(event) {
// Don't do anything! We want this error.
}
event = yield;
is(event.type, "abort", "Got a transaction abort event");
is(db.version, "", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
request = db.setVersion("1");
request.onsuccess = grabEventAndContinueHandler;
request.onerror = errorHandler;
event = yield;
event.transaction.oncomplete = grabEventAndContinueHandler;
event.transaction.onabort = unexpectedSuccessHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
let objectStore = db.createObjectStore("foo", "");
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
request = objectStore.add({}, 1);
request.onsuccess = grabEventAndContinueHandler;
request.onerror = errorHandler;
event = yield;
request = objectStore.add({}, 1);
request.onsuccess = unexpectedSuccessHandler;
request.onerror = function(event) {
// Expected, but prevent the abort.
event.preventDefault();
}
event = yield;
is(event.type, "complete", "Got a transaction complete event");
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
finishTest();
yield;
}
</script>
</head>
<body onload="testGenerator.next();"></body>
</html>

Просмотреть файл

@ -138,9 +138,14 @@
objectStore = transaction.objectStore("foo");
request = objectStore.add({}, 1);
request.onsuccess = grabEventAndContinueHandler;
request.onerror = errorHandler;
event = yield;
request = objectStore.add({}, 1);
request.onsuccess = function(event) {
ok(false, "Did not expect third add to succeed.");
ok(false, "Did not expect second add to succeed.");
};
request.onerror = errorEventCounter;
yield;

Просмотреть файл

@ -0,0 +1,108 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
let testGenerator = testSteps();
function ok(val, message) {
val = val ? "true" : "false";
window.parent.postMessage("SimpleTest.ok(" + val + ", '" + message +
"');", "*");
}
function is(a, b, message) {
ok(a == b, message);
}
function grabEventAndContinueHandler(event) {
testGenerator.send(event);
}
function errorHandler(event) {
ok(false, "indexedDB error (" + event.code + "): " + event.message);
finishTest();
}
function unexpectedSuccessHandler(event) {
ok(false, "got success when it was not expected!");
finishTest();
}
function finishTest() {
// Let window.onerror have a chance to fire
setTimeout(function() {
setTimeout(function() {
testGenerator.close();
window.parent.postMessage("SimpleTest.finish();", "*");
}, 0);
}, 0);
}
window.onerror = function(event) {
event.preventDefault();
};
function testSteps() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
let uri = window.document.documentURIObject;
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(uri, "indexedDB",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
let request = moz_indexedDB.open(window.location.pathname);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
db.onerror = function(event) {
event.preventDefault();
};
is(db.version, "", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
event = yield;
event.transaction.oncomplete = unexpectedSuccessHandler;
event.transaction.onabort = grabEventAndContinueHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
let objectStore = db.createObjectStore("foo", "");
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
request = objectStore.add({}, 1);
request.onsuccess = function(event) {
throw "foo";
};
event = yield;
is(event.type, "abort", "Got transaction abort event");
finishTest();
yield;
}
</script>
</head>
<body onload="testGenerator.next();"></body>
</html>

Просмотреть файл

@ -13,11 +13,6 @@
<script type="text/javascript;version=1.7">
function testSteps()
{
const NOT_FOUND_ERR =
Components.interfaces.nsIIDBDatabaseException.NOT_FOUND_ERR;
const NEXT = Components.interfaces.nsIIDBCursor.NEXT;
const PREV = Components.interfaces.nsIIDBCursor.PREV;
const name = window.location.pathname;
const description = "My Test Database";
const keys = [1, -1, 0, 10, 2000, "q", "z", "two", "b", "a"];
@ -288,7 +283,7 @@
let gotRemoveEvent = false;
let retval = false;
request = objectStore.openCursor(null, NEXT);
request = objectStore.openCursor(null, IDBCursor.NEXT);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
@ -319,7 +314,7 @@
is(gotRemoveEvent, true, "Saw the remove event");
request = objectStore.get(sortedKeys[4]);
request.onerror = new ExpectError(NOT_FOUND_ERR);
request.onerror = new ExpectError(IDBDatabaseException.NOT_FOUND_ERR);
request.onsuccess = unexpectedSuccessHandler;
event = yield;
@ -330,7 +325,7 @@
keyIndex = sortedKeys.length - 1;
request = objectStore.openCursor(null, PREV);
request = objectStore.openCursor(null, IDBCursor.PREV);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;

Просмотреть файл

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function runTest() {
SimpleTest.waitForExplicitFinish();
function messageListener(event) {
eval(event.data);
}
window.addEventListener("message", messageListener, false);
}
</script>
</head>
<body onload="runTest();">
<iframe src="error_events_abort_transactions_iframe.html"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function runTest() {
SimpleTest.waitForExplicitFinish();
function messageListener(event) {
eval(event.data);
}
window.addEventListener("message", messageListener, false);
}
</script>
</head>
<body onload="runTest();">
<iframe src="exceptions_in_success_events_iframe.html"></iframe>
</body>
</html>

Просмотреть файл

@ -181,9 +181,9 @@
is(event.result, key1, "put gave back the same key");
request = objectStore.add({id:10});
request.onerror = grabEventAndContinueHandler;
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
request.onsuccess = unexpectedSuccessHandler;
yield;
event = yield;
request = objectStore.add({}, null);
request.onerror = errorHandler;

Просмотреть файл

@ -156,6 +156,8 @@ class nsHashKey;
#define NS_PRIV_EVENT_UNTRUSTED_PERMITTED 0x8000
#define NS_EVENT_FLAG_EXCEPTION_THROWN 0x10000
#define NS_EVENT_CAPTURE_MASK (~(NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))
#define NS_EVENT_BUBBLE_MASK (~(NS_EVENT_FLAG_CAPTURE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))