From 34a138e3efe9506e3ea4e8462b7c5280e3e28b6c Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 17 Mar 2019 09:45:28 -0400 Subject: [PATCH] Add `unlimitedStorage` to Firefox manifest; add timeout to IndexedDB access Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/416 The Chromium version of uBO has declared `unlimitedStorage` since the extension was first published in 2014. Declaring this permission in Firefox brings uBO inline with the Chromium version. I suspect some reported errors could be caused by IndexedDB eviction due to the lack of `unlimitedStorage` permission. Additionally, a timeout has been added when uBO tries to access its indexedDB storage. It's unclear whether this will help with the mentioned related issue though, the root cause is still to be identified. --- platform/firefox/manifest.json | 1 + src/js/cachestorage.js | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/platform/firefox/manifest.json b/platform/firefox/manifest.json index ace1bfca9..099030ffe 100644 --- a/platform/firefox/manifest.json +++ b/platform/firefox/manifest.json @@ -74,6 +74,7 @@ "privacy", "storage", "tabs", + "unlimitedStorage", "webNavigation", "webRequest", "webRequestBlocking", diff --git a/src/js/cachestorage.js b/src/js/cachestorage.js index e2b51ba0c..317980813 100644 --- a/src/js/cachestorage.js +++ b/src/js/cachestorage.js @@ -226,19 +226,30 @@ table.createIndex('value', 'value', { unique: false }); }; req.onsuccess = function(ev) { + if ( resolve === undefined ) { return; } req = undefined; db = ev.target.result; db.onerror = db.onabort = genericErrorHandler; dbPromise = undefined; resolve(db); + resolve = undefined; }; req.onerror = req.onblocked = function() { + if ( resolve === undefined ) { return; } req = undefined; console.log(this.error); db = null; dbPromise = undefined; resolve(null); + resolve = undefined; }; + setTimeout(( ) => { + if ( resolve === undefined ) { return; } + db = null; + dbPromise = undefined; + resolve(null); + resolve = undefined; + }, 5000); }); return dbPromise; }; @@ -246,8 +257,8 @@ const getFromDb = function(keys, keyvalStore, callback) { if ( typeof callback !== 'function' ) { return; } if ( keys.length === 0 ) { return callback(keyvalStore); } - let promises = []; - let gotOne = function() { + const promises = []; + const gotOne = function() { if ( typeof this.result !== 'object' ) { return; } keyvalStore[this.result.key] = this.result.value; if ( this.result.value instanceof Blob === false ) { return; } @@ -262,7 +273,7 @@ }; getDb().then(db => { if ( !db ) { return callback(); } - const transaction = db.transaction(STORAGE_NAME); + const transaction = db.transaction(STORAGE_NAME, 'readonly'); transaction.oncomplete = transaction.onerror = transaction.onabort = ( ) => { @@ -272,11 +283,13 @@ }; const table = transaction.objectStore(STORAGE_NAME); for ( const key of keys ) { - let req = table.get(key); + const req = table.get(key); req.onsuccess = gotOne; req.onerror = noopfn; - req = undefined; } + }).catch(reason => { + console.info(`cacheStorage.getFromDb() failed: ${reason}`); + callback(); }); };