/** * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. * * * Copyright (C) 2011, 2012, 2013, 2014 Loic J. Duros * Copyright (C) 2014, 2015 Nik Nyby * * This file is part of GNU LibreJS. * * GNU LibreJS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GNU LibreJS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU LibreJS. If not, see . */ var relationCheckerObj = require("../js_checker/relation_checker") .relationChecker; // import free_libraries to populate the cache hash map. var free_libraries = require("../script_entries/free_libraries"); var crypto = require('./crypto'); const checkTypes = require("../js_checker/constant_types").checkTypes; // cachedResults contains objects with result/relationChecker for // scripts entries indexed by SHA1sum var cachedResults = {}; /** * ScriptsCached keeps a cache of whitelisted scripts in the browser * session. */ var ScriptsCached = function() { }; ScriptsCached.prototype.getHash = function(scriptText) { require('../ui/notification').createNotification( scriptText.substring(0,100)); return crypto.sha1Encrypt(scriptText); }; /** * resetCache * Resets the full cache and re-initialize * the free libraries list. */ ScriptsCached.prototype.resetCache = function () { cachedResults = {}; free_libraries.init(); }; /** * * addEntry * * Adds a script entry to the cache by providing the results * and the actual script text. * */ ScriptsCached.prototype.addEntry = function( scriptText, result, relationChecker, allowTrivial, url) { console.debug("result addEntry is", JSON.stringify(result)); cachedResults[this.getHash(scriptText)] = { 'result': result, 'relationChecker': relationCheckerObj(), 'allowTrivial': allowTrivial, 'url': url }; }; /** * * addEntry * * Adds a script entry to the cache by providing the results * using the script's hash. * */ ScriptsCached.prototype.addEntryByHash = function( hash, result, relationChecker, allowTrivial, url) { cachedResults[hash] = { 'result': result, 'relationChecker': relationCheckerObj(), 'allowTrivial': allowTrivial, 'url': url || '' }; }; /** * removeEntryByHash * * Remove an entry from the cache using hash key. */ ScriptsCached.prototype.removeEntryByHash = function(hash) { delete cachedResults[hash]; }; /** * addEntryIfNotCached * * Checks first if entry is cached before attempting to cache result. */ ScriptsCached.prototype.addEntryIfNotCached = function( scriptText, result, relationChecker, allowTrivial, url) { // save a bit of computing by getting hash once. var hash = this.getHash(scriptText); console.debug('hash is then', hash); if (!this.isCached(scriptText, hash)) { cachedResults[hash] = { 'result': result, 'relationChecker': relationCheckerObj(), 'allowTrivial': allowTrivial, 'url': url || '' }; } return hash; }; /** * * addObjectEntry * * Adds a script entry by providing an object. * Used to provide free library hashes from free_libraries.js * */ ScriptsCached.prototype.addObjectEntry = function(hash, script) { cachedResults[hash] = script; }; ScriptsCached.prototype.isCached = function(scriptText, hash) { var scriptHash; console.debug("Is CACHED start?"); try { if (typeof hash === 'string') { scriptHash = hash; } else { scriptHash = this.getHash(scriptText); } if (typeof scriptHash === 'string') { let cachedResult = cachedResults[scriptHash]; if (cachedResult) { // exact copy of file has already been cached. console.debug('scriptHash is', cachedResult); if (cachedResult.relationChecker == "[rl]") { cachedResult.relationChecker = {}; //relationCheckerObj(); } console.debug("Is Cached ENd TRUE"); return cachedResult; } } return false; } catch (e) { console.debug("an error", scriptHash, e, e.linenumber, e.filename); } }; /** * Writes allowed scripts to the cache. * nonfree/nontrivial scripts are not added to the cache. */ ScriptsCached.prototype.getCacheForWriting = function() { var formattedResults = {}; for (let item in cachedResults) { let type = cachedResults[item].result.type; if (type != checkTypes.NONTRIVIAL && type != checkTypes.TRIVIAL_DEFINES_FUNCTION ) { formattedResults[item] = cachedResults[item]; } } return formattedResults; }; /** * Import data from database into cachedResults. * Calling this function replaces the current cache if it exists. */ ScriptsCached.prototype.bulkImportCache = function(data) { cachedResults = data; console.debug("Imported data. Number of keys ISSS ", Object.keys(cachedResults).length); console.debug("It looks like ", JSON.stringify(cachedResults)); }; exports.scriptsCached = new ScriptsCached();