/******************************************************************************* ηMatrix - a browser extension to black/white list requests. Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors Copyright (C) 2019-2020 Alessio Vanni This program 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. This program 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 this program. If not, see {http://www.gnu.org/licenses/}. Home: https://libregit.spks.xyz/heckyel/ematrix uMatrix Home: https://github.com/gorhill/uMatrix */ 'use strict'; Components.utils.import('chrome://ematrix/content/lib/UriTools.jsm'); var EXPORTED_SYMBOLS = ['CookieCache', 'CookieUtils']; var junkyard = []; var dict = new Map(); var CookieEntry = function (cookie) { this.usedOn = new Set(); this.init(cookie); }; CookieEntry.prototype.init = function (cookie) { this.secure = cookie.secure; this.session = cookie.session; this.anySubdomain = cookie.domain.charAt(0) === '.'; this.hostname = this.anySubdomain ? cookie.domain.slice(1) : cookie.domain; this.domain = UriTools.domainFromHostname(this.hostname) || this.hostname; this.path = cookie.path; this.name = cookie.name; this.value = cookie.value; this.tstamp = Date.now(); this.usedOn.clear(); return this; }; CookieEntry.prototype.dispose = function () { this.hostname = ''; this.domain = ''; this.path = ''; this.name = ''; this.value = ''; this.usedOn.clear(); return this; }; var CookieUtils = { keyFromCookie: function (cookie) { let cb = []; cb[0] = cookie.secure ? 'https' : 'http'; cb[1] = '://'; cb[2] = cookie.domain.charAt(0) === '.' ? cookie.domain.slice(1) : cookie.domain; cb[3] = cookie.path; cb[4] = '{'; cb[5] = cookie.session ? 'session' : 'persistent'; cb[6] = '-cookie:'; cb[7] = cookie.name; cb[8] = '}'; return cb.join(''); }, keyFromURL: function (url, type, name) { if (typeof url !== 'object') { throw new Error('Invalid URL parameter'); } let cb = []; cb[0] = url.scheme; cb[1] = '://'; cb[2] = url.hostname; cb[3] = url.path; cb[4] = '{'; cb[5] = type; cb[6] = '-cookie:'; cb[7] = name; cb[8] = '}'; return cb.join(''); }, urlFromEntry: function (entry) { if (!entry) { return ''; } return (entry.secure ? 'https://' : 'http://') + entry.hostname + entry.path; }, matchDomains: function (key, allHosts) { let entry = CookieCache.get(key); if (entry === undefined) { return false; } if (allHosts.indexOf(' '+entry.hostname+' ') < 0) { if (!entry.anySubdomain) { return false; } if (allHosts.indexOf('.'+entry.hostname+' ') < 0) { return false; } } return true; }, }; var CookieCache = { add: function (cookie) { let key = CookieUtils.keyFromCookie(cookie); let value = dict.get(key); if (value === undefined) { value = junkyard.pop(); if (value) { value.init(cookie); } else { value = new CookieEntry(cookie); } dict.set(key, value); } return value; }, addVector: function (vector) { for (let i=vector.length-1; i>=0; --i) { CookieCache.add(vector[i]); } }, remove: function (cookie) { let value = dict.get(cookie); if (value === undefined) { return false; } dict.delete(cookie); if (junkyard.length < 25) { junkyard.push(value.dispose()); } return true; }, get: function (key) { return dict.get(key); }, keys: function () { return dict.keys(); } };