diff --git a/src/js/background.js b/src/js/background.js index 6f537ff8a..8d295a3ea 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -145,6 +145,16 @@ const µBlock = (( ) => { // jshint ignore:line selfieMagic: 23, // Increase when selfie format changes }, + // https://github.com/uBlockOrigin/uBlock-issues/issues/759#issuecomment-546654501 + // The assumption is that cache storage state reflects whether + // compiled or selfie assets are available or not. The properties + // below is to no longer rely on this assumption -- though it's still + // not clear how the assumption could be wrong, and it's still not + // clear whether relying on those properties will really solve the + // issue. It's just an attempt at hardening. + compiledFormatChanged: false, + selfieIsInvalid: false, + restoreBackupSettings: { lastRestoreFile: '', lastRestoreTime: 0, diff --git a/src/js/start.js b/src/js/start.js index a52e9c78b..fcf513949 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -173,15 +173,15 @@ const onUserSettingsReady = function(fetched) { // Housekeeping, as per system setting changes const onSystemSettingsReady = function(fetched) { - let mustSaveSystemSettings = false; if ( fetched.compiledMagic !== µb.systemSettings.compiledMagic ) { µb.assets.remove(/^compiled\//); - mustSaveSystemSettings = true; + µb.compiledFormatChanged = true; + µb.selfieIsInvalid = true; } if ( fetched.selfieMagic !== µb.systemSettings.selfieMagic ) { - mustSaveSystemSettings = true; + µb.selfieIsInvalid = true; } - if ( mustSaveSystemSettings ) { + if ( µb.selfieIsInvalid ) { fetched.selfie = null; µb.selfieManager.destroy(); vAPI.storage.set(µb.systemSettings); diff --git a/src/js/storage.js b/src/js/storage.js index e78ef1cab..084ca98f4 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -638,6 +638,7 @@ this.selfieManager.destroy(); this.lz4Codec.relinquish(); + this.compiledFormatChanged = false; loadingPromise = undefined; }; @@ -712,10 +713,12 @@ µBlock.getCompiledFilterList = async function(assetKey) { const compiledPath = 'compiled/' + assetKey; - let compiledDetails = await this.assets.get(compiledPath); - if ( compiledDetails.content !== '' ) { - compiledDetails.assetKey = assetKey; - return compiledDetails; + if ( this.compiledFormatChanged === false ) { + let compiledDetails = await this.assets.get(compiledPath); + if ( compiledDetails.content !== '' ) { + compiledDetails.assetKey = assetKey; + return compiledDetails; + } } const rawDetails = await this.assets.get(assetKey); @@ -730,7 +733,7 @@ // Fetching the raw content may cause the compiled content to be // generated somewhere else in uBO, hence we try one last time to // fetch the compiled content in case it has become available. - compiledDetails = await this.assets.get(compiledPath); + let compiledDetails = await this.assets.get(compiledPath); if ( compiledDetails.content === '' ) { compiledDetails.content = this.compileFilters( rawDetails.content, @@ -1053,6 +1056,7 @@ ), ]); µb.lz4Codec.relinquish(); + µb.selfieIsInvalid = false; }; const loadMain = async function() { @@ -1080,7 +1084,7 @@ }; const load = async function() { - if ( destroyTimer !== undefined ) { + if ( µb.selfieIsInvalid ) { return false; } try { @@ -1108,6 +1112,7 @@ const destroy = function() { µb.cacheStorage.remove('selfie'); // TODO: obsolete, remove eventually. µb.assets.remove(/^selfie\//); + µb.selfieIsInvalid = true; createTimer = vAPI.setTimeout(( ) => { createTimer = undefined; create(); @@ -1127,6 +1132,7 @@ }, 1019 ); + µb.selfieIsInvalid = true; }; return { load, destroy: destroyAsync };