Skip to content

Commit

Permalink
hardening sqlite code
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhill committed May 28, 2015
1 parent 4c9d3f6 commit c285ace
Showing 1 changed file with 76 additions and 34 deletions.
110 changes: 76 additions & 34 deletions platform/firefox/vapi-background.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ vAPI.storage = (function() {
if ( db === null ) {
return;
}
db.createStatement('VACUUM').executeAsync();
db.createAsyncStatement('VACUUM').executeAsync();
db.asyncClose();
db = null;
};

var open = function() {
if ( db !== null ) {
return;
return db;
}

// Create path
Expand All @@ -125,14 +125,27 @@ vAPI.storage = (function() {
path.append(location.host + '.sqlite');

// Open database
db = Services.storage.openDatabase(path);
try {
db = Services.storage.openDatabase(path);
if ( db.connectionReady === false ) {
db.asyncClose();
db = null;
}
} catch (ex) {
}

if ( db === null ) {
return null;
}

// Database was opened, register cleanup task
cleanupTasks.push(close);

// Setup database
db.createAsyncStatement('CREATE TABLE IF NOT EXISTS settings(name TEXT PRIMARY KEY NOT NULL, value TEXT);')
.executeAsync();

return db;
};

// Execute a query
Expand Down Expand Up @@ -160,6 +173,10 @@ vAPI.storage = (function() {
},
handleError: function(error) {
console.error('SQLite error ', error.result, error.message);
// Caller expects an answer regardless of failure.
if ( typeof callback === 'function' ) {
callback(null);
}
}
});
};
Expand All @@ -179,27 +196,31 @@ vAPI.storage = (function() {
};

var clear = function(callback) {
if ( db === null ) {
open();
if ( open() === null ) {
if ( typeof callback === 'function' ) {
callback();
}
return;
}
runStatement(db.createStatement('DELETE FROM settings; VACUUM;'), callback);
runStatement(db.createAsyncStatement('DELETE FROM settings; VACUUM;'), callback);
};

var getBytesInUse = function(keys, callback) {
if ( typeof callback !== 'function' ) {
return;
}

if ( db === null ) {
open();
if ( open() === null ) {
callback(0);
return;
}

var stmt;
if ( Array.isArray(keys) ) {
stmt = db.createStatement('SELECT "size" AS size, SUM(LENGTH(value)) FROM settings WHERE name = :name');
stmt = db.createAsyncStatement('SELECT "size" AS size, SUM(LENGTH(value)) FROM settings WHERE name = :name');
bindNames(keys);
} else {
stmt = db.createStatement('SELECT "size" AS size, SUM(LENGTH(value)) FROM settings');
stmt = db.createAsyncStatement('SELECT "size" AS size, SUM(LENGTH(value)) FROM settings');
}

runStatement(stmt, function(result) {
Expand All @@ -212,8 +233,27 @@ vAPI.storage = (function() {
return;
}

if ( db === null ) {
open();
var prepareResult = function(result) {
var key;
for ( key in result ) {
if ( result.hasOwnProperty(key) === false ) {
continue;
}
result[key] = JSON.parse(result[key]);
}
if ( typeof details === 'object' && details !== null ) {
for ( key in details ) {
if ( result.hasOwnProperty(key) === false ) {
result[key] = details[key];
}
}
}
callback(result);
};

if ( open() === null ) {
prepareResult({});
return;
}

var names = [];
Expand All @@ -229,43 +269,36 @@ vAPI.storage = (function() {

var stmt;
if ( names.length === 0 ) {
stmt = db.createStatement('SELECT * FROM settings');
stmt = db.createAsyncStatement('SELECT * FROM settings');
} else {
stmt = db.createStatement('SELECT * FROM settings WHERE name = :name');
stmt = db.createAsyncStatement('SELECT * FROM settings WHERE name = :name');
bindNames(stmt, names);
}

runStatement(stmt, function(result) {
var key;
for ( key in result ) {
result[key] = JSON.parse(result[key]);
}
if ( typeof details === 'object' && details !== null ) {
for ( key in details ) {
if ( result.hasOwnProperty(key) === false ) {
result[key] = details[key];
}
}
}
callback(result);
});
runStatement(stmt, prepareResult);
};

var remove = function(keys, callback) {
if ( db === null ) {
open();
if ( open() === null ) {
if ( typeof callback === 'function' ) {
callback();
}
return;
}
var stmt = db.createStatement('DELETE FROM settings WHERE name = :name');
var stmt = db.createAsyncStatement('DELETE FROM settings WHERE name = :name');
bindNames(stmt, typeof keys === 'string' ? [keys] : keys);
runStatement(stmt, callback);
};

var write = function(details, callback) {
if ( db === null ) {
open();
if ( open() === null ) {
if ( typeof callback === 'function' ) {
callback();
}
return;
}

var stmt = db.createStatement('INSERT OR REPLACE INTO settings (name, value) VALUES(:name, :value)');
var stmt = db.createAsyncStatement('INSERT OR REPLACE INTO settings (name, value) VALUES(:name, :value)');
var params = stmt.newBindingParamsArray(), bp;
for ( var key in details ) {
if ( details.hasOwnProperty(key) === false ) {
Expand Down Expand Up @@ -1080,6 +1113,7 @@ var httpObserver = {
this.tabId = 0;
this._key = ''; // key is url, from URI.spec
},

// If all work fine, this map should not grow indefinitely. It can have
// stale items in it, but these will be taken care of when entries in
// the ring buffer are overwritten.
Expand All @@ -1094,6 +1128,7 @@ var httpObserver = {
this.pendingRingBuffer[i] = new this.PendingRequest();
}
},

createPendingRequest: function(url) {
var bucket;
var i = this.pendingWritePointer;
Expand Down Expand Up @@ -1126,6 +1161,7 @@ var httpObserver = {
preq._key = url;
return preq;
},

lookupPendingRequest: function(url) {
var i = this.pendingURLToIndex.get(url);
if ( i === undefined ) {
Expand Down Expand Up @@ -1232,6 +1268,7 @@ var httpObserver = {
parentFrameId: channelData[1],
responseHeaders: result ? [{name: topic, value: result}] : [],
tabId: channelData[3],
type: this.typeMap[channelData[4]] || 'other',
url: URI.asciiSpec
});

Expand Down Expand Up @@ -1402,6 +1439,11 @@ vAPI.net.registerListeners = function() {
var browser = e.target;
var tabId = vAPI.tabs.getTabId(browser);

// Ignore notifications related to our popup
if ( details.url.lastIndexOf(vAPI.getURL('popup.html'), 0) === 0 ) {
return;
}

//console.debug("nsIWebProgressListener: onLocationChange: " + details.url + " (" + details.flags + ")");

// LOCATION_CHANGE_SAME_DOCUMENT = "did not load a new document"
Expand Down

1 comment on commit c285ace

@gorhill
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case somebody read this, the changes here are to address AMO reviewer's feedback:

After installing I got in the Browser Console following error:
NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [mozIStorageConnection.createStatement] vapi-background.js:234:0 (
(chrome//ublock/content/js/vapi-background.js)

However I haven't been able to reproduce this. If anybody can reproduce, please let me know, as currently I am working on a fix in blind mode since I can't reproduce. In the commit here I am assuming that in the reviewer's case, the connectionReady flag was false (for whatever reason).

Please sign in to comment.