mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Bug 1081703, r=khuey.
This commit is contained in:
parent
9ffe3e11d4
commit
38b2675dc9
@ -2027,7 +2027,6 @@ BackgroundCursorChild::SendContinueInternal(const CursorRequestParams& aParams)
|
||||
MOZ_ASSERT(!mStrongCursor);
|
||||
|
||||
// Make sure all our DOM objects stay alive.
|
||||
mStrongRequest = mRequest;
|
||||
mStrongCursor = mCursor;
|
||||
|
||||
MOZ_ASSERT(mRequest->ReadyState() == IDBRequestReadyState::Done);
|
||||
@ -2119,9 +2118,7 @@ BackgroundCursorChild::HandleResponse(
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()), Move(cloneReadInfo));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mObjectStore,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(cloneReadInfo));
|
||||
mCursor = newCursor;
|
||||
@ -2150,10 +2147,7 @@ BackgroundCursorChild::HandleResponse(
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mObjectStore,
|
||||
this,
|
||||
mDirection,
|
||||
Move(response.key()));
|
||||
newCursor = IDBCursor::Create(this, Move(response.key()));
|
||||
mCursor = newCursor;
|
||||
}
|
||||
|
||||
@ -2187,9 +2181,7 @@ BackgroundCursorChild::HandleResponse(const IndexCursorResponse& aResponse)
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mIndex,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
@ -2218,9 +2210,7 @@ BackgroundCursorChild::HandleResponse(const IndexKeyCursorResponse& aResponse)
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()), Move(response.objectKey()));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mIndex,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.objectKey()));
|
||||
mCursor = newCursor;
|
||||
@ -2265,8 +2255,8 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
|
||||
MOZ_ASSERT(aResponse.type() != CursorResponse::T__None);
|
||||
MOZ_ASSERT(mRequest);
|
||||
MOZ_ASSERT(mTransaction);
|
||||
MOZ_ASSERT(mStrongRequest);
|
||||
MOZ_ASSERT_IF(mCursor, mStrongCursor);
|
||||
MOZ_ASSERT_IF(!mCursor, mStrongRequest);
|
||||
|
||||
MaybeCollectGarbageOnIPCMessage();
|
||||
|
||||
|
@ -568,6 +568,38 @@ public:
|
||||
void
|
||||
SendDeleteMeInternal();
|
||||
|
||||
IDBRequest*
|
||||
GetRequest() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mRequest;
|
||||
}
|
||||
|
||||
IDBObjectStore*
|
||||
GetObjectStore() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mObjectStore;
|
||||
}
|
||||
|
||||
IDBIndex*
|
||||
GetIndex() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
Direction
|
||||
GetDirection() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mDirection;
|
||||
}
|
||||
|
||||
private:
|
||||
// Only destroyed by BackgroundTransactionChild or
|
||||
// BackgroundVersionChangeTransactionChild.
|
||||
|
@ -27,23 +27,20 @@ namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
IDBCursor::IDBCursor(Type aType,
|
||||
IDBObjectStore* aSourceObjectStore,
|
||||
IDBIndex* aSourceIndex,
|
||||
IDBTransaction* aTransaction,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
const Key& aKey)
|
||||
: mSourceObjectStore(aSourceObjectStore)
|
||||
, mSourceIndex(aSourceIndex)
|
||||
, mTransaction(aTransaction)
|
||||
, mBackgroundActor(aBackgroundActor)
|
||||
, mScriptOwner(aTransaction->Database()->GetScriptOwner())
|
||||
: mBackgroundActor(aBackgroundActor)
|
||||
, mRequest(aBackgroundActor->GetRequest())
|
||||
, mSourceObjectStore(aBackgroundActor->GetObjectStore())
|
||||
, mSourceIndex(aBackgroundActor->GetIndex())
|
||||
, mTransaction(mRequest->GetTransaction())
|
||||
, mScriptOwner(mTransaction->Database()->GetScriptOwner())
|
||||
, mCachedKey(JSVAL_VOID)
|
||||
, mCachedPrimaryKey(JSVAL_VOID)
|
||||
, mCachedValue(JSVAL_VOID)
|
||||
, mKey(aKey)
|
||||
, mType(aType)
|
||||
, mDirection(aDirection)
|
||||
, mDirection(aBackgroundActor->GetDirection())
|
||||
, mHaveCachedKey(false)
|
||||
, mHaveCachedPrimaryKey(false)
|
||||
, mHaveCachedValue(false)
|
||||
@ -51,12 +48,13 @@ IDBCursor::IDBCursor(Type aType,
|
||||
, mContinueCalled(false)
|
||||
, mHaveValue(true)
|
||||
{
|
||||
MOZ_ASSERT_IF(aType == Type_ObjectStore || aType == Type_ObjectStoreKey,
|
||||
aSourceObjectStore);
|
||||
MOZ_ASSERT_IF(aType == Type_Index || aType == Type_IndexKey, aSourceIndex);
|
||||
MOZ_ASSERT(aTransaction);
|
||||
aTransaction->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mRequest);
|
||||
MOZ_ASSERT_IF(aType == Type_ObjectStore || aType == Type_ObjectStoreKey,
|
||||
mSourceObjectStore);
|
||||
MOZ_ASSERT_IF(aType == Type_Index || aType == Type_IndexKey, mSourceIndex);
|
||||
MOZ_ASSERT(mTransaction);
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(mScriptOwner);
|
||||
|
||||
@ -80,25 +78,18 @@ IDBCursor::~IDBCursor()
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo)
|
||||
{
|
||||
MOZ_ASSERT(aObjectStore);
|
||||
aObjectStore->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_ObjectStore,
|
||||
aObjectStore,
|
||||
nullptr,
|
||||
aObjectStore->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_ObjectStore, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mCloneInfo = Move(aCloneInfo);
|
||||
|
||||
@ -107,51 +98,37 @@ IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey)
|
||||
{
|
||||
MOZ_ASSERT(aObjectStore);
|
||||
aObjectStore->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_ObjectStoreKey,
|
||||
aObjectStore,
|
||||
nullptr,
|
||||
aObjectStore->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_ObjectStoreKey, aBackgroundActor, aKey);
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo)
|
||||
{
|
||||
MOZ_ASSERT(aIndex);
|
||||
aIndex->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(!aPrimaryKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_Index,
|
||||
nullptr,
|
||||
aIndex,
|
||||
aIndex->ObjectStore()->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_Index, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mPrimaryKey = Move(aPrimaryKey);
|
||||
cursor->mCloneInfo = Move(aCloneInfo);
|
||||
@ -161,26 +138,19 @@ IDBCursor::Create(IDBIndex* aIndex,
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey)
|
||||
{
|
||||
MOZ_ASSERT(aIndex);
|
||||
aIndex->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(!aPrimaryKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_IndexKey,
|
||||
nullptr,
|
||||
aIndex,
|
||||
aIndex->ObjectStore()->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_IndexKey, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mPrimaryKey = Move(aPrimaryKey);
|
||||
|
||||
@ -800,9 +770,9 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBCursor)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBCursor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceObjectStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceIndex)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
@ -819,7 +789,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor)
|
||||
// Don't unlink mSourceObjectStore or mSourceIndex or mTransaction!
|
||||
// Don't unlink mRequest, mSourceObjectStore, or mSourceIndex!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->DropJSObjects();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -59,11 +59,14 @@ private:
|
||||
Type_IndexKey,
|
||||
};
|
||||
|
||||
BackgroundCursorChild* mBackgroundActor;
|
||||
|
||||
nsRefPtr<IDBRequest> mRequest;
|
||||
nsRefPtr<IDBObjectStore> mSourceObjectStore;
|
||||
nsRefPtr<IDBIndex> mSourceIndex;
|
||||
nsRefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
BackgroundCursorChild* mBackgroundActor;
|
||||
// mSourceObjectStore or mSourceIndex will hold this alive.
|
||||
IDBTransaction* mTransaction;
|
||||
|
||||
JS::Heap<JSObject*> mScriptOwner;
|
||||
|
||||
@ -88,30 +91,22 @@ private:
|
||||
|
||||
public:
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey);
|
||||
|
||||
@ -194,11 +189,7 @@ public:
|
||||
|
||||
private:
|
||||
IDBCursor(Type aType,
|
||||
IDBObjectStore* aSourceObjectStore,
|
||||
IDBIndex* aSourceIndex,
|
||||
IDBTransaction* aTransaction,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
const Key& aKey);
|
||||
|
||||
~IDBCursor();
|
||||
|
@ -46,6 +46,7 @@ support-files =
|
||||
unit/test_indexes.js
|
||||
unit/test_indexes_bad_values.js
|
||||
unit/test_indexes_funny_things.js
|
||||
unit/test_invalid_cursor.js
|
||||
unit/test_invalid_version.js
|
||||
unit/test_invalidate.js
|
||||
unit/test_key_requirements.js
|
||||
@ -267,6 +268,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_indexes_funny_things.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalid_cursor.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalid_version.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalidate.html]
|
||||
|
18
dom/indexedDB/test/test_invalid_cursor.html
Normal file
18
dom/indexedDB/test/test_invalid_cursor.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>IndexedDB Test</title>
|
||||
|
||||
<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" src="unit/test_invalid_cursor.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
62
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
62
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
let testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName = ("window" in this) ? window.location.pathname : "test";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const data = 0;
|
||||
|
||||
let req = indexedDB.open(dbName, dbVersion);
|
||||
req.onerror = errorHandler;
|
||||
req.onupgradeneeded = grabEventAndContinueHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got upgradeneeded event");
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore =
|
||||
db.createObjectStore(objectStoreName, { autoIncrement: true });
|
||||
objectStore.add(data);
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for open");
|
||||
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
objectStore.openCursor().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for openCursor");
|
||||
|
||||
let cursor = event.target.result;
|
||||
is(cursor.value, data, "Got correct cursor value");
|
||||
|
||||
objectStore.get(cursor.key).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data, "Got correct get value");
|
||||
|
||||
info("Collecting garbage");
|
||||
|
||||
gc();
|
||||
|
||||
info("Done collecting garbage");
|
||||
|
||||
cursor.continue();
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "No more entries");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
@ -36,6 +36,7 @@ skip-if = toolkit == 'android' # bug 1079278
|
||||
[test_indexes.js]
|
||||
[test_indexes_bad_values.js]
|
||||
[test_indexes_funny_things.js]
|
||||
[test_invalid_cursor.js]
|
||||
[test_invalid_version.js]
|
||||
[test_key_requirements.js]
|
||||
[test_keys.js]
|
||||
|
Loading…
x
Reference in New Issue
Block a user