Skip to content

Commit 9a2ed53

Browse files
committed
Replace trivial-validate.py with 3.0 version
As of this commit: diracdeltas/https-everywhere@d921337
1 parent ae7c95f commit 9a2ed53

File tree

1 file changed

+75
-42
lines changed

1 file changed

+75
-42
lines changed

utils/trivial-validate.py

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@
1414

1515
ignoredups = [re.compile(val) for opt, val in longargs if opt == "--ignoredups"]
1616

17+
multi_file_validate = True
18+
1719
if args:
18-
try:
19-
os.chdir(args[0])
20-
except:
21-
sys.stderr.write("could not chdir to %s\n" % args[0])
22-
sys.stderr.write("usage: %s directoryname\n" % sys.argv[0])
23-
sys.exit(2)
20+
if os.path.isfile(args[0]):
21+
multi_file_validate = False
22+
else:
23+
try:
24+
os.chdir(args[0])
25+
except:
26+
sys.stderr.write("could not chdir to %s\n" % args[0])
27+
sys.stderr.write("usage: %s (<directoryname> or <file to validate><directory of all rulesets (optional)>\n" % sys.argv[0])
28+
sys.exit(2)
2429

2530
def test_not_anchored(tree):
2631
# Rules not anchored to the beginning of a line.
@@ -42,19 +47,6 @@ def test_bad_regexp(tree):
4247
return False
4348
return True
4449

45-
def test_missing_to(tree):
46-
47-
# Rules that are terminated before setting 'to'.
48-
# These cases are probably either due to a misplaced
49-
# rule end or intended to be different elements.
50-
"""Rule is missing a 'to' value."""
51-
for rule in tree.xpath("/ruleset/rule"):
52-
if not rule.get("to"):
53-
sys.stdout.write("warning: 'to' attribute missing in %s. " %fi)
54-
sys.stdout.write("Misplaced end or misnamed element?\n")
55-
return False
56-
return True
57-
5850
def test_unescaped_dots(tree):
5951
# Rules containing unescaped dots outside of brackets and before slash.
6052
# Note: this is meant to require example\.com instead of example.com,
@@ -95,19 +87,16 @@ def test_unencrypted_to(tree):
9587
# Now warn if the rule author indicates they intended it, with the
9688
# downgrade attribute. Error if this attribute is not present.
9789
"""Rule redirects to something other than https."""
98-
down_warned = False
9990
for rule in tree.xpath("/ruleset/rule"):
10091
to, downgrade = rule.get("to"), rule.get("downgrade")
10192
if to[:6] != "https:" and to[:5] != "http:":
10293
return False
10394
elif to[:5] == "http:" and downgrade:
104-
if not down_warned:
105-
sys.stdout.write("warning: downgrade rule in %s redirects " %fi)
106-
sys.stdout.write("to http.\n")
107-
down_warned = True
95+
sys.stdout.write("warning: downgrade rule in %s redirects " % fi)
96+
sys.stdout.write("to http.\n")
10897
elif to[:5] == "http:":
109-
sys.stdout.write("error: rule in %s redirects to http and " % fi)
110-
sys.stdout.write("downgrade attribute not specified.\n")
98+
sys.stdout.write("error: rule in %s redirects to http and " % fi)
99+
sys.stdout.write("downgrade attribute not specified.\n")
111100
return False
112101
return True
113102

@@ -162,7 +151,22 @@ def test_non_ascii(tree):
162151
return False
163152
return True
164153

165-
tests = [test_not_anchored, test_bad_regexp, test_unescaped_dots, test_missing_to,
154+
def get_all_names_and_targets(d):
155+
names = set()
156+
targets = set()
157+
for fi in os.listdir(d):
158+
try:
159+
tree = etree.parse(fi)
160+
ruleset_name = tree.xpath("/ruleset/@name")[0]
161+
target_names = tree.xpath("/ruleset/target/@host")
162+
except Exception:
163+
continue
164+
names.add(ruleset_name)
165+
for target in target_names:
166+
targets.add(target)
167+
return names, targets
168+
169+
tests = [test_not_anchored, test_bad_regexp, test_unescaped_dots,
166170
test_space_in_to, test_unencrypted_to, test_backslash_in_to,
167171
test_no_trailing_slash, test_lacks_target_host, test_bad_target_host,
168172
test_duplicated_target_host, test_non_ascii]
@@ -172,25 +176,55 @@ def test_non_ascii(tree):
172176
all_targets = set()
173177
all_names = set()
174178

175-
for fi in os.listdir("."):
179+
if multi_file_validate:
180+
for fi in os.listdir("."):
181+
try:
182+
tree = etree.parse(fi)
183+
if fi[-4:] != ".xml":
184+
if tree.xpath("/ruleset"):
185+
sys.stdout.write("warning: ruleset in file without .xml extension: %s\n" % fi)
186+
else:
187+
continue
188+
seen_file = True
189+
except Exception, oops:
190+
if fi[-4:] != ".xml":
191+
continue
192+
failure = 1
193+
sys.stdout.write("%s failed XML validity: %s\n" % (fi, oops))
194+
ruleset_name = tree.xpath("/ruleset/@name")[0]
195+
if ruleset_name in all_names:
196+
failure = 1
197+
sys.stdout.write("failure: duplicate ruleset name %s\n" % ruleset_name)
198+
all_names.add(ruleset_name)
199+
for test in tests:
200+
if not test(tree):
201+
failure = 1
202+
sys.stdout.write("failure: %s failed test: %s\n" % (fi, test.__doc__))
203+
for target in tree.xpath("/ruleset/target/@host"):
204+
if target in all_targets and not any(ign.search(target) for ign in ignoredups):
205+
# suppress warning about duplicate targets if an --ignoredups
206+
# pattern matches target
207+
sys.stdout.write("warning: duplicate target: %s\n" % target)
208+
all_targets.add(target)
209+
else:
210+
fi = os.path.basename(args[0])
211+
if len(args) > 1:
212+
all_names, all_targets = get_all_names_and_targets(args[1])
213+
else:
214+
sys.stdout.write("warning: pass a directory of existing rulesets as the second argument to check for duplicates \n")
176215
try:
177-
tree = etree.parse(fi)
178-
if fi[-4:] != ".xml":
179-
if tree.xpath("/ruleset"):
180-
sys.stdout.write("warning: ruleset in file without .xml extension: %s\n" % fi)
181-
else:
182-
continue
183-
seen_file = True
184-
except Exception as oops:
185-
if fi[-4:] != ".xml":
186-
continue
187-
failure = 1
188-
sys.stdout.write("%s failed XML validity: %s\n" % (fi, oops))
216+
tree = etree.parse(fi)
217+
if fi[-4:] != ".xml":
218+
if tree.xpath("/ruleset"):
219+
sys.stdout.write("warning: ruleset in file without .xml extension: %s\n" % fi)
220+
seen_file = True
221+
except Exception, oops:
222+
failure = 1
223+
sys.stdout.write("%s failed XML validity: %s\n" % (fi, oops))
189224
ruleset_name = tree.xpath("/ruleset/@name")[0]
190225
if ruleset_name in all_names:
191226
failure = 1
192227
sys.stdout.write("failure: duplicate ruleset name %s\n" % ruleset_name)
193-
all_names.add(ruleset_name)
194228
for test in tests:
195229
if not test(tree):
196230
failure = 1
@@ -200,7 +234,6 @@ def test_non_ascii(tree):
200234
# suppress warning about duplicate targets if an --ignoredups
201235
# pattern matches target
202236
sys.stdout.write("warning: duplicate target: %s\n" % target)
203-
all_targets.add(target)
204237

205238
if not seen_file:
206239
which = "specified" if args else "current"

0 commit comments

Comments
 (0)