mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1179025 - Protect against using cursors on a deleted objectStore/index, r=janv.
This commit is contained in:
parent
02432eb394
commit
dc3eb40174
@ -6248,12 +6248,6 @@ private:
|
||||
bool
|
||||
VerifyRequestParams(const RequestParams& aParams) const;
|
||||
|
||||
bool
|
||||
VerifyRequestParams(const OpenCursorParams& aParams) const;
|
||||
|
||||
bool
|
||||
VerifyRequestParams(const CursorRequestParams& aParams) const;
|
||||
|
||||
bool
|
||||
VerifyRequestParams(const SerializedKeyRange& aKeyRange) const;
|
||||
|
||||
@ -7550,6 +7544,12 @@ private:
|
||||
nsRefPtr<FileManager> mFileManager;
|
||||
PBackgroundParent* mBackgroundParent;
|
||||
|
||||
// These should only be touched on the PBackground thread to check whether the
|
||||
// objectStore or index has been deleted. Holding these saves a hash lookup
|
||||
// for every call to continue()/advance().
|
||||
nsRefPtr<FullObjectStoreMetadata> mObjectStoreMetadata;
|
||||
nsRefPtr<FullIndexMetadata> mIndexMetadata;
|
||||
|
||||
const int64_t mObjectStoreId;
|
||||
const int64_t mIndexId;
|
||||
|
||||
@ -7565,7 +7565,8 @@ private:
|
||||
const Type mType;
|
||||
const Direction mDirection;
|
||||
|
||||
bool mUniqueIndex;
|
||||
const bool mUniqueIndex;
|
||||
const bool mIsSameProcessActor;
|
||||
bool mActorDestroyed;
|
||||
|
||||
public:
|
||||
@ -7575,8 +7576,8 @@ private:
|
||||
// Only created by TransactionBase.
|
||||
Cursor(TransactionBase* aTransaction,
|
||||
Type aType,
|
||||
int64_t aObjectStoreId,
|
||||
int64_t aIndexId,
|
||||
FullObjectStoreMetadata* aObjectStoreMetadata,
|
||||
FullIndexMetadata* aIndexMetadata,
|
||||
Direction aDirection);
|
||||
|
||||
// Reference counted.
|
||||
@ -7585,6 +7586,9 @@ private:
|
||||
MOZ_ASSERT(mActorDestroyed);
|
||||
}
|
||||
|
||||
bool
|
||||
VerifyRequestParams(const CursorRequestParams& aParams) const;
|
||||
|
||||
// Only called by TransactionBase.
|
||||
bool
|
||||
Start(const OpenCursorParams& aParams);
|
||||
@ -13368,115 +13372,6 @@ TransactionBase::VerifyRequestParams(const RequestParams& aParams) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TransactionBase::VerifyRequestParams(const OpenCursorParams& aParams) const
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != OpenCursorParams::T__None);
|
||||
|
||||
switch (aParams.type()) {
|
||||
case OpenCursorParams::TObjectStoreOpenCursorParams: {
|
||||
const ObjectStoreOpenCursorParams& params =
|
||||
aParams.get_ObjectStoreOpenCursorParams();
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TObjectStoreOpenKeyCursorParams: {
|
||||
const ObjectStoreOpenKeyCursorParams& params =
|
||||
aParams.get_ObjectStoreOpenKeyCursorParams();
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TIndexOpenCursorParams: {
|
||||
const IndexOpenCursorParams& params = aParams.get_IndexOpenCursorParams();
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
nsRefPtr<FullIndexMetadata> indexMetadata =
|
||||
GetMetadataForIndexId(objectStoreMetadata, params.indexId());
|
||||
if (NS_WARN_IF(!indexMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TIndexOpenKeyCursorParams: {
|
||||
const IndexOpenKeyCursorParams& params =
|
||||
aParams.get_IndexOpenKeyCursorParams();
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
nsRefPtr<FullIndexMetadata> indexMetadata =
|
||||
GetMetadataForIndexId(objectStoreMetadata, params.indexId());
|
||||
if (NS_WARN_IF(!indexMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TransactionBase::VerifyRequestParams(const CursorRequestParams& aParams) const
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != CursorRequestParams::T__None);
|
||||
|
||||
switch (aParams.type()) {
|
||||
case CursorRequestParams::TContinueParams:
|
||||
break;
|
||||
|
||||
case CursorRequestParams::TAdvanceParams:
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TransactionBase::VerifyRequestParams(const SerializedKeyRange& aParams) const
|
||||
{
|
||||
@ -13796,15 +13691,94 @@ PBackgroundIDBCursorParent*
|
||||
TransactionBase::AllocCursor(const OpenCursorParams& aParams, bool aTrustParams)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != OpenCursorParams::T__None);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Always verify parameters in DEBUG builds!
|
||||
aTrustParams = false;
|
||||
#endif
|
||||
|
||||
if (!aTrustParams && NS_WARN_IF(!VerifyRequestParams(aParams))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata;
|
||||
nsRefPtr<FullIndexMetadata> indexMetadata;
|
||||
|
||||
switch (aParams.type()) {
|
||||
case OpenCursorParams::TObjectStoreOpenCursorParams: {
|
||||
const ObjectStoreOpenCursorParams& params =
|
||||
aParams.get_ObjectStoreOpenCursorParams();
|
||||
objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
if (aTrustParams &&
|
||||
NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TObjectStoreOpenKeyCursorParams: {
|
||||
const ObjectStoreOpenKeyCursorParams& params =
|
||||
aParams.get_ObjectStoreOpenKeyCursorParams();
|
||||
objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
if (aTrustParams &&
|
||||
NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TIndexOpenCursorParams: {
|
||||
const IndexOpenCursorParams& params = aParams.get_IndexOpenCursorParams();
|
||||
objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
indexMetadata =
|
||||
GetMetadataForIndexId(objectStoreMetadata, params.indexId());
|
||||
if (NS_WARN_IF(!indexMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
if (aTrustParams &&
|
||||
NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenCursorParams::TIndexOpenKeyCursorParams: {
|
||||
const IndexOpenKeyCursorParams& params =
|
||||
aParams.get_IndexOpenKeyCursorParams();
|
||||
objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId());
|
||||
if (NS_WARN_IF(!objectStoreMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
indexMetadata =
|
||||
GetMetadataForIndexId(objectStoreMetadata, params.indexId());
|
||||
if (NS_WARN_IF(!indexMetadata)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
if (aTrustParams &&
|
||||
NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(mCommitOrAbortReceived)) {
|
||||
@ -13819,7 +13793,7 @@ TransactionBase::AllocCursor(const OpenCursorParams& aParams, bool aTrustParams)
|
||||
int64_t indexId;
|
||||
Cursor::Direction direction;
|
||||
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case OpenCursorParams::TObjectStoreOpenCursorParams: {
|
||||
const auto& params = aParams.get_ObjectStoreOpenCursorParams();
|
||||
objectStoreId = params.objectStoreId();
|
||||
@ -13857,7 +13831,7 @@ TransactionBase::AllocCursor(const OpenCursorParams& aParams, bool aTrustParams)
|
||||
}
|
||||
|
||||
nsRefPtr<Cursor> actor =
|
||||
new Cursor(this, type, objectStoreId, indexId, direction);
|
||||
new Cursor(this, type, objectStoreMetadata, indexMetadata, direction);
|
||||
|
||||
// Transfer ownership to IPDL.
|
||||
return actor.forget().take();
|
||||
@ -14688,26 +14662,32 @@ VersionChangeTransaction::DeallocPBackgroundIDBCursorParent(
|
||||
|
||||
Cursor::Cursor(TransactionBase* aTransaction,
|
||||
Type aType,
|
||||
int64_t aObjectStoreId,
|
||||
int64_t aIndexId,
|
||||
FullObjectStoreMetadata* aObjectStoreMetadata,
|
||||
FullIndexMetadata* aIndexMetadata,
|
||||
Direction aDirection)
|
||||
: mTransaction(aTransaction)
|
||||
, mBackgroundParent(nullptr)
|
||||
, mObjectStoreId(aObjectStoreId)
|
||||
, mIndexId(aIndexId)
|
||||
, mObjectStoreMetadata(aObjectStoreMetadata)
|
||||
, mIndexMetadata(aIndexMetadata)
|
||||
, mObjectStoreId(aObjectStoreMetadata->mCommonMetadata.id())
|
||||
, mIndexId(aIndexMetadata ? aIndexMetadata->mCommonMetadata.id() : 0)
|
||||
, mCurrentlyRunningOp(nullptr)
|
||||
, mType(aType)
|
||||
, mDirection(aDirection)
|
||||
, mUniqueIndex(false)
|
||||
, mUniqueIndex(aIndexMetadata ?
|
||||
aIndexMetadata->mCommonMetadata.unique() :
|
||||
false)
|
||||
, mIsSameProcessActor(!BackgroundParent::IsOtherProcessActor(
|
||||
aTransaction->GetBackgroundParent()))
|
||||
, mActorDestroyed(false)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aTransaction);
|
||||
MOZ_ASSERT(aType != OpenCursorParams::T__None);
|
||||
MOZ_ASSERT(aObjectStoreId);
|
||||
MOZ_ASSERT(aObjectStoreMetadata);
|
||||
MOZ_ASSERT_IF(aType == OpenCursorParams::TIndexOpenCursorParams ||
|
||||
aType == OpenCursorParams::TIndexOpenKeyCursorParams,
|
||||
aIndexId);
|
||||
aIndexMetadata);
|
||||
|
||||
if (mType == OpenCursorParams::TObjectStoreOpenCursorParams ||
|
||||
mType == OpenCursorParams::TIndexOpenCursorParams) {
|
||||
@ -14718,26 +14698,93 @@ Cursor::Cursor(TransactionBase* aTransaction,
|
||||
MOZ_ASSERT(mBackgroundParent);
|
||||
}
|
||||
|
||||
if (aIndexId) {
|
||||
MOZ_ASSERT(aType == OpenCursorParams::TIndexOpenCursorParams ||
|
||||
aType == OpenCursorParams::TIndexOpenKeyCursorParams);
|
||||
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
aTransaction->GetMetadataForObjectStoreId(aObjectStoreId);
|
||||
MOZ_ASSERT(objectStoreMetadata);
|
||||
|
||||
nsRefPtr<FullIndexMetadata> indexMetadata =
|
||||
aTransaction->GetMetadataForIndexId(objectStoreMetadata, aIndexId);
|
||||
MOZ_ASSERT(indexMetadata);
|
||||
|
||||
mUniqueIndex = indexMetadata->mCommonMetadata.unique();
|
||||
}
|
||||
|
||||
static_assert(OpenCursorParams::T__None == 0 &&
|
||||
OpenCursorParams::T__Last == 4,
|
||||
"Lots of code here assumes only four types of cursors!");
|
||||
}
|
||||
|
||||
bool
|
||||
Cursor::VerifyRequestParams(const CursorRequestParams& aParams) const
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != CursorRequestParams::T__None);
|
||||
MOZ_ASSERT(mObjectStoreMetadata);
|
||||
MOZ_ASSERT_IF(mType == OpenCursorParams::TIndexOpenCursorParams ||
|
||||
mType == OpenCursorParams::TIndexOpenKeyCursorParams,
|
||||
mIndexMetadata);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata =
|
||||
mTransaction->GetMetadataForObjectStoreId(mObjectStoreId);
|
||||
if (objectStoreMetadata) {
|
||||
MOZ_ASSERT(objectStoreMetadata == mObjectStoreMetadata);
|
||||
} else {
|
||||
MOZ_ASSERT(mObjectStoreMetadata->mDeleted);
|
||||
}
|
||||
|
||||
if (objectStoreMetadata &&
|
||||
(mType == OpenCursorParams::TIndexOpenCursorParams ||
|
||||
mType == OpenCursorParams::TIndexOpenKeyCursorParams)) {
|
||||
nsRefPtr<FullIndexMetadata> indexMetadata =
|
||||
mTransaction->GetMetadataForIndexId(objectStoreMetadata, mIndexId);
|
||||
if (indexMetadata) {
|
||||
MOZ_ASSERT(indexMetadata == mIndexMetadata);
|
||||
} else {
|
||||
MOZ_ASSERT(mIndexMetadata->mDeleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NS_WARN_IF(mObjectStoreMetadata->mDeleted) ||
|
||||
(mIndexMetadata && NS_WARN_IF(mIndexMetadata->mDeleted))) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (aParams.type()) {
|
||||
case CursorRequestParams::TContinueParams: {
|
||||
const Key& key = aParams.get_ContinueParams().key();
|
||||
if (!key.IsUnset()) {
|
||||
switch (mDirection) {
|
||||
case IDBCursor::NEXT:
|
||||
case IDBCursor::NEXT_UNIQUE:
|
||||
if (NS_WARN_IF(key <= mKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDBCursor::PREV:
|
||||
case IDBCursor::PREV_UNIQUE:
|
||||
if (NS_WARN_IF(key >= mKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CursorRequestParams::TAdvanceParams:
|
||||
if (NS_WARN_IF(!aParams.get_AdvanceParams().count())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Cursor::Start(const OpenCursorParams& aParams)
|
||||
{
|
||||
@ -14863,6 +14910,9 @@ Cursor::ActorDestroy(ActorDestroyReason aWhy)
|
||||
}
|
||||
|
||||
mBackgroundParent = nullptr;
|
||||
|
||||
mObjectStoreMetadata = nullptr;
|
||||
mIndexMetadata = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -14885,6 +14935,24 @@ Cursor::RecvContinue(const CursorRequestParams& aParams)
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != CursorRequestParams::T__None);
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
MOZ_ASSERT(mObjectStoreMetadata);
|
||||
MOZ_ASSERT_IF(mType == OpenCursorParams::TIndexOpenCursorParams ||
|
||||
mType == OpenCursorParams::TIndexOpenKeyCursorParams,
|
||||
mIndexMetadata);
|
||||
|
||||
const bool trustParams =
|
||||
#ifdef DEBUG
|
||||
// Always verify parameters in DEBUG builds!
|
||||
false
|
||||
#else
|
||||
mIsSameProcessActor
|
||||
#endif
|
||||
;
|
||||
|
||||
if (!trustParams && !VerifyRequestParams(aParams)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(mCurrentlyRunningOp)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
@ -14896,32 +14964,6 @@ Cursor::RecvContinue(const CursorRequestParams& aParams)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aParams.type() == CursorRequestParams::TContinueParams) {
|
||||
const Key& key = aParams.get_ContinueParams().key();
|
||||
if (!key.IsUnset()) {
|
||||
switch (mDirection) {
|
||||
case IDBCursor::NEXT:
|
||||
case IDBCursor::NEXT_UNIQUE:
|
||||
if (NS_WARN_IF(key <= mKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDBCursor::PREV:
|
||||
case IDBCursor::PREV_UNIQUE:
|
||||
if (NS_WARN_IF(key >= mKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mTransaction->IsInvalidated()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -207,6 +207,31 @@ IDBCursor::DropJSObjects()
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
bool
|
||||
IDBCursor::IsSourceDeleted() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mTransaction);
|
||||
MOZ_ASSERT(mTransaction->IsOpen());
|
||||
|
||||
IDBObjectStore* sourceObjectStore;
|
||||
if (mType == Type_Index || mType == Type_IndexKey) {
|
||||
MOZ_ASSERT(mSourceIndex);
|
||||
|
||||
if (mSourceIndex->IsDeleted()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sourceObjectStore = mSourceIndex->ObjectStore();
|
||||
MOZ_ASSERT(sourceObjectStore);
|
||||
} else {
|
||||
MOZ_ASSERT(mSourceObjectStore);
|
||||
sourceObjectStore = mSourceObjectStore;
|
||||
}
|
||||
|
||||
return sourceObjectStore->IsDeleted();
|
||||
}
|
||||
|
||||
void
|
||||
IDBCursor::Reset()
|
||||
{
|
||||
@ -392,7 +417,7 @@ IDBCursor::Continue(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mHaveValue || mContinueCalled) {
|
||||
if (IsSourceDeleted() || !mHaveValue || mContinueCalled) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
@ -468,18 +493,19 @@ IDBCursor::Advance(uint32_t aCount, ErrorResult &aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (!aCount) {
|
||||
aRv.ThrowTypeError(MSG_INVALID_ADVANCE_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mTransaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mHaveValue || mContinueCalled) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aCount) {
|
||||
aRv.ThrowTypeError(MSG_INVALID_ADVANCE_COUNT);
|
||||
if (IsSourceDeleted() || !mHaveValue || mContinueCalled) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -531,13 +557,16 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mHaveValue || mType == Type_ObjectStoreKey || mType == Type_IndexKey) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
if (!mTransaction->IsWriteAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mTransaction->IsWriteAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
|
||||
if (IsSourceDeleted() ||
|
||||
!mHaveValue ||
|
||||
mType == Type_ObjectStoreKey ||
|
||||
mType == Type_IndexKey) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -645,13 +674,16 @@ IDBCursor::Delete(JSContext* aCx, ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mHaveValue || mType == Type_ObjectStoreKey || mType == Type_IndexKey) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
if (!mTransaction->IsWriteAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mTransaction->IsWriteAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
|
||||
if (IsSourceDeleted() ||
|
||||
!mHaveValue ||
|
||||
mType == Type_ObjectStoreKey ||
|
||||
mType == Type_IndexKey) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -196,6 +196,9 @@ private:
|
||||
|
||||
void
|
||||
DropJSObjects();
|
||||
|
||||
bool
|
||||
IsSourceDeleted() const;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
|
@ -168,6 +168,14 @@ public:
|
||||
void
|
||||
NoteDeletion();
|
||||
|
||||
bool
|
||||
IsDeleted() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return !!mDeletedMetadata;
|
||||
}
|
||||
|
||||
void
|
||||
AssertIsOnOwningThread() const
|
||||
#ifdef DEBUG
|
||||
|
@ -268,6 +268,14 @@ public:
|
||||
void
|
||||
NoteDeletion();
|
||||
|
||||
bool
|
||||
IsDeleted() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return !!mDeletedSpec;
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
[idbcursor_advance_index9.htm]
|
||||
type: testharness
|
||||
[IDBCursor.advance() - index - throw InvalidStateError caused by object store been deleted]
|
||||
expected: FAIL
|
||||
|
@ -1,5 +0,0 @@
|
||||
[idbcursor_advance_objectstore5.htm]
|
||||
type: testharness
|
||||
[IDBCursor.advance() - object store - throw InvalidStateError caused by object store been deleted]
|
||||
expected: FAIL
|
||||
|
@ -1,5 +0,0 @@
|
||||
[idbcursor_continue_index8.htm]
|
||||
type: testharness
|
||||
[IDBCursor.continue() - index - throw InvalidStateError caused by object store been deleted]
|
||||
expected: FAIL
|
||||
|
@ -1,5 +0,0 @@
|
||||
[idbcursor_continue_objectstore6.htm]
|
||||
type: testharness
|
||||
[IDBCursor.continue() - object store - throw InvalidStateError caused by object store been deleted]
|
||||
expected: FAIL
|
||||
|
Loading…
Reference in New Issue
Block a user