def opt_value_of_const_array(ast):
    for node in ast.iter():
        if node.tag == "IndexExpressionAst":
            subnodes = list(node)

            if subnodes[0].tag == "StringConstantExpressionAst":
                target = subnodes[0].text
            elif subnodes[0].tag == "ArrayLiteralAst":
                target = get_array_literal_values(subnodes[0])
            else:
                continue

            if subnodes[1].tag == "ConstantExpressionAst":
                indexes = [int(subnodes[1].text)]
            elif subnodes[1].tag == "ArrayLiteralAst":
                values = get_array_literal_values(subnodes[1])
                indexes = values
            else:
                continue

            if target is not None and indexes is not None:
                if len(indexes) > 0:

                    new_array_ast = create_array_literal_values([target[index] for index in indexes])

                    log_debug(f"Apply index {indexes} operation to constant {target.__class__.__name__} {target}")

                    replace_node(ast, node, new_array_ast)

                    return True

    return False
Esempio n. 2
0
def opt_binary_expression_plus(ast):
    for node in ast.iter():
        if node.tag == 'BinaryExpressionAst':
            operator = node.attrib['Operator']
            if operator == "Plus":
                subnodes = list(node)

                if subnodes[0].tag == "StringConstantExpressionAst":
                    left = subnodes[0].text
                elif subnodes[0].tag == "ArrayLiteralAst":
                    left = get_array_literal_values(subnodes[0])
                else:
                    continue

                if subnodes[1].tag == "StringConstantExpressionAst":
                    right = subnodes[1].text
                elif subnodes[1].tag == "ArrayLiteralAst":
                    right = get_array_literal_values(subnodes[1])
                else:
                    continue

                if left is not None and right is not None:
                    if isinstance(left, str) and isinstance(right, str):

                        new_element = Element('StringConstantExpressionAst')
                        new_element.set('StringConstantType', 'DoubleQuoted')
                        new_element.text = left + right

                        log_debug(
                            "Merging constant strings:  '%s', '%s' to '%s'" %
                            (subnodes[0].text, subnodes[1].text,
                             new_element.text))

                        replace_node(ast, node, new_element)

                        return True

                    else:
                        items = []
                        if isinstance(left, str) and isinstance(right, list):
                            right.insert(0, left)
                            items = right
                        elif isinstance(left, list) and isinstance(right, str):
                            left.append(right)
                            items = left
                        elif isinstance(left, list) and isinstance(
                                right, list):
                            left.extend(right)
                            items = left

                        new_array_ast = create_array_literal_values(items)

                        replace_node(ast, node, new_array_ast)

                        return True
    return False
Esempio n. 3
0
def opt_binary_expression_format(ast):
    for node in ast.iter():
        if node.tag in ["BinaryExpressionAst"
                        ] and node.attrib["Operator"] == "Format":
            format_str = node.find("StringConstantExpressionAst")
            if format_str is not None:
                format_str = format_str.text

            argument_values = get_array_literal_values(
                node.find("ArrayLiteralAst"))
            if argument_values is None:
                continue

            try:
                formatted = format_str.format(*argument_values)
            except IndexError:
                continue

            new_element = Element("StringConstantExpressionAst", {
                "StringConstantType": "SingleQuoted",
                "StaticType": "string",
            })
            new_element.text = formatted

            log_debug("Apply format operation to '%s'" % formatted)

            replace_node(ast, node, new_element)

            return True
    return False
Esempio n. 4
0
def opt_binary_expression_replace(ast):
    for node in ast.iter():
        if node.tag in ["BinaryExpressionAst"
                        ] and node.attrib["Operator"] == "Ireplace":
            target = node.find("StringConstantExpressionAst")
            if target is not None:
                target = target.text

            argument_values = get_array_literal_values(
                node.find("ArrayLiteralAst"))

            if argument_values is None or len(argument_values) != 2:
                return False

            formatted = target.replace(argument_values[0], argument_values[1])

            log_debug("Apply replace operator to '%s'" % formatted)

            new_element = Element("StringConstantExpressionAst", {
                "StringConstantType": "SingleQuoted",
                "StaticType": "string",
            })
            new_element.text = formatted

            replace_node(ast, node, new_element)

            return True
    return False
Esempio n. 5
0
def opt_replace_constant_variable_by_value(ast):
    cst_assigned = dict()

    used_vars = get_used_vars(ast)

    for node in ast.iter():
        if node.tag in ["AssignmentStatementAst"]:
            subnodes = list(node)
            if subnodes[0].tag == "VariableExpressionAst":
                variable = subnodes[0]
                if subnodes[1].tag == "CommandExpressionAst":
                    subnodes = list(subnodes[1])
                    if len(subnodes) == 1:
                        if subnodes[0].tag == "StringConstantExpressionAst":
                            cst_assigned[variable.attrib["VariablePath"].lower()] = subnodes[0].text
                        elif subnodes[0].tag == "ArrayLiteralAst":
                            cst_assigned[variable.attrib["VariablePath"].lower()] = get_array_literal_values(
                                subnodes[0])
                    else:
                        if variable.attrib["VariablePath"].lower() in cst_assigned:
                            del cst_assigned[variable.attrib["VariablePath"].lower()]

        if node.tag in ["UnaryExpressionAst", "BinaryExpressionAst", "Arguments", "InvokeMemberExpressionAst"]:
            subnodes = list(node)
            for subnode in subnodes:
                if subnode.tag == "VariableExpressionAst":
                    var_name = subnode.attrib["VariablePath"].lower()
                    if var_name in cst_assigned and used_vars.setdefault(var_name, 0) == 1:

                        value = cst_assigned[var_name]

                        if isinstance(value, str):
                            new_element = create_constant_string(value,
                                                                 "BareWord" if node.tag == "InvokeMemberExpressionAst"
                                                                 else "DoubleQuoted")

                            log_debug("Replace constant variable %s (string) in expression" % (
                                subnode.attrib["VariablePath"]))

                            replace_node(ast, subnode, new_element)
                            return True

                        elif isinstance(value, list):
                            new_element = create_array_literal_values(value)
                            log_debug(
                                "Replace constant variable %s (array) in expression" % (subnode.attrib["VariablePath"]))
                            replace_node(ast, subnode, new_element)
                            return True

    return False
Esempio n. 6
0
def opt_binary_expression_join(ast):
    for node in ast.iter():
        if node.tag in ["BinaryExpressionAst"
                        ] and node.attrib["Operator"] == "Join":
            subnodes = list(node)

            joiner = node.find("StringConstantExpressionAst")
            if joiner is not None:
                joiner = joiner.text
                if joiner is None:
                    joiner = ""
            else:
                log_err(
                    f"BinaryExpression Join with {subnodes[0].tag} joiner is unsupported"
                )
                continue

            values = node.find("ArrayLiteralAst")
            if values is not None:
                values = get_array_literal_values(values)

            if joiner is None or values is None:
                continue

            try:
                joined = joiner.join(values)
            except Exception:
                continue

            new_element = Element("StringConstantExpressionAst", {
                "StringConstantType": "SingleQuoted",
                "StaticType": "string",
            })
            new_element.text = joined

            log_debug("Apply join operation to '%s'" % joined)

            replace_node(ast, node, new_element)

            return True
    return False