dom/activities/src/ActivitiesServiceFilter.jsm

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict"
michael@0 6
michael@0 7 this.EXPORTED_SYMBOLS = ['ActivitiesServiceFilter'];
michael@0 8
michael@0 9 this.ActivitiesServiceFilter = {
michael@0 10 match: function(aValues, aFilters) {
michael@0 11
michael@0 12 function matchValue(aValue, aFilter, aFilterObj) {
michael@0 13 if (aFilter !== null) {
michael@0 14 // Custom functions for the different types.
michael@0 15 switch (typeof(aFilter)) {
michael@0 16 case 'boolean':
michael@0 17 return aValue === aFilter;
michael@0 18
michael@0 19 case 'number':
michael@0 20 return Number(aValue) === aFilter;
michael@0 21
michael@0 22 case 'string':
michael@0 23 return String(aValue) === aFilter;
michael@0 24
michael@0 25 default: // not supported
michael@0 26 return false;
michael@0 27 }
michael@0 28 }
michael@0 29
michael@0 30 // Pattern.
michael@0 31 if (('pattern' in aFilterObj)) {
michael@0 32 var pattern = String(aFilterObj.pattern);
michael@0 33
michael@0 34 var patternFlags = '';
michael@0 35 if (('patternFlags' in aFilterObj)) {
michael@0 36 patternFlags = String(aFilterObj.patternFlags);
michael@0 37 }
michael@0 38
michael@0 39 var re = new RegExp('^(?:' + pattern + ')$', patternFlags);
michael@0 40 return re.test(aValue);
michael@0 41 }
michael@0 42
michael@0 43 // Validation of the min/Max.
michael@0 44 if (('min' in aFilterObj) || ('max' in aFilterObj)) {
michael@0 45 // Min value.
michael@0 46 if (('min' in aFilterObj) &&
michael@0 47 aFilterObj.min > aValue) {
michael@0 48 return false;
michael@0 49 }
michael@0 50
michael@0 51 // Max value.
michael@0 52 if (('max' in aFilterObj) &&
michael@0 53 aFilterObj.max < aValue) {
michael@0 54 return false;
michael@0 55 }
michael@0 56 }
michael@0 57
michael@0 58 return true;
michael@0 59 }
michael@0 60
michael@0 61 // this function returns true if the value matches with the filter object
michael@0 62 function matchObject(aValue, aFilterObj) {
michael@0 63
michael@0 64 // Let's consider anything an array.
michael@0 65 let filters = ('value' in aFilterObj)
michael@0 66 ? (Array.isArray(aFilterObj.value)
michael@0 67 ? aFilterObj.value
michael@0 68 : [aFilterObj.value])
michael@0 69 : [ null ];
michael@0 70 let values = Array.isArray(aValue) ? aValue : [aValue];
michael@0 71
michael@0 72 for (var filterId = 0; filterId < filters.length; ++filterId) {
michael@0 73 for (var valueId = 0; valueId < values.length; ++valueId) {
michael@0 74 if (matchValue(values[valueId], filters[filterId], aFilterObj)) {
michael@0 75 return true;
michael@0 76 }
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 return false;
michael@0 81 }
michael@0 82
michael@0 83 // Creation of a filter map useful to know what has been
michael@0 84 // matched and what is not.
michael@0 85 let filtersMap = {}
michael@0 86 for (let filter in aFilters) {
michael@0 87 // Convert this filter in an object if needed
michael@0 88 let filterObj = aFilters[filter];
michael@0 89
michael@0 90 if (Array.isArray(filterObj) || typeof(filterObj) !== 'object') {
michael@0 91 filterObj = {
michael@0 92 required: false,
michael@0 93 value: filterObj
michael@0 94 }
michael@0 95 }
michael@0 96
michael@0 97 filtersMap[filter] = { filter: filterObj,
michael@0 98 found: false };
michael@0 99 }
michael@0 100
michael@0 101 // For any incoming property.
michael@0 102 for (let prop in aValues) {
michael@0 103 // If this is unknown for the app, let's continue.
michael@0 104 if (!(prop in filtersMap)) {
michael@0 105 continue;
michael@0 106 }
michael@0 107
michael@0 108 if (Array.isArray(aValues[prop]) && aValues[prop].length == 0) {
michael@0 109 continue;
michael@0 110 }
michael@0 111
michael@0 112 // Otherwise, let's check the value against the filter.
michael@0 113 if (!matchObject(aValues[prop], filtersMap[prop].filter)) {
michael@0 114 return false;
michael@0 115 }
michael@0 116
michael@0 117 filtersMap[prop].found = true;
michael@0 118 }
michael@0 119
michael@0 120 // Required filters:
michael@0 121 for (let filter in filtersMap) {
michael@0 122 if (filtersMap[filter].filter.required && !filtersMap[filter].found) {
michael@0 123 return false;
michael@0 124 }
michael@0 125 }
michael@0 126
michael@0 127 return true;
michael@0 128 }
michael@0 129 }

mercurial