示例#1
0
    def scan(self, file_object, options):
        self.metadata.setdefault("literals", [])
        self.metadata.setdefault("functions", [])
        self.metadata.setdefault("variables", [])

        try:
            p = pyjsparser.PyJsParser()
            parsed = p.parse(file_object.data.decode())
            self._javascript_recursion(self, parsed)

        except AttributeError:
            file_object.flags.append(f"{self.scanner_name}::attribute_error")
        except IndexError:
            file_object.flags.append(f"{self.scanner_name}::index_error")
        except KeyError:
            file_object.flags.append(f"{self.scanner_name}::key_error")
        except NotImplementedError:
            file_object.flags.append(
                f"{self.scanner_name}::not_implemented_error")
        except RecursionError:
            file_object.flags.append(
                f"{self.scanner_name}::recursion_depth_exceeded")
        except UnicodeDecodeError:
            file_object.flags.append(
                f"{self.scanner_name}::unicode_decode_error")
        except pyjsparser.pyjsparserdata.JsSyntaxError:
            file_object.flags.append(f"{self.scanner_name}::js_syntax_error")
示例#2
0
def test_parse_number(js_test_path, typ_expected, value_expected):
    js_test_path = os.path.join(PASSING_DIR, js_test_path)
    code = get_js_code(js_test_path)
    result = pyjsparser.PyJsParser().parse(code)
    value = result['body'][0]['expression']['right']['properties'][0]['value'][
        'value']
    assert value == value_expected
    assert isinstance(value, typ_expected)
示例#3
0
def organize_js(js, HEADER=DEFAULT_HEADER):
    parser = pyjsparser.PyJsParser()
    parsed = parser.parse(js)  # js to esprima syntax tree
    # Another way of doing that would be with my auto esprima translation but its much slower and causes import problems:
    # parsed = esprima.parse(js).to_dict()
    translating_nodes.clean_stacks()
    translating_nodes.trans(parsed)  # syntax tree to python code
    print(translating_nodes.root_scope.toJSON())
    return translating_nodes.root_scope
示例#4
0
def translate_js(js, HEADER=DEFAULT_HEADER):
    """js has to be a javascript source code.
       returns equivalent python code."""
    parser = pyjsparser.PyJsParser()
    parsed = parser.parse(js)  # js to esprima syntax tree
    # Another way of doing that would be with my auto esprima translation but its much slower and causes import problems:
    # parsed = esprima.parse(js).to_dict()
    translating_nodes.clean_stacks()
    return HEADER + translating_nodes.trans(
        parsed)  # syntax tree to python code
示例#5
0
def translate_js(js, HEADER=DEFAULT_HEADER, use_compilation_plan=False):
    """js has to be a javascript source code.
       returns equivalent python code."""
    if use_compilation_plan and not '//' in js and not '/*' in js:
        return translate_js_with_compilation_plan(js, HEADER=HEADER)
    parser = pyjsparser.PyJsParser()
    parsed = parser.parse(js)  # js to esprima syntax tree
    # Another way of doing that would be with my auto esprima translation but its much slower and causes import problems:
    # parsed = esprima.parse(js).to_dict()
    translating_nodes.clean_stacks()
    ret = HEADER + translating_nodes.trans(
        parsed)  # syntax tree to python code
    print(translating_nodes.root_scope.toJSON())
    return ret
def translate_js_with_compilation_plan(js, HEADER=DEFAULT_HEADER):
    """js has to be a javascript source code.
       returns equivalent python code.

       compile plans only work with the following restrictions:
       - only enabled for oneliner expressions
       - when there are comments in the js code string substitution is disabled
       - when there nested escaped quotes string substitution is disabled, so

       cacheable:
       Q1 == 1 && name == 'harry'

       not cacheable:
       Q1 == 1 && name == 'harry' // some comment

       not cacheable:
       Q1 == 1 && name == 'o\'Reilly'

       not cacheable:
       Q1 == 1 && name /* some comment */ == 'o\'Reilly'
       """

    match_increaser_str, match_increaser_num, compilation_plan = get_compilation_plan(
        js)

    cp_hash = hashlib.md5(compilation_plan.encode('utf-8')).digest()
    try:
        python_code = cache[cp_hash]['proto_python_code']
    except:
        parser = pyjsparser.PyJsParser()
        parsed = parser.parse(compilation_plan)  # js to esprima syntax tree
        # Another way of doing that would be with my auto esprima translation but its much slower and causes import problems:
        # parsed = esprima.parse(js).to_dict()
        translating_nodes.clean_stacks()
        python_code = translating_nodes.trans(
            parsed)  # syntax tree to python code
        cache[cp_hash] = {
            'compilation_plan': compilation_plan,
            'proto_python_code': python_code,
        }

    python_code = match_increaser_str.wrap_up(python_code)
    python_code = match_increaser_num.wrap_up(python_code)

    return HEADER + python_code
示例#7
0
    def scan(self, file_object, options):
        beautify = options.get("beautify", True)

        self.metadata.setdefault("literals", [])
        self.metadata.setdefault("functions", [])
        self.metadata.setdefault("variables", [])
        self.metadata["beautified"] = False
        js = None

        try:
            if beautify:
                js = jsbeautifier.beautify(file_object.data.decode())
                self.metadata["beautified"] = True
        except:  # noqa
            file_object.flags.append(
                f"{self.scanner_name}::beautify_exception")

        if js is None:
            js = file_object.data.decode()

        try:
            parser = pyjsparser.PyJsParser()
            parsed = parser.parse(js)
            self._javascript_recursion(self, parsed)

        except AttributeError:
            file_object.flags.append(f"{self.scanner_name}::attribute_error")
        except IndexError:
            file_object.flags.append(f"{self.scanner_name}::index_error")
        except KeyError:
            file_object.flags.append(f"{self.scanner_name}::key_error")
        except NotImplementedError:
            file_object.flags.append(
                f"{self.scanner_name}::not_implemented_error")
        except RecursionError:
            file_object.flags.append(
                f"{self.scanner_name}::recursion_depth_exceeded")
        except UnicodeDecodeError:
            file_object.flags.append(
                f"{self.scanner_name}::unicode_decode_error")
        except pyjsparser.pyjsparserdata.JsSyntaxError:
            file_object.flags.append(f"{self.scanner_name}::js_syntax_error")
示例#8
0
    def parse_example(prefix):
        def fmt(value):
            return pprint.pformat(value, width=120) + "\n"

        def output(out_dir, prefix, contents):
            pathlib.Path(out_dir).mkdir(parents=True, exist_ok=True)
            path = "{}/{}.txt".format(out_dir, prefix)
            with open(path, "w") as f:
                f.write(contents)

        js_path = "examples/{}_data.js".format(prefix)
        js = open(js_path).read()

        doc = pyjsparser.PyJsParser().parse(js)

        output("examples_doc", prefix, fmt(doc))

        metrics_of = globals()["metrics_of_{}".format(prefix)]
        metrics = list(metrics_of(doc))

        output("examples_metrics", prefix, fmt(metrics))

        return
示例#9
0
def metrics_of_host(host):
    address = host["address"]
    hostname = host["hostname"]

    def log_in():
        data = {"password": host["password"]}
        r = requests.post("http://{}/login.cgi".format(address), data=data)
        assert 200 == r.status_code
        if "Incorrect password, please try again." in r.text:
            raise ValueError("Wrong password for switch at {}".format(address))

    log_in()

    for prefix in ("link", "poe", "system"):
        r = requests.get("http://{}/{}_data.js".format(address, prefix))
        assert 200 == r.status_code
        assert not r.text.startswith("<")

        doc = pyjsparser.PyJsParser().parse(r.text)
        metrics_of = globals()["metrics_of_{}".format(prefix)]

        for m in metrics_of(doc):
            m["host"] = hostname
            yield m
示例#10
0
    # restore context
    Context = previous_context
    # define in upper context
    inline_stack.define(PyName, whole_code)
    return PyName


LogicalExpression = BinaryExpression
PostfixExpression = UpdateExpression

clean_stacks()

if __name__ == '__main__':
    import codecs
    import time
    import pyjsparser

    c = None  #'''`ijfdij`'''
    if not c:
        with codecs.open("esp.js", "r", "utf-8") as f:
            c = f.read()

    print('Started')
    t = time.time()
    res = trans(pyjsparser.PyJsParser().parse(c))
    dt = time.time() - t + 0.000000001
    print(('Translated everyting in', round(dt, 5), 'seconds.'))
    print(('Thats %d characters per second' % int(len(c) / dt)))
    with open('res.py', 'w') as f:
        f.write(res)
示例#11
0
def _check_directive_scope(all_files):
    """This function checks that all directives have an explicit
    scope: {} and it should not be scope: true.
    """
    print 'Starting directive scope check'
    print '----------------------------------------'
    summary_messages = []
    # Select JS files which need to be checked.
    files_to_check = [
        filename for filename in all_files if not
        any(fnmatch.fnmatch(filename, pattern) for pattern in EXCLUDED_PATHS)
        and filename.endswith('.js')]
    failed = False
    summary_messages = []
    # Use Pyjsparser to parse a JS file as a Python dictionary.
    parser = pyjsparser.PyJsParser()
    for filename in files_to_check:
        with open(filename) as f:
            content = f.read()
        # Parse the body of the content as nodes.
        parsed_nodes = parser.parse(content)['body']
        for parsed_node in parsed_nodes:
            # Check the type of the node.
            if parsed_node['type'] != 'ExpressionStatement':
                continue
            # Separate the expression part of the node.
            expression = parsed_node['expression']
            # Check whether the expression belongs to a directive.
            expression_type_is_not_call = (
                expression['type'] != 'CallExpression')
            if expression_type_is_not_call:
                continue
            expression_callee_type_is_not_member = (
                expression['callee']['type'] != 'MemberExpression')
            if expression_callee_type_is_not_member:
                continue
            expression_callee_property_name_is_not_directive = (
                expression['callee']['property']['name'] != 'directive')
            if expression_callee_property_name_is_not_directive:
                continue
            # Separate the arguments of the expression.
            arguments = expression['arguments']
            # The first argument of the expression is the
            # name of the directive.
            if arguments[0]['type'] == 'Literal':
                directive_name = str(arguments[0]['value'])
            arguments = arguments[1:]
            for argument in arguments:
                # Check the type of an argument.
                if argument['type'] != 'ArrayExpression':
                    continue
                # Separate out the elements for the argument.
                elements = argument['elements']
                for element in elements:
                    # Check the type of an element.
                    if element['type'] != 'FunctionExpression':
                        continue
                    # Separate out the body of the element.
                    body = element['body']
                    if body['type'] != 'BlockStatement':
                        continue
                    # Further separate the body elements from the body.
                    body_elements = body['body']
                    for body_element in body_elements:
                        # Check if the body element is a return statement.
                        body_element_type_is_not_return = (
                            body_element['type'] != 'ReturnStatement')
                        body_element_argument_type_is_not_object = (
                            body_element['argument']['type'] != (
                                'ObjectExpression'))
                        if (body_element_type_is_not_return or (
                                body_element_argument_type_is_not_object)):
                            continue
                        # Separate the properties of the return node.
                        return_node_properties = (
                            body_element['argument']['properties'])
                        # Loop over all the properties of the return node
                        # to find out the scope key.
                        for return_node_property in return_node_properties:
                            # Check whether the property is scope.
                            property_key_is_an_identifier = (
                                return_node_property['key']['type'] == (
                                    'Identifier'))
                            property_key_name_is_scope = (
                                return_node_property['key']['name'] == (
                                    'scope'))
                            if (
                                    property_key_is_an_identifier and (
                                        property_key_name_is_scope)):
                                # Separate the scope value and
                                # check if it is an Object Expression.
                                # If it is not, then check for scope: true
                                # and report the error message.
                                scope_value = return_node_property['value']
                                if scope_value['type'] == 'Literal' and (
                                        scope_value['value']):
                                    failed = True
                                    print (
                                        'Please ensure that %s '
                                        'directive in %s file '
                                        'does not have scope set to '
                                        'true.' % (directive_name, filename))
                                elif scope_value['type'] != 'ObjectExpression':
                                    # Check whether the directive has scope: {}
                                    # else report the error message.
                                    failed = True
                                    print (
                                        'Please ensure that %s directive '
                                        'in %s file has a scope: {}.' % (
                                            directive_name, filename))

    if failed:
        summary_message = '%s   Directive scope check failed' % (
            _MESSAGE_TYPE_FAILED)
        print summary_message
        summary_messages.append(summary_message)
    else:
        summary_message = '%s  Directive scope check passed' % (
            _MESSAGE_TYPE_SUCCESS)
        print summary_message
        summary_messages.append(summary_message)

    print ''
    print '----------------------------------------'
    print ''

    return summary_messages
 def __init__(self):
     self.parser = pyjsparser.PyJsParser()
示例#13
0
def pyjsparser_parse_fn(code):
    parser = pyjsparser.PyJsParser()
    return parser.parse(code)