Skip to content

Commit 8ccfcca

Browse files
committed
Work in progress on broken rule indication.
1 parent 7ce42e3 commit 8ccfcca

File tree

6 files changed

+96
-42
lines changed

6 files changed

+96
-42
lines changed

src/chrome/content/code/ApplicableList.js

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@ serial_number = 0
77
function ApplicableList(logger, doc, domWin) {
88
this.domWin = domWin;
99
this.home = doc.baseURIObject.spec; // what doc we're housekeeping for
10+
this.doc = doc;
1011
this.log = logger;
1112
this.active = {};
13+
this.breaking = {}; // rulesets with redirection loops
1214
this.inactive = {};
1315
this.moot={}; // rulesets that might be applicable but uris are already https
14-
this.all={}; // active + inactive + moot
16+
this.all={}; // active + breaking + inactive + moot
1517
serial_number += 1;
1618
this.serial = serial_number;
1719
this.log(DBUG,"Alist serial #" + this.serial + " for " + this.home);
18-
// The base URI of the dom tends to be loaded from some /other/
19-
// ApplicableList, so pretend we're loading it from here.
20-
HTTPSEverywhere.instance.https_rules.rewrittenURI(this, doc.baseURIObject);
2120
};
2221

2322
ApplicableList.prototype = {
@@ -29,6 +28,13 @@ ApplicableList.prototype = {
2928
this.all[ruleset.name] = ruleset;
3029
},
3130

31+
breaking_rule: function(ruleset) {
32+
this.log(WARN,"breaking rule " + ruleset.name +" in "+ this.home +" -> " +
33+
this.domWin.document.baseURIObject.spec+ " serial " + this.serial);
34+
this.breaking[ruleset.name] = ruleset;
35+
this.all[ruleset.name] = ruleset;
36+
},
37+
3238
inactive_rule: function(ruleset) {
3339

3440
this.log(INFO,"inactive rule " + ruleset.name +" in "+ this.home +" -> " +
@@ -50,6 +56,13 @@ ApplicableList.prototype = {
5056
},
5157

5258
populate_menu: function(document) {
59+
60+
// The base URI of the dom tends to be loaded from some /other/
61+
// ApplicableList, so pretend we're loading it from here.
62+
this.log(WARN,"BASE uri is", this.doc.baseURIObject.spec);
63+
this.log(WARN,"home is", this.home);
64+
HTTPSEverywhere.instance.https_rules.rewrittenURI(this, this.doc.baseURIObject);
65+
this.show_applicable();
5366
this.log(DBUG, "populating using alist #" + this.serial);
5467
this.document = document;
5568

@@ -62,12 +75,13 @@ ApplicableList.prototype = {
6275
}
6376

6477
// add the label at the top
65-
var rules_count = 0;
66-
for(x in this.active) rules_count++;
67-
for(x in this.inactive) rules_count++;
68-
for(x in this.moot) rules_count++;
78+
var any_rules = false
79+
for (var x in this.all) {
80+
any_rules = true; // how did JavaScript get this ugly?
81+
break;
82+
}
6983
var label = document.createElement('menuitem');
70-
if(rules_count > 0) {
84+
if (any_rules) {
7185
label.setAttribute('label', 'Enable / Disable Rules');
7286
} else {
7387
label.setAttribute('label', '(No Rules for This Page)');
@@ -89,6 +103,8 @@ ApplicableList.prototype = {
89103
}
90104

91105
// add all applicable commands
106+
for(var x in this.breaking)
107+
this.add_command(this.breaking[x]);
92108
for(var x in this.active)
93109
this.add_command(this.active[x]);
94110
for(var x in this.moot)
@@ -97,13 +113,17 @@ ApplicableList.prototype = {
97113
this.add_command(this.inactive[x]);
98114

99115
// add all the menu items
100-
for(var x in this.active)
101-
this.add_menuitem(this.active[x], 'active');
116+
for (var x in this.breaking)
117+
this.add_menuitem(this.breaking[x], 'breaking');
118+
// break once break everywhere
119+
for (var x in this.active)
120+
if (!(x in this.breaking))
121+
this.add_menuitem(this.active[x], 'active');
102122
// rules that are active for some uris are not really moot
103-
for(var x in this.moot)
104-
if(!(x in this.active))
123+
for (var x in this.moot)
124+
if (!(x in this.active))
105125
this.add_menuitem(this.moot[x], 'moot');
106-
for(var x in this.inactive)
126+
for (var x in this.inactive)
107127
this.add_menuitem(this.inactive[x], 'inactive');
108128

109129
// add other menu items
@@ -140,7 +160,9 @@ ApplicableList.prototype = {
140160
this.commandset.appendChild(command);
141161
},
142162

143-
// add a menu item for a rule -- type is "active", "inactive", or "moot"
163+
// add a menu item for a rule -- type is "active", "inactive", "moot",
164+
// or "breaking"
165+
144166
add_menuitem: function(rule, type) {
145167
// create the menuitem
146168
var item = this.document.createElement('menuitem');
@@ -150,9 +172,10 @@ ApplicableList.prototype = {
150172
// set the icon
151173
var image = this.document.createElement('image');
152174
var image_src;
153-
if(type == 'active') image_src = 'tick.png';
154-
else if(type == 'inactive') image_src = 'cross.png';
155-
else if(type == 'moot') image_src = 'tick-moot.png';
175+
if (type == 'active') image_src = 'tick.png';
176+
else if (type == 'inactive') image_src = 'cross.png';
177+
else if (type == 'moot') image_src = 'tick-moot.png';
178+
else if (type == 'breaking') image_src = 'tick-red.png';
156179
image.setAttribute('src', 'chrome://https-everywhere/skin/'+image_src);
157180

158181
// set the label
@@ -173,6 +196,9 @@ ApplicableList.prototype = {
173196
this.log(WARN, "Applicable list number " + this.serial);
174197
for (var x in this.active)
175198
this.log(WARN,"Active: " + this.active[x].name);
199+
200+
for (var x in this.breaking)
201+
this.log(WARN,"Breaking: " + this.breaking[x].name);
176202

177203
for (x in this.inactive)
178204
this.log(WARN,"Inactive: " + this.inactive[x].name);

src/chrome/content/code/HTTPS.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ const HTTPS = {
2929
httpsRewrite: null,
3030

3131
replaceChannel: function(applicable_list, channel) {
32-
var uri = HTTPSRules.rewrittenURI(applicable_list, channel.URI);
33-
if (!uri) {
32+
var blob = HTTPSRules.rewrittenURI(applicable_list, channel.URI);
33+
if (null == blob) {
3434
//HTTPS.log(INFO,
3535
// "Got replace channel with no applicable rules for URI "
3636
// + channel.URI.spec);
3737
return false;
3838
}
39+
var uri = blob.newuri;
40+
if (!uri) this.log(WARN, "OH NO BAD ARGH\nARGH");
3941

4042
var c2=channel.QueryInterface(CI.nsIHttpChannel);
4143
this.log(DBUG,"Redirection limit is " + c2.redirectionLimit);
@@ -46,7 +48,11 @@ const HTTPS = {
4648
if (c2.redirectionLimit < 10) {
4749
this.log(WARN, "Redirection loop trying to set HTTPS on:\n " +
4850
channel.URI.spec +"\n(falling back to HTTP)");
49-
https_everywhere_blacklist[channel.URI.spec] = true;
51+
if (!blob.applied_rule) {
52+
this.log(WARN,"DEATH\nDEATH\nDEATH\nDEATH");
53+
https_everywhere_blacklist[channel.URI.spec] = true;
54+
}
55+
https_everywhere_blacklist[channel.URI.spec] = blob.applied_rule;
5056
return false;
5157
}
5258
if (ChannelReplacement.supported) {
@@ -97,7 +103,7 @@ const HTTPS = {
97103
return null;
98104
}
99105
domWin = doc.defaultView;
100-
this.log(DBUG,"Coerced nsIDOMWin from Node: " + domWin);
106+
//this.log(DBUG,"Coerced nsIDOMWin from Node: " + domWin);
101107
} else {
102108
this.log(WARN, "Context for " + uri.spec +
103109
"is some bizarre unexpected thing: " + ctx);
@@ -116,8 +122,9 @@ const HTTPS = {
116122
// what rulesets might have applied to this page
117123
this.log(VERB, "Context is " + ctx);
118124
var alist = this.getApplicableListForContext(ctx, uri);
119-
var newuri = HTTPSRules.rewrittenURI(alist, uri);
120-
if (!newuri) return true; // no applicable rule
125+
var blob = HTTPSRules.rewrittenURI(alist, uri);
126+
if (null == blob) return true; // no applicable rule
127+
var newuri = blob.newuri;
121128

122129
try {
123130
if (this.rewriteInPlace(uri, newuri))

src/chrome/content/code/HTTPSRules.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,13 @@ const HTTPSRules = {
347347
rewrittenURI: function(alist, uri) {
348348
// This function oversees the task of working out if a uri should be
349349
// rewritten, what it should be rewritten to, and recordkeeping of which
350-
// applicable rulesets are and aren't active.
350+
// applicable rulesets are and aren't active. Previously this returned
351+
// the new uri if there was a rewrite. Now it returns a JS object with
352+
// a newuri attribute and an applied_rule attribute (or null if there's no
353+
// rewrite).
351354
var i = 0;
352-
var newuri = null
355+
var blob = {};
356+
blob.newuri = null;
353357
try {
354358
var rs = this.potentiallyApplicableRulesets(uri.host);
355359
} catch(e) {
@@ -364,11 +368,16 @@ const HTTPSRules = {
364368
alist.inactive_rule(rs[i]);
365369
continue;
366370
}
367-
newuri = rs[i].transformURI(uri);
368-
if (newuri) {
371+
blob.newuri = rs[i].transformURI(uri);
372+
if (blob.newuri) {
369373
// we rewrote the uri
370-
if (alist) alist.active_rule(rs[i]);
371-
return newuri;
374+
if (alist)
375+
if (blob.newuri.spec in https_everywhere_blacklist)
376+
alist.breaking_rule(rs[i])
377+
else
378+
alist.active_rule(rs[i]);
379+
blob.applied_rule = rs[i];
380+
return blob;
372381
}
373382
if (uri.scheme == "https" && alist) {
374383
// we didn't rewrite but the rule applies to this domain and the

src/chrome/skin/https-everywhere.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ toolbar[iconsize="small"] #https-everywhere-button {
1717
opacity: 0.5;
1818
font-weight: bold;
1919
}
20+
#https-everywhere-button menuitem.breaking-item label {
21+
color: #b99999;
22+
font-weight: bold;
23+
}
2024
#https-everywhere-button menuitem.inactive-item label {
2125
color: #999999;
2226
font-weight: bold;

src/chrome/skin/tick-red.png

459 Bytes
Loading

src/components/https-everywhere.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ HTTPSEverywhere.prototype = {
236236
try {
237237
if (c) {
238238
c = c.wrappedJSObject;
239-
this.log(DBUG, "Found a controller, returning data");
239+
//this.log(DBUG, "Found a controller, returning data");
240240
return c.data[key];
241241
} else {
242242
this.log(INFO, "No controller attached to " + domWin);
@@ -245,7 +245,9 @@ HTTPSEverywhere.prototype = {
245245
} catch(e) {
246246
// Firefox 3.5
247247
this.log(WARN,"exception in getExpando");
248-
return this.getExpando_old(domWin.document, key, null);
248+
this.getExpando = this.getExpando_old;
249+
this.setExpando = this.setExpando_old;
250+
return this.getExpando_old(domWin, key, null);
249251
}
250252
},
251253
setExpando: function(domWin, key, value) {
@@ -260,16 +262,21 @@ HTTPSEverywhere.prototype = {
260262
}
261263
c.data[key] = value;
262264
} catch(e) {
263-
this.setExpando_old(domWin.document, key, value);
265+
this.log(WARN,"exception in setExpando");
266+
this.getExpando = this.getExpando_old;
267+
this.setExpando = this.setExpando_old;
268+
this.setExpando_old(domWin, key, value);
264269
}
265270
},
266271

267272
// This method is straight out of NoScript... we fall back to it in FF 3.*?
268-
getExpando_old: function(domObject, key, defValue) {
273+
getExpando_old: function(domWin, key, defValue) {
274+
var domObject = domWin.document;
269275
return domObject && domObject.__httpsEStorage && domObject.__httpsEStorage[key] ||
270276
(defValue ? this.setExpando(domObject, key, defValue) : null);
271277
},
272-
setExpando_old: function(domObject, key, value) {
278+
setExpando_old: function(domWin, key, value) {
279+
var domObject = domWin.document;
273280
if (!domObject) return null;
274281
if (!domObject.__httpsEStorage) domObject.__httpsEStorage = {};
275282
if (domObject.__httpsEStorage) domObject.__httpsEStorage[key] = value;
@@ -317,7 +324,7 @@ HTTPSEverywhere.prototype = {
317324
try {
318325
var domWin = nc.getInterface(CI.nsIDOMWindow);
319326
} catch(e) {
320-
this.log(WARN, "exploded getting DOMWin for " + channel.URI.spec);
327+
this.log(INFO, "exploded getting DOMWin for " + channel.URI.spec);
321328
return null;
322329
}
323330
if (!domWin) {
@@ -341,23 +348,23 @@ HTTPSEverywhere.prototype = {
341348
return null;
342349
}
343350
var dw = domWin.top;
344-
this.log(DBUG, "Forcing new AL in getApplicableListForDOMWin in onLocationChange");
345351
var alist = new ApplicableList(this.log,dw.document,dw);
346352
this.setExpando(dw,"applicable_rules",alist);
347353
return alist;
348354
},
349355

350356
getApplicableListForDOMWin: function(domWin, where) {
351357
if (!domWin || !(domWin instanceof CI.nsIDOMWindow)) {
352-
this.log(WARN, "Get alist without domWin");
358+
//this.log(WARN, "Get alist without domWin");
353359
return null;
354360
}
355361
var dw = domWin.top;
356362
var alist= this.getExpando(dw,"applicable_rules",null);
357363
if (alist) {
358-
this.log(DBUG,"get AL success in " + where);
364+
//this.log(DBUG,"get AL success in " + where);
365+
return alist;
359366
} else {
360-
this.log(DBUG, "Making new AL in getApplicableListForDOMWin in " + where);
367+
//this.log(DBUG, "Making new AL in getApplicableListForDOMWin in " + where);
361368
alist = new ApplicableList(this.log,dw.document,dw);
362369
this.setExpando(dw,"applicable_rules",alist);
363370
}
@@ -373,11 +380,12 @@ HTTPSEverywhere.prototype = {
373380
if (topic == "http-on-modify-request") {
374381
if (!(channel instanceof CI.nsIHttpChannel)) return;
375382
this.log(DBUG,"Got http-on-modify-request: "+channel.URI.spec);
383+
var lst = this.getApplicableListForChannel(channel);
376384
if (channel.URI.spec in https_everywhere_blacklist) {
377-
this.log(DBUG, "Avoiding blacklisted " + channel.URI.spec);
385+
this.log(WARN, "Avoiding blacklisted " + channel.URI.spec);
386+
lst.breaking_rule(https_everywhere_blacklist[channel.URI.spec]);
378387
return;
379388
}
380-
var lst = this.getApplicableListForChannel(channel);
381389
HTTPS.replaceChannel(lst, channel);
382390
} else if (topic == "http-on-examine-response") {
383391
this.log(DBUG, "Got http-on-examine-response @ "+ (channel.URI ? channel.URI.spec : '') );

0 commit comments

Comments
 (0)