def prune_tree(self, tree): name, children = tree if self.coalesce: children = self.coalesce(children) if name in self.tokens: return (name, [(tree_to_string(tree), [])]) else: return (name, [self.prune_tree(c) for c in children])
def swap_fragment(self, seed): """Substitutes a random fragment with another with the same symbol""" if seed.has_structure: n_nodes = self.count_nodes(seed.structure) self.to_swap = random.randint(2, n_nodes) new_structure = self.recursive_swap(seed.structure) new_seed = Seed(tree_to_string(new_structure)) new_seed.has_structure = True new_seed.structure = new_structure return new_seed return seed
def delete_fragment(self, seed): """Deletes a random fragment""" if seed.has_structure: n_nodes = self.count_nodes(seed.structure) self.to_delete = random.randint(2, n_nodes) new_structure = self.recursive_delete(seed.structure) new_seed = Seed(tree_to_string(new_structure)) new_seed.has_structure = True new_seed.structure = new_structure # do not return an empty new_seed if not new_seed.data: return seed else: return new_seed return seed
def swap_fragment(self, seed): """Chooses a random region and swaps it with a fragment that starts with the same symbol""" if not seed.has_structure and seed.has_regions: regions = [ r for r in seed.regions if (len(seed.regions[r]) > 0 and len(self.fragments[r]) > 0) ] if len(regions) == 0: return seed key = random.choice(list(regions)) s, e = random.choice(list(seed.regions[key])) swap_structure = random.choice(self.fragments[key]) swap_string = tree_to_string(swap_structure) new_seed = Seed(seed.data[:s] + swap_string + seed.data[e:]) new_seed.has_structure = False new_seed.has_regions = False return new_seed else: return super().swap_fragment(seed)
from GrammarFuzzer import tree_to_string else: from .GrammarFuzzer import tree_to_string if __name__ == "__main__": valid_seed = Seed( "<html><header><title>Hello</title></header><body>World<br/></body></html>" ) fragment_mutator = FragmentMutator( EarleyParser(XML_GRAMMAR, tokens=XML_TOKENS)) fragment_mutator.add_to_fragment_pool(valid_seed) for key in fragment_mutator.fragments: print(key) for f in fragment_mutator.fragments[key]: print("|-%s" % tree_to_string(f)) # ### Fragment-Based Mutation if __name__ == "__main__": print('\n### Fragment-Based Mutation') class FragmentMutator(FragmentMutator): def __init__(self, parser): """Initialize mutators""" super().__init__(parser) self.seen_seeds = [] def mutate(self, seed): """Implement structure-aware mutation. Memoize seeds."""
"<digit>": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] } if __name__ == "__main__": syntax_diagram(A1_GRAMMAR) if __name__ == "__main__": mystring = '1+2' if __name__ == "__main__": tree = ('<start>', [ ('<expr>', [('<expr>', [('<integer>', [('<digit>', [('1', [])])])]), ('+', []), ('<expr>', [('<integer>', [('<digit>', [('2', [])])])])]) ]) assert mystring == tree_to_string(tree) display_tree(tree) A2_GRAMMAR = { "<start>": ["<expr>"], "<expr>": ["<integer><expr_>"], "<expr_>": ["+<expr>", "-<expr>", ""], "<integer>": ["<digit><integer_>"], "<integer_>": ["<integer>", ""], "<digit>": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] } if __name__ == "__main__": syntax_diagram(A2_GRAMMAR) if __name__ == "__main__":
def fuzz(self): tree, node = self.candidate() tree_with_a_hole = self.generate_new_tree(tree, node) modified = self.gfuzz.expand_tree(tree_with_a_hole) return tree_to_string(modified)
def fuzz(self): tree, node = self.candidate() modified = self.generate_new_tree(tree, node) return tree_to_string(modified)
lf = LangFuzzer(PEGParser(VAR_GRAMMAR, tokens=VAR_TOKENS), mystrings) tree, node = lf.candidate() def hl_predicate(_d, nid, _s, _a): return nid in {node} if __package__ is None or __package__ == "": from GrammarFuzzer import tree_to_string else: from .GrammarFuzzer import tree_to_string if __name__ == "__main__": new_tree = lf.generate_new_tree(tree, node) for s in [tree_to_string(i) for i in [tree, new_tree]]: print(s) display_tree(new_tree, node_attr=highlight_node(hl_predicate)) # #### Fuzz if __name__ == "__main__": print('\n#### Fuzz') class LangFuzzer(LangFuzzer): def fuzz(self): tree, node = self.candidate() modified = self.generate_new_tree(tree, node) return tree_to_string(modified)