Backout d6efd06ceb84 (bug 828992) for assertions on a CLOSED TREE

This commit is contained in:
Ed Morley 2013-01-11 14:30:05 +00:00
Родитель 34abe91f47
Коммит 3326161473
9 изменённых файлов: 123 добавлений и 498 удалений

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

@ -52,29 +52,6 @@ using namespace mozilla::dom;
using namespace mozilla::dom::indexedDB::ipc;
using mozilla::dom::quota::FileOutputStream;
BEGIN_INDEXEDDB_NAMESPACE
struct FileHandleData
{
nsString type;
nsString name;
};
struct BlobOrFileData
{
BlobOrFileData()
: tag(0), size(0), lastModifiedDate(UINT64_MAX)
{ }
uint32_t tag;
uint64_t size;
nsString type;
nsString name;
uint64_t lastModifiedDate;
};
END_INDEXEDDB_NAMESPACE
namespace {
inline
@ -651,187 +628,6 @@ ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aContentType,
return true;
}
class MainThreadDeserializationTraits
{
public:
static JSObject* CreateAndWrapFileHandle(JSContext* aCx,
IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const FileHandleData& aData)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<FileInfo>& fileInfo = aFile.mFileInfo;
nsRefPtr<IDBFileHandle> fileHandle = IDBFileHandle::Create(aDatabase,
aData.name, aData.type, fileInfo.forget());
jsval wrappedFileHandle;
nsresult rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
static_cast<nsIDOMFileHandle*>(fileHandle),
&NS_GET_IID(nsIDOMFileHandle),
&wrappedFileHandle);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return JSVAL_TO_OBJECT(wrappedFileHandle);
}
static JSObject* CreateAndWrapBlobOrFile(JSContext* aCx,
IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const BlobOrFileData& aData)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aData.tag == SCTAG_DOM_BLOB);
nsresult rv = NS_OK;
nsRefPtr<FileInfo>& fileInfo = aFile.mFileInfo;
nsCOMPtr<nsIFile> nativeFile;
if (!aFile.mFile) {
FileManager* fileManager = aDatabase->Manager();
NS_ASSERTION(fileManager, "This should never be null!");
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
if (!directory) {
NS_WARNING("Failed to get directory!");
return nullptr;
}
nativeFile = fileManager->GetFileForId(directory, fileInfo->Id());
if (!nativeFile) {
NS_WARNING("Failed to get file!");
return nullptr;
}
}
if (aData.tag == SCTAG_DOM_BLOB) {
nsCOMPtr<nsIDOMBlob> domBlob;
if (aFile.mFile) {
if (!ResolveMysteryBlob(aFile.mFile, aData.type, aData.size)) {
return nullptr;
}
domBlob = aFile.mFile;
}
else {
domBlob = new nsDOMFileFile(aData.type, aData.size, nativeFile,
fileInfo);
}
jsval wrappedBlob;
rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domBlob,
&NS_GET_IID(nsIDOMBlob), &wrappedBlob);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return JSVAL_TO_OBJECT(wrappedBlob);
}
nsCOMPtr<nsIDOMFile> domFile;
if (aFile.mFile) {
if (!ResolveMysteryFile(aFile.mFile, aData.name, aData.type, aData.size,
aData.lastModifiedDate)) {
return nullptr;
}
domFile = do_QueryInterface(aFile.mFile);
NS_ASSERTION(domFile, "This should never fail!");
}
else {
domFile = new nsDOMFileFile(aData.name, aData.type, aData.size,
nativeFile, fileInfo);
}
jsval wrappedFile;
rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domFile,
&NS_GET_IID(nsIDOMFile), &wrappedFile);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return JSVAL_TO_OBJECT(wrappedFile);
}
};
class CreateIndexDeserializationTraits
{
public:
static JSObject* CreateAndWrapFileHandle(JSContext* aCx,
IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const FileHandleData& aData)
{
// FileHandle can't be used in index creation, so just make a dummy object.
return JS_NewObject(aCx, nullptr, nullptr, nullptr);
}
static JSObject* CreateAndWrapBlobOrFile(JSContext* aCx,
IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const BlobOrFileData& aData)
{
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aData.tag == SCTAG_DOM_BLOB);
// The following properties are available for use in index creation
// Blob.size
// Blob.type
// File.name
// File.lastModifiedDate
JSObject* obj = JS_NewObject(aCx, nullptr, nullptr, nullptr);
if (!obj) {
NS_WARNING("Failed to create object!");
return nullptr;
}
// Technically these props go on the proto, but this detail won't change
// the results of index creation.
JSString* type =
JS_NewUCStringCopyN(aCx, aData.type.get(), aData.type.Length());
if (!type ||
!JS_DefineProperty(aCx, obj, "size",
JS_NumberValue((double)aData.size),
nullptr, nullptr, 0) ||
!JS_DefineProperty(aCx, obj, "type", STRING_TO_JSVAL(type),
nullptr, nullptr, 0)) {
return nullptr;
}
if (aData.tag == SCTAG_DOM_BLOB) {
return obj;
}
JSString* name =
JS_NewUCStringCopyN(aCx, aData.name.get(), aData.name.Length());
JSObject* date = JS_NewDateObjectMsec(aCx, aData.lastModifiedDate);
if (!name || !date ||
!JS_DefineProperty(aCx, obj, "name", STRING_TO_JSVAL(name),
nullptr, nullptr, 0) ||
!JS_DefineProperty(aCx, obj, "lastModifiedDate", OBJECT_TO_JSVAL(date),
nullptr, nullptr, 0)) {
return nullptr;
}
return obj;
}
};
} // anonymous namespace
JSClass IDBObjectStore::sDummyPropJSClass = {
@ -1207,7 +1003,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
JSAutoRequest ar(aCx);
JSStructuredCloneCallbacks callbacks = {
IDBObjectStore::StructuredCloneReadCallback<MainThreadDeserializationTraits>,
IDBObjectStore::StructuredCloneReadCallback,
nullptr,
nullptr
};
@ -1294,87 +1090,6 @@ StructuredCloneReadString(JSStructuredCloneReader* aReader,
}
// static
bool
IDBObjectStore::ReadFileHandle(JSStructuredCloneReader* aReader,
FileHandleData* aRetval)
{
MOZ_STATIC_ASSERT(SCTAG_DOM_FILEHANDLE == 0xFFFF8004,
"Update me!");
MOZ_ASSERT(aReader && aRetval);
nsCString type;
if (!StructuredCloneReadString(aReader, type)) {
return false;
}
CopyUTF8toUTF16(type, aRetval->type);
nsCString name;
if (!StructuredCloneReadString(aReader, name)) {
return false;
}
CopyUTF8toUTF16(name, aRetval->name);
return true;
}
// static
bool
IDBObjectStore::ReadBlobOrFile(JSStructuredCloneReader* aReader,
uint32_t aTag,
BlobOrFileData* aRetval)
{
MOZ_STATIC_ASSERT(SCTAG_DOM_BLOB == 0xFFFF8001 &&
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE == 0xFFFF8002 &&
SCTAG_DOM_FILE == 0xFFFF8005,
"Update me!");
MOZ_ASSERT(aReader && aRetval);
MOZ_ASSERT(aTag == SCTAG_DOM_FILE ||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aTag == SCTAG_DOM_FILE);
aRetval->tag = aTag;
// If it's not a FileHandle, it's a Blob or a File.
uint64_t size;
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
NS_WARNING("Failed to read size!");
return false;
}
aRetval->size = SwapBytes(size);
nsCString type;
if (!StructuredCloneReadString(aReader, type)) {
return false;
}
CopyUTF8toUTF16(type, aRetval->type);
// Blobs are done.
if (aTag == SCTAG_DOM_BLOB) {
return true;
}
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
uint64_t lastModifiedDate = UINT64_MAX;
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
NS_WARNING("Failed to read lastModifiedDate");
return false;
}
aRetval->lastModifiedDate = lastModifiedDate;
nsCString name;
if (!StructuredCloneReadString(aReader, name)) {
return false;
}
CopyUTF8toUTF16(name, aRetval->name);
return true;
}
// static
template <class DeserializationTraits>
JSObject*
IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
JSStructuredCloneReader* aReader,
@ -1403,26 +1118,137 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
return nullptr;
}
nsresult rv;
StructuredCloneFile& file = cloneReadInfo->mFiles[aData];
nsRefPtr<FileInfo>& fileInfo = file.mFileInfo;
IDBDatabase* database = cloneReadInfo->mDatabase;
if (aTag == SCTAG_DOM_FILEHANDLE) {
FileHandleData data;
if (!ReadFileHandle(aReader, &data)) {
nsCString type;
if (!StructuredCloneReadString(aReader, type)) {
return nullptr;
}
NS_ConvertUTF8toUTF16 convType(type);
nsCString name;
if (!StructuredCloneReadString(aReader, name)) {
return nullptr;
}
NS_ConvertUTF8toUTF16 convName(name);
nsRefPtr<IDBFileHandle> fileHandle = IDBFileHandle::Create(database,
convName, convType, fileInfo.forget());
jsval wrappedFileHandle;
rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
static_cast<nsIDOMFileHandle*>(fileHandle),
&NS_GET_IID(nsIDOMFileHandle),
&wrappedFileHandle);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return DeserializationTraits::CreateAndWrapFileHandle(aCx, database,
file, data);
return JSVAL_TO_OBJECT(wrappedFileHandle);
}
BlobOrFileData data;
if (!ReadBlobOrFile(aReader, aTag, &data)) {
// If it's not a FileHandle, it's a Blob or a File.
uint64_t size;
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
NS_WARNING("Failed to read size!");
return nullptr;
}
size = SwapBytes(size);
nsCString type;
if (!StructuredCloneReadString(aReader, type)) {
return nullptr;
}
NS_ConvertUTF8toUTF16 convType(type);
nsCOMPtr<nsIFile> nativeFile;
if (!file.mFile) {
FileManager* fileManager = database->Manager();
NS_ASSERTION(fileManager, "This should never be null!");
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
if (!directory) {
NS_WARNING("Failed to get directory!");
return nullptr;
}
nativeFile = fileManager->GetFileForId(directory, fileInfo->Id());
if (!nativeFile) {
NS_WARNING("Failed to get file!");
return nullptr;
}
}
if (aTag == SCTAG_DOM_BLOB) {
nsCOMPtr<nsIDOMBlob> domBlob;
if (file.mFile) {
if (!ResolveMysteryBlob(file.mFile, convType, size)) {
return nullptr;
}
domBlob = file.mFile;
}
else {
domBlob = new nsDOMFileFile(convType, size, nativeFile, fileInfo);
}
jsval wrappedBlob;
rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domBlob,
&NS_GET_IID(nsIDOMBlob), &wrappedBlob);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return JSVAL_TO_OBJECT(wrappedBlob);
}
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
uint64_t lastModifiedDate = UINT64_MAX;
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
NS_WARNING("Failed to read lastModifiedDate");
return nullptr;
}
return DeserializationTraits::CreateAndWrapBlobOrFile(aCx, database,
file, data);
nsCString name;
if (!StructuredCloneReadString(aReader, name)) {
return nullptr;
}
NS_ConvertUTF8toUTF16 convName(name);
nsCOMPtr<nsIDOMFile> domFile;
if (file.mFile) {
if (!ResolveMysteryFile(file.mFile, convName, convType, size, lastModifiedDate)) {
return nullptr;
}
domFile = do_QueryInterface(file.mFile);
NS_ASSERTION(domFile, "This should never fail!");
}
else {
domFile = new nsDOMFileFile(convName, convType, size, nativeFile,
fileInfo);
}
jsval wrappedFile;
rv =
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domFile,
&NS_GET_IID(nsIDOMFile), &wrappedFile);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to wrap native!");
return nullptr;
}
return JSVAL_TO_OBJECT(wrappedFile);
}
const JSStructuredCloneCallbacks* runtimeCallbacks =
@ -3803,7 +3629,7 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
JSAutoStructuredCloneBuffer& buffer = cloneReadInfo.mCloneBuffer;
JSStructuredCloneCallbacks callbacks = {
IDBObjectStore::StructuredCloneReadCallback<CreateIndexDeserializationTraits>,
IDBObjectStore::StructuredCloneReadCallback,
nullptr,
nullptr
};

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

@ -44,9 +44,6 @@ struct IndexInfo;
struct IndexUpdateInfo;
struct ObjectStoreInfo;
struct FileHandleData;
struct BlobOrFileData;
class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
{
public:
@ -101,7 +98,6 @@ public:
StructuredCloneWriteInfo& aCloneWriteInfo,
jsval aValue);
template <class DeserializationTraits>
static JSObject*
StructuredCloneReadCallback(JSContext* aCx,
JSStructuredCloneReader* aReader,
@ -273,14 +269,6 @@ protected:
static void
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
static bool
ReadFileHandle(JSStructuredCloneReader* aReader,
FileHandleData* aRetval);
static bool
ReadBlobOrFile(JSStructuredCloneReader* aReader,
uint32_t aTag,
BlobOrFileData* aRetval);
private:
nsRefPtr<IDBTransaction> mTransaction;

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

@ -141,7 +141,7 @@ GetJSValFromKeyPathString(JSContext* aCx,
// If the property doesn't exist, fall into below path of starting
// to define properties, if allowed.
if (aOptions == DoNotCreateProperties) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
return NS_OK;
}
targetObject = obj;

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

@ -73,7 +73,6 @@ MOCHITEST_FILES = \
test_index_update_delete.html \
test_indexes.html \
test_indexes_bad_values.html \
test_indexes_funny_things.html \
test_key_requirements.html \
test_keys.html \
test_leaving_page.html \

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

@ -1,18 +0,0 @@
<!--
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="/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_indexes_funny_things.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

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

@ -35,7 +35,6 @@ MOCHITEST_FILES = \
test_index_update_delete.js \
test_indexes.js \
test_indexes_bad_values.js \
test_indexes_funny_things.js \
test_key_requirements.js \
test_keys.js \
test_multientry.js \

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

@ -7,7 +7,7 @@ var testGenerator = testSteps();
function testSteps()
{
const name = this.window ? window.location.pathname : "Splendid Test";
const name = this.window ? this.window ? window.location.pathname : "Splendid Test" : "Splendid Test";
const objectStoreName = "People";

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

@ -1,168 +0,0 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
// Blob constructor is not implemented outside of windows yet (Bug 827723).
if (!this.window) {
finishTest();
yield;
}
const name = this.window ? window.location.pathname : "Splendid Test";
const objectStoreName = "Things";
const blob1 = new Blob(["foo", "bar"], { type: "text/plain" });
const blob2 = new Blob(["foobazybar"], { type: "text/plain" });
const blob3 = new Blob(["2"], { type: "bogus/" });
const str = "The Book of Mozilla";
str.type = blob1;
const arr = [1, 2, 3, 4, 5];
const objectStoreData = [
{ key: "1", value: blob1},
{ key: "2", value: blob2},
{ key: "3", value: blob3},
{ key: "4", value: str},
{ key: "5", value: arr},
];
const indexData = [
{ name: "type", keyPath: "type", options: { } },
{ name: "length", keyPath: "length", options: { unique: true } }
];
const objectStoreDataTypeSort = [
{ key: "3", value: blob3},
{ key: "1", value: blob1},
{ key: "2", value: blob2},
];
const objectStoreDataLengthSort = [
{ key: "5", value: arr},
//{ key: "4", value: str},
];
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
// First, add all our data to the object store.
let addedData = 0;
for (let i in objectStoreData) {
request = objectStore.add(objectStoreData[i].value,
objectStoreData[i].key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
if (++addedData == objectStoreData.length) {
testGenerator.send(event);
}
}
}
event = yield;
// Now create the indexes.
for (let i in indexData) {
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
indexData[i].options);
}
is(objectStore.indexNames.length, indexData.length, "Good index count");
yield;
objectStore = db.transaction(objectStoreName)
.objectStore(objectStoreName);
// Check global properties to make sure they are correct.
is(objectStore.indexNames.length, indexData.length, "Good index count");
for (let i in indexData) {
let found = false;
for (let j = 0; j < objectStore.indexNames.length; j++) {
if (objectStore.indexNames.item(j) == indexData[i].name) {
found = true;
break;
}
}
is(found, true, "objectStore has our index");
let index = objectStore.index(indexData[i].name);
is(index.name, indexData[i].name, "Correct name");
is(index.storeName, objectStore.name, "Correct store name");
is(index.keyPath, indexData[i].keyPath, "Correct keyPath");
is(index.unique, indexData[i].options.unique ? true : false,
"Correct unique value");
}
ok(true, "Test group 1");
let keyIndex = 0;
request = objectStore.index("type").openKeyCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
"Correct key");
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
"Correct primary key");
ok(!("value" in cursor), "No value");
cursor.continue();
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
"Correct key");
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
"Correct value");
ok(!("value" in cursor), "No value");
keyIndex++;
}
else {
testGenerator.next();
}
}
yield;
is(keyIndex, objectStoreDataTypeSort.length, "Saw all the expected keys");
ok(true, "Test group 2");
keyIndex = 0;
request = objectStore.index("length").openKeyCursor(null, "next");
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
"Correct key");
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
"Correct value");
cursor.continue();
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
"Correct key");
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
"Correct value");
keyIndex++;
}
else {
testGenerator.next();
}
}
yield;
is(keyIndex, objectStoreDataLengthSort.length, "Saw all the expected keys");
finishTest();
yield;
}

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

@ -28,7 +28,6 @@ tail =
[test_index_update_delete.js]
[test_indexes.js]
[test_indexes_bad_values.js]
[test_indexes_funny_things.js]
[test_key_requirements.js]
[test_keys.js]
[test_multientry.js]