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
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
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)
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
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