зеркало из https://github.com/mozilla/FlightDeck.git
130 строки
4.7 KiB
Python
130 строки
4.7 KiB
Python
|
|
import os, sys, re
|
|
|
|
COMMENT_PREFIXES = ["//", "/*", "*", "\'", "\""]
|
|
|
|
REQUIRE_RE = r"(?<![\'\"])require\s*\(\s*[\'\"]([^\'\"]+?)[\'\"]\s*\)"
|
|
|
|
def scan_requirements_with_grep(fn, lines):
|
|
requires = set()
|
|
for line in lines:
|
|
for clause in line.split(";"):
|
|
clause = clause.strip()
|
|
iscomment = False
|
|
for commentprefix in COMMENT_PREFIXES:
|
|
if clause.startswith(commentprefix):
|
|
iscomment = True
|
|
if iscomment:
|
|
continue
|
|
mo = re.search(REQUIRE_RE, clause)
|
|
if mo:
|
|
modname = mo.group(1)
|
|
requires.add(mo.group(1))
|
|
return requires
|
|
|
|
MUST_ASK_FOR_CHROME = """\
|
|
To use chrome authority, as in line %d in:
|
|
%s
|
|
> %s
|
|
You must enable it with:
|
|
let {Cc,Ci,Cu,Cr,Cm} = require('chrome');
|
|
"""
|
|
|
|
CHROME_ALIASES = ["Cc", "Ci", "Cu", "Cr", "Cm"]
|
|
|
|
def scan_chrome(fn, lines, stderr):
|
|
filename = os.path.basename(fn)
|
|
if filename == "cuddlefish.js" or filename == "securable-module.js":
|
|
return False, False # these are the loader
|
|
problems = False
|
|
asks_for_chrome = set() # Cc,Ci in: var {Cc,Ci} = require("chrome")
|
|
asks_for_all_chrome = False # e.g.: var c = require("chrome")
|
|
uses_chrome = set()
|
|
uses_components = False
|
|
uses_chrome_at = []
|
|
for lineno,line in enumerate(lines):
|
|
# note: this scanner is not obligated to spot all possible forms of
|
|
# chrome access. The scanner is detecting voluntary requests for
|
|
# chrome. Runtime tools will enforce allowance or denial of access.
|
|
line = line.strip()
|
|
iscomment = False
|
|
for commentprefix in COMMENT_PREFIXES:
|
|
if line.startswith(commentprefix):
|
|
iscomment = True
|
|
if iscomment:
|
|
continue
|
|
mo = re.search(REQUIRE_RE, line)
|
|
if mo:
|
|
if mo.group(1) == "chrome":
|
|
for alias in CHROME_ALIASES:
|
|
if alias in line:
|
|
asks_for_chrome.add(alias)
|
|
if not asks_for_chrome:
|
|
asks_for_all_chrome = True
|
|
alias_in_this_line = False
|
|
for wanted in CHROME_ALIASES:
|
|
if re.search(r'\b'+wanted+r'\b', line):
|
|
alias_in_this_line = True
|
|
uses_chrome.add(wanted)
|
|
uses_chrome_at.append( (wanted, lineno+1, line) )
|
|
|
|
if not alias_in_this_line and "Components." in line:
|
|
uses_components = True
|
|
uses_chrome_at.append( (None, lineno+1, line) )
|
|
problems = True
|
|
break
|
|
if uses_components or (uses_chrome - asks_for_chrome):
|
|
problems = True
|
|
print >>stderr, ""
|
|
print >>stderr, "To use chrome authority, as in:"
|
|
print >>stderr, " %s" % fn
|
|
for (alias, lineno, line) in uses_chrome_at:
|
|
if alias not in asks_for_chrome:
|
|
print >>stderr, " %d> %s" % (lineno, line)
|
|
print >>stderr, "You must enable it with something like:"
|
|
uses = sorted(uses_chrome)
|
|
if uses_components:
|
|
uses.append("components")
|
|
needed = ",".join(uses)
|
|
print >>stderr, ' const {%s} = require("chrome");' % needed
|
|
wants_chrome = bool(asks_for_chrome) or asks_for_all_chrome
|
|
return wants_chrome, problems
|
|
|
|
def scan_module(fn, lines, stderr=sys.stderr):
|
|
# barfs on /\s+/ in context-menu.js
|
|
#requires = scan_requirements_with_jsscan(fn)
|
|
requires = scan_requirements_with_grep(fn, lines)
|
|
requires.discard("chrome")
|
|
chrome, problems = scan_chrome(fn, lines, stderr)
|
|
return sorted(requires), chrome, problems
|
|
|
|
def scan_package(pkg_name, dirname, stderr=sys.stderr):
|
|
manifest = []
|
|
has_problems = False
|
|
for dirpath, dirnames, filenames in os.walk(dirname):
|
|
for fn in [fn for fn in filenames if fn.endswith(".js")]:
|
|
modname = os.path.splitext(fn)[0]
|
|
# turn "packages/jetpack-core/lib/content/foo" into "content/foo"
|
|
reldir = dirpath[len(dirname)+1:]
|
|
if reldir:
|
|
modname = "/".join(reldir.split(os.sep) + [modname])
|
|
absfn = os.path.join(dirpath, fn)
|
|
lines = open(absfn).readlines()
|
|
requires, chrome, problems = scan_module(absfn, lines, stderr)
|
|
manifest.append( (pkg_name, modname, requires, chrome) )
|
|
if problems:
|
|
has_problems = True
|
|
return manifest, has_problems
|
|
|
|
if __name__ == '__main__':
|
|
for fn in sys.argv[1:]:
|
|
requires,chrome,problems = scan_module(fn, open(fn).readlines())
|
|
print
|
|
print "---", fn
|
|
if problems:
|
|
print "PROBLEMS"
|
|
sys.exit(1)
|
|
print "chrome: %s" % chrome
|
|
print "requires: %s" % (",".join(requires))
|
|
|