Skip to content
This repository was archived by the owner on Nov 6, 2023. It is now read-only.
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 50 additions & 29 deletions chromium/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ const trivial_rule_from_c = new RegExp("^http:");
const trivial_cookie_name_c = new RegExp(".*");
const trivial_cookie_host_c = new RegExp(".*");


// Empty iterable singleton to reduce memory usage
const nullIterable = Object.create(null, {
[Symbol.iterator]: {
value: function* () {
// do nothing

@ghost ghost Sep 15, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done in a simpler way.

const nullIterator = {
  next() {
    return { done: true };
  }
};

const nullIterable = {
  [Symbol.iterator]: function () {
    return nullIterator;
  }
};

Will also save memory since it will not create a new iterator each time.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having just one name is nice. How about just:

const nullIterable = Object.create(null, {
  [Symbol.iterator]: {
    value: () => ({
      next() {
        return {done: true};
      }
    })
  }
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cowlicks const nullIterable = (function* () {})() would be better.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cowlicks why use Object.create(null, { ...?

@ghost ghost Sep 15, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cowlicks This will create a new instance of { next() { return { done: true } } } each time.

@ghost ghost Sep 15, 2017

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently I have this code:

const nullIterator = {
  next() {
    return { done: true };
  }
};

const nullIterable = {
  size: 0,
  [Symbol.iterator]: function () {
    return nullIterator;
  }
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@koops76 see #12577 (comment)

re: new instance of ... thing - that is fine, it should get GC'd immediately anyway

}
},

size: {
value: 0
},
});

/**
* A single rule
* @param from
Expand Down Expand Up @@ -416,63 +430,70 @@ RuleSets.prototype = {
*/
potentiallyApplicableRulesets: function(host) {
// Have we cached this result? If so, return it!
var cached_item = this.ruleCache.get(host);
if (cached_item !== undefined) {
util.log(util.DBUG, "Ruleset cache hit for " + host + " items:" + cached_item.length);
if (this.ruleCache.has(host)) {
let cached_item = this.ruleCache.get(host);
util.log(DBUG, "Ruleset cache hit for " + host + " items:" + cached_item.size);
return cached_item;
} else {
util.log(DBUG, "Ruleset cache miss for " + host);
}
util.log(util.DBUG, "Ruleset cache miss for " + host);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some issues with how this was merged, this line should have been kept (it should be util.DBUG).


var results = [];
if (this.targets.has(host)) {
// Copy the host targets so we don't modify them.
results = results.concat(this.targets.get(host));
}
// Let's begin search
// Copy the host targsts so we don't modify them.
let results = (this.targets.has(host) ?
new Set([...this.targets.get(host)]) :
new Set());

// Ensure host is well-formed (RFC 1035)
if (host.indexOf("..") != -1 || host.length > 255) {
util.log(util.WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host);
return null;
if (host.length > 255 || host.indexOf("..") != -1) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense 👍

util.log(WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host);
return nullIterable;
}

// Replace each portion of the domain with a * in turn
var segmented = host.split(".");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid renaming and changing this code unless its necessary to the PR. This algorithm is important, but isn't well tested unfortunately.

for (let i=0; i < segmented.length; i++) {
let segmented = host.split(".");
for (let i = 0; i < segmented.length; i++) {
let tmp = segmented[i];
segmented[i] = "*";
results = results.concat(this.targets.get(segmented.join(".")));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be something like my above comment, (https://github.com/EFForg/https-everywhere/pull/12577/files#r139258106) or maybe a ternary expression like

results = (this.targets.has(segmented.join('.')) ? 
  (new Set([...results, ...this.targets.get(segmented.join('.')]) :
  results);


results = (this.targets.has(segmented.join(".")) ?
new Set([...results, ...this.targets.get(segmented.join("."))]) :
results);

segmented[i] = tmp;
}

// now eat away from the left, with *, so that for x.y.z.google.com we
// check *.z.google.com and *.google.com (we did *.y.z.google.com above)
for (var i = 2; i <= segmented.length - 2; ++i) {
var t = "*." + segmented.slice(i,segmented.length).join(".");
results = results.concat(this.targets.get(t));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this rename. Then just use one of the methods I suggested above to update the results

for (let i = 2; i <= segmented.length - 2; i++) {
let t = "*." + segmented.slice(i, segmented.length).join(".");

results = (this.targets.has(t) ?
new Set([...results, ...this.targets.get(t)]) :
results);
}

// Clean the results list, which may contain duplicates or undefined entries
var resultSet = new Set(results);
resultSet.delete(undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep a results.delete(undefined) around to be safe.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what

results.delete(undefined);

util.log(util.DBUG,"Applicable rules for " + host + ":");
if (resultSet.size == 0) {
util.log(util.DBUG, " None");
log(DBUG,"Applicable rules for " + host + ":");
if (results.size == 0) {
util.log(DBUG, " None");
results = nullIterable;
} else {
for (let target of resultSet.values()) {
util.log(util.DBUG, " " + target.name);
}
results.forEach(result => util.log(DBUG, " " + result.name));
}

// Insert results into the ruleset cache
this.ruleCache.set(host, resultSet);
this.ruleCache.set(host, results);

// Cap the size of the cache. (Limit chosen somewhat arbitrarily)
if (this.ruleCache.size > 1000) {
// Map.prototype.keys() returns keys in insertion order, so this is a FIFO.
this.ruleCache.delete(this.ruleCache.keys().next().value);
}

return resultSet;
return results;
},

/**
Expand Down