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.

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

mercurial