blob: afacb59650419796eecea6954609d1bf214c559c [file] [log] [blame]
function terminateTest()
{
if (window.testRunner)
testRunner.notifyDone();
}
function logAndTerminateTest(message, error)
{
log(message + ": " + error.message);
terminateTest();
}
function cleanup(db)
{
db.transaction(function(tx) {
tx.executeSql("DROP TABLE IF EXISTS Results;");
tx.executeSql("DROP TABLE IF EXISTS TempTable;");
tx.executeSql("DROP TRIGGER IF EXISTS TempTrigger;");
},
function(error) {
logAndTerminateTest("Cleanup failed", error);
});
}
function statementSuccessCallback(statementType)
{
log(statementType + " statement succeeded.");
}
function statementErrorCallback(statementType, error)
{
log(statementType + " statement failed: " + error.message);
return false;
}
function executeStatement(tx, statement, operation)
{
tx.executeSql(statement, [],
function(result) {
statementSuccessCallback(operation);
},
function(tx, error) {
return statementErrorCallback(operation, error);
});
}
function testCallbacks(tx)
{
executeStatement(tx, "CREATE TABLE Results (Key TEXT, Value TEXT);", "CREATE TABLE");
// Create a temporary table with the same schema as __WebKitDatabaseInfoTable__ and populate it with a valid version.
executeStatement(tx, "CREATE TEMPORARY TABLE TempTable (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);", "CREATE TEMP TABLE");
executeStatement(tx, "INSERT INTO TempTable VALUES ('WebKitDatabaseVersionKey','1.0');", "INSERT IN TEMP TABLE");
// Set up a trigger to capture changes to the table we just created.
executeStatement(tx, "CREATE TRIGGER TempTrigger BEFORE INSERT ON TempTable BEGIN INSERT INTO Results VALUES (NEW.key, NEW.value); END;", "CREATE TRIGGER");
// Try to spoof that table as the info table.
executeStatement(tx, "ALTER TABLE TempTable RENAME TO __WebKitDatabaseInfoTable__;", "ALTER TO INFO TABLE");
}
function testStep1(db)
{
db.transaction(function(tx) {
testCallbacks(tx);
},
function(error) {
logAndTerminateTest("Step 1 transaction failed", error);
},
function() {
log("Step 1 transaction succeeded.");
testStep2(db);
});
}
function testStep2(db)
{
// At this point there's a temporary table named the same as the internal info table.
// WebKit should not use it.
db.changeVersion('1.0', '2.0', null, function(error) {
log("Failed to change DB version - " + error.message);
},
function() {
log("Successfully changed DB version");
});
// If our trigger fired it will have captured the changed to the info table and put them in the results table.
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM Results;", [], function(tx, results) {
if (results.rows.length == 0)
return;
log("The Results table actually has stuff in it, and it shouldn't");
var result = results.rows.item(0);
for (n in result)
log(n + " " + result[n]);
});
},
function(error) {
logAndTerminateTest("Step 2 transaction failed", error);
},
function() {
log("Step 2 transaction succeeded.");
terminateTest();
});
}
function runTest()
{
var db = openDatabaseWithSuffix("AlterInfoTableTest", "1.0", "Tests altering the info table", 32768);
cleanup(db);
testStep1(db);
}