Minor refactoring, fixes for emscripted apps
This commit is contained in:
Родитель
b99995da1e
Коммит
e6d01f0701
|
@ -9,6 +9,7 @@ PACKAGE_ANY = 0
|
|||
PACKAGE_WEBAPP = 8
|
||||
PACKAGE_PACKAGED_WEBAPP = 9
|
||||
|
||||
JS_DEBUG = False
|
||||
SPIDERMONKEY_INSTALLATION = os.environ.get("SPIDERMONKEY_INSTALLATION")
|
||||
|
||||
DEFAULT_WEBAPP_MRKT_URLS = ["https://marketplace.firefox.com",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
CSP_INFO = "https://developer.mozilla.org/en-US/docs/Security/CSP"
|
||||
CSP_INFO = "https://developer.mozilla.org/Apps/CSP"
|
||||
|
||||
MESSAGE_TITLE = "CSP Violation Detected"
|
||||
MESSAGE_GENERAL_DESC = ("You can find more information about what is and is "
|
||||
|
|
|
@ -38,6 +38,7 @@ class BaseErrorBundle(object):
|
|||
|
||||
def _message(type_, message_type):
|
||||
def wrap(self, *args, **kwargs):
|
||||
arg_len = len(args)
|
||||
message = {
|
||||
"uid": uuid.uuid4().hex,
|
||||
"id": kwargs.get("err_id") or args[0],
|
||||
|
@ -45,18 +46,26 @@ class BaseErrorBundle(object):
|
|||
kwargs.get(message_type) or args[1]),
|
||||
"description": unicodehelper.decode(
|
||||
kwargs.get("description", args[2] if
|
||||
len(args) > 2 else None)),
|
||||
arg_len > 2 else None)),
|
||||
# Filename is never None.
|
||||
"file": kwargs.get("filename",
|
||||
args[3] if len(args) > 3 else ""),
|
||||
args[3] if arg_len > 3 else ""),
|
||||
"line": kwargs.get("line",
|
||||
args[4] if len(args) > 4 else None),
|
||||
args[4] if arg_len > 4 else None),
|
||||
"column": kwargs.get("column",
|
||||
args[5] if len(args) > 5 else None),
|
||||
args[5] if arg_len > 5 else None),
|
||||
"tier": kwargs.get("tier", self.tier),
|
||||
"context": None,
|
||||
}
|
||||
|
||||
destination = getattr(self, type_)
|
||||
# Don't show duplicate messages.
|
||||
if any(x["id"] == message["id"] and
|
||||
x["file"] == message["file"] and
|
||||
x["line"] == message["line"] and
|
||||
x["column"] == message["column"] for x in destination):
|
||||
return self
|
||||
|
||||
context = kwargs.get("context")
|
||||
if context is not None:
|
||||
if isinstance(context, tuple):
|
||||
|
@ -66,7 +75,7 @@ class BaseErrorBundle(object):
|
|||
line=message["line"], column=message["column"])
|
||||
|
||||
# Append the message to the right stack.
|
||||
getattr(self, type_).append(message)
|
||||
destination.append(message)
|
||||
|
||||
# If instant mode is turned on, output the message immediately.
|
||||
if self.instant:
|
||||
|
|
|
@ -65,6 +65,19 @@ class JSReflectException(Exception):
|
|||
self.line = int(line_num)
|
||||
return self
|
||||
|
||||
BOOTSTRAP_SCRIPT = """
|
||||
var stdin = JSON.parse(readline());
|
||||
try{
|
||||
print(JSON.stringify(Reflect.parse(stdin)));
|
||||
} catch(e) {
|
||||
print(JSON.stringify({
|
||||
"error":true,
|
||||
"error_message":e.toString(),
|
||||
"line_number":e.lineNumber
|
||||
}));
|
||||
}"""
|
||||
BOOTSTRAP_SCRIPT = re.sub("\n +", "", BOOTSTRAP_SCRIPT)
|
||||
|
||||
|
||||
def _get_tree(code, shell=SPIDERMONKEY_INSTALLATION):
|
||||
"""Return an AST tree of the JS passed in `code`."""
|
||||
|
@ -72,25 +85,12 @@ def _get_tree(code, shell=SPIDERMONKEY_INSTALLATION):
|
|||
if not code:
|
||||
return None
|
||||
|
||||
code = json.dumps(JS_ESCAPE.sub("u", unicodehelper.decode(code)))
|
||||
|
||||
data = """
|
||||
var stdin = JSON.parse(readline());
|
||||
try{
|
||||
print(JSON.stringify(Reflect.parse(stdin)));
|
||||
} catch(e) {
|
||||
print(JSON.stringify({
|
||||
"error":true,
|
||||
"error_message":e.toString(),
|
||||
"line_number":e.lineNumber
|
||||
}));
|
||||
}"""
|
||||
|
||||
cmd = [shell, "-e", data]
|
||||
cmd = [shell, "-e", BOOTSTRAP_SCRIPT]
|
||||
shell_obj = subprocess.Popen(
|
||||
cmd, shell=False, stdin=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
code = json.dumps(JS_ESCAPE.sub("u", unicodehelper.decode(code)))
|
||||
data, stderr = shell_obj.communicate(code)
|
||||
|
||||
if stderr:
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import re
|
||||
import types
|
||||
|
||||
from appvalidator.constants import JS_DEBUG
|
||||
from .jstypes import *
|
||||
from .nodedefinitions import DEFINITIONS
|
||||
from .predefinedentities import GLOBAL_ENTITIES
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
class Traverser(object):
|
||||
"""Traverses the AST Tree and determines problems with a chunk of JS."""
|
||||
|
||||
|
@ -34,12 +32,12 @@ class Traverser(object):
|
|||
self.debug_level = 0
|
||||
|
||||
# If we're not debugging, don't waste more cycles than we need to.
|
||||
if not DEBUG:
|
||||
if not JS_DEBUG:
|
||||
self._debug = lambda *args, **kwargs: None
|
||||
|
||||
def _debug(self, data, indent=0):
|
||||
"""Write a message to the console if debugging is enabled."""
|
||||
if DEBUG:
|
||||
if JS_DEBUG:
|
||||
output = data
|
||||
if isinstance(data, JSObject) or isinstance(data, JSContext):
|
||||
output = data.output()
|
||||
|
@ -49,7 +47,7 @@ class Traverser(object):
|
|||
output.encode("ascii", "replace"))
|
||||
|
||||
def run(self, data):
|
||||
if DEBUG:
|
||||
if JS_DEBUG:
|
||||
x = open("/tmp/output.js", "w")
|
||||
x.write(unicode(data))
|
||||
x.close()
|
||||
|
@ -71,7 +69,7 @@ class Traverser(object):
|
|||
if self.contexts:
|
||||
# If we're in debug mode, save a copy of the global context for
|
||||
# analysis during unit tests.
|
||||
if DEBUG:
|
||||
if JS_DEBUG:
|
||||
self.err.final_context = self.contexts[0]
|
||||
|
||||
def traverse_node(self, node):
|
||||
|
@ -114,7 +112,7 @@ class Traverser(object):
|
|||
if action is not None:
|
||||
action_result = action(self, node)
|
||||
|
||||
if DEBUG:
|
||||
if JS_DEBUG:
|
||||
self._debug("ACTION>>%s (%s)" % (repr(action_result), node["type"]))
|
||||
|
||||
if action_result is None:
|
||||
|
|
|
@ -16,9 +16,22 @@ def test_js_file(err, filename, data, line=0, context=None):
|
|||
before_tier = err.tier
|
||||
err.set_tier(3)
|
||||
|
||||
tree = get_tree(data, err, filename,
|
||||
err and err.get_resource("SPIDERMONKEY") or
|
||||
SPIDERMONKEY_INSTALLATION)
|
||||
tree = None
|
||||
try:
|
||||
tree = get_tree(data, err, filename,
|
||||
err and err.get_resource("SPIDERMONKEY") or
|
||||
SPIDERMONKEY_INSTALLATION)
|
||||
except RuntimeError as exc:
|
||||
warning ="JS: Unknown runtime error"
|
||||
if "out of memory" in str(exc):
|
||||
warning = "JS: Out of memory exception"
|
||||
err.warning(
|
||||
err_id=("js", "parse", "runtimeerror"),
|
||||
warning=warning,
|
||||
description="An error was encountered while trying to validate a "
|
||||
"JS file.",
|
||||
filename=filename)
|
||||
|
||||
if not tree:
|
||||
err.metadata["ran_js_tests"] = "no;missing ast"
|
||||
if err is not None:
|
||||
|
|
11
jsmain.py
11
jsmain.py
|
@ -1,16 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import appvalidator.testcases.scripting as scripting
|
||||
import appvalidator.testcases.javascript.traverser
|
||||
from appvalidator.constants import SPIDERMONKEY_INSTALLATION
|
||||
from appvalidator.errorbundle import ErrorBundle
|
||||
from appvalidator.errorbundle.outputhandlers.shellcolors import OutputHandler
|
||||
import appvalidator.testcases.scripting as scripting
|
||||
import appvalidator.testcases.javascript.traverser
|
||||
from appvalidator.testcases.javascript.predefinedentities import GLOBAL_ENTITIES
|
||||
import appvalidator.testcases.javascript.spidermonkey as spidermonkey
|
||||
appvalidator.testcases.javascript.traverser.DEBUG = True
|
||||
from appvalidator.testcases.scripting import get_tree
|
||||
appvalidator.testcases.javascript.traverser.JS_DEBUG = True
|
||||
|
||||
if __name__ == '__main__':
|
||||
err = ErrorBundle(instant=True)
|
||||
|
@ -69,7 +68,7 @@ if __name__ == '__main__':
|
|||
print actions[vars[0]](wrap)
|
||||
continue
|
||||
|
||||
tree = spidermonkey.get_tree(line, err, shell=SPIDERMONKEY_INSTALLATION)
|
||||
tree = get_tree(line, err, shell=SPIDERMONKEY_INSTALLATION)
|
||||
if tree is None:
|
||||
continue
|
||||
tree = tree["body"]
|
||||
|
|
|
@ -9,10 +9,10 @@ from ..helper import MockXPI
|
|||
from appvalidator.constants import SPIDERMONKEY_INSTALLATION
|
||||
from appvalidator.errorbundle import ErrorBundle
|
||||
from appvalidator.errorbundle.outputhandlers.shellcolors import OutputHandler
|
||||
import appvalidator
|
||||
import appvalidator.testcases.content
|
||||
import appvalidator.testcases.scripting as scripting
|
||||
|
||||
scripting.traverser.DEBUG = True
|
||||
appvalidator.testcases.javascript.traverser.JS_DEBUG = True
|
||||
|
||||
|
||||
def uses_js(func):
|
||||
|
|
Загрузка…
Ссылка в новой задаче