This file is indexed.

/usr/share/gnome-shell/js/misc/hash.js is in gnome-shell-common 3.10.4-0ubuntu5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-

const Lang = imports.lang;
const System = imports.system;

const Params = imports.misc.params;

// This is an implementation of EcmaScript SameValue algorithm,
// which returns true if two values are not observably distinguishable.
// It was taken from http://wiki.ecmascript.org/doku.php?id=harmony:egal
//
// In the future, we may want to use the 'is' operator instead.
function _sameValue(x, y) {
    if (x === y) {
        // 0 === -0, but they are not identical
        return x !== 0 || 1 / x === 1 / y;
    }

    // NaN !== NaN, but they are identical.
    // NaNs are the only non-reflexive value, i.e., if x !== x,
    // then x is a NaN.
    // isNaN is broken: it converts its argument to number, so
    // isNaN("foo") => true
    return x !== x && y !== y;
}

const _hashers = {
    object: function(o) { return o ? System.addressOf(o) : 'null'; },
    function: function(f) { return System.addressOf(f); },
    string: function(s) { return s; },
    number: function(n) { return String(n); },
    undefined: function() { return 'undefined'; },
};

/* Map is meant to be similar in usage to ES6 Map, which is
   described at http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets,
   without requiring more than ES5 + Gjs extensions.

   Known differences from other implementations:
   Polyfills around the web usually implement HashMaps for
   primitive values and reversed WeakMaps for object keys,
   but we want real maps with real O(1) semantics in all cases,
   and the easiest way is to have different hashers for different
   types.

   Known differences from the ES6 specification:
   - Map is a Lang.Class, not a ES6 class, so inheritance,
     prototype, sealing, etc. work differently.
   - items(), keys() and values() don't return iterators,
     they return actual arrays, so they incur a full copy everytime
     they're called, and they don't see changes if you mutate
     the table while iterating
     (admittedly, the ES6 spec is a bit unclear on this, and
     the reference code would just blow up)
*/
const Map = new Lang.Class({
    Name: 'Map',

    _init: function(iterable) {
        this._pool = { };
        this._size = 0;

        if (iterable) {
            for (let i = 0; i < iterable.length; i++) {
                let [key, value] = iterable[i];
                this.set(key, value);
            }
        }
    },

    _hashKey: function(key) {
        let type = typeof(key);
        return type + ':' + _hashers[type](key);
    },

    _internalGet: function(key) {
        let hash = this._hashKey(key);
        let node = this._pool[hash];

        if (node && _sameValue(node.key, key))
            return [true, node.value];
        else
            return [false, null];
    },

    get: function(key) {
        return this._internalGet(key)[1];
    },

    has: function(key) {
        return this._internalGet(key)[0];
    },

    set: function(key, value) {
        let hash = this._hashKey(key);
        let node = this._pool[hash];

        if (node) {
            node.key = key;
            node.value = value;
        } else {
            this._pool[hash] = { key: key, value: value };
            this._size++;
        }
    },

    delete: function(key) {
        let hash = this._hashKey(key);
        let node = this._pool[hash];

        if (node && _sameValue(node.key, key)) {
            delete this._pool[hash];
            this._size--;
            return [node.key, node.value];
        } else {
            return [null, null];
        }
    },

    keys: function() {
        let pool = this._pool;
        return Object.getOwnPropertyNames(pool).map(function(hash) {
            return pool[hash].key;
        });
    },

    values: function() {
        let pool = this._pool;
        return Object.getOwnPropertyNames(pool).map(function(hash) {
            return pool[hash].value;
        });
    },

    items: function() {
        let pool = this._pool;
        return Object.getOwnPropertyNames(pool).map(function(hash) {
            return [pool[hash].key, pool[hash].value];
        });
    },

    size: function() {
        return this._size;
    },
});