예제 #1
0
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
예제 #2
0
def opt_invoke_split_string(ast):
    for node in ast.iter():
        if node.tag == "InvokeMemberExpressionAst":
            subnodes = list(node)

            if len(subnodes) < 3:
                continue

            if subnodes[2].tag == 'StringConstantExpressionAst' and \
                    subnodes[2].attrib["StringConstantType"] == "BareWord" and \
                    subnodes[2].text.lower() == "split":
                if subnodes[1].tag == 'StringConstantExpressionAst' and \
                        subnodes[1].attrib["StringConstantType"] != "BareWord":
                    argument = subnodes[0]
                    if argument is not None:
                        argument = argument.find("StringConstantExpressionAst")
                        if argument is not None:

                            splitted = subnodes[1].text.split(argument.text)

                            new_array_ast = create_array_literal_values(splitted)

                            log_debug("Apply split operation to %s" % splitted)

                            replace_node(ast, node, new_array_ast)
                            return True
    return False
예제 #3
0
def opt_convert_type_to_array(ast):
    for node in ast.iter():
        if node.tag in ["ConvertExpressionAst"]:
            type_name = node.find("TypeConstraintAst")
            if type_name is not None:
                type_name = type_name.attrib["TypeName"].lower()

            if type_name == "array":
                cst_string_node = node.find("StringConstantExpressionAst")
                if cst_string_node is not None:

                    log_debug("Replace array of one string to string '%s'" %
                              cst_string_node.text)

                    replace_node(ast, node, cst_string_node)

            elif type_name == "char[]":
                cst_string_node = node.find("StringConstantExpressionAst")
                if cst_string_node is not None:
                    arrayed = [c for c in cst_string_node.text]

                    new_array_ast = create_array_literal_values(arrayed)

                    log_debug("Replace (cast) string to array: '%s'" % arrayed)

                    replace_node(ast, node, new_array_ast)
예제 #4
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
예제 #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