├── qlpack.yml ├── test-data ├── data.csv.gz ├── php_php-fuzz-parser_ranking.svg ├── libpcap_fuzz_both_ranking.svg ├── freetype2-2017_ranking.svg └── libxml2-v2.9.2_ranking.svg ├── array-literals.ql ├── local-variables.ql ├── Global-values.ql ├── globals-values.ql ├── memcmpvals.ql ├── strstrvals.ql ├── strcmpvals.ql ├── magic-values.ql ├── strtool.ql ├── regex-values.ql ├── README.md ├── MIT-License.txt ├── Global-values.py ├── magic-values.py ├── memcmpvals.py ├── regex-values.py ├── strcmpvals.py ├── strstrvals.py ├── array-literals.py ├── local-variables.py └── run.py /qlpack.yml: -------------------------------------------------------------------------------- 1 | name: fuzzingdriver 2 | version: 0.0.0 3 | libraryPathDependencies: codeql-cpp 4 | -------------------------------------------------------------------------------- /test-data/data.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cryptomadco/fuzzingdriver/HEAD/test-data/data.csv.gz -------------------------------------------------------------------------------- /array-literals.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | 3 | from ArrayAggregateLiteral a 4 | 5 | select a.getElementExpr(_).getValueText() 6 | -------------------------------------------------------------------------------- /local-variables.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | 3 | from LocalVariable v 4 | 5 | select v.getAnAssignedValue().getValueText() 6 | -------------------------------------------------------------------------------- /Global-values.ql: -------------------------------------------------------------------------------- 1 | 2 | import cpp 3 | 4 | from GlobalVariable gb 5 | 6 | select gb.getAnAssignedValue().getValueText().toString() 7 | -------------------------------------------------------------------------------- /globals-values.ql: -------------------------------------------------------------------------------- 1 | /** 2 | * @kind problem 3 | */ 4 | import cpp 5 | 6 | from GlobalVariable gb 7 | 8 | select gb.getAnAssignedValue().getValueText().toString() 9 | -------------------------------------------------------------------------------- /memcmpvals.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | from FunctionCall fucall, Expr size 3 | where 4 | fucall.getTarget().hasName("memcmp") 5 | select fucall.getArgument(_).getValueText() 6 | -------------------------------------------------------------------------------- /strstrvals.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | from FunctionCall fucall, Expr size 3 | where 4 | fucall.getTarget().hasName("strstr") 5 | select fucall.getArgument(_).getValueText() 6 | -------------------------------------------------------------------------------- /strcmpvals.ql: -------------------------------------------------------------------------------- 1 | 2 | import cpp 3 | from FunctionCall fucall, Expr size 4 | where 5 | fucall.getTarget().hasName("strncmp") 6 | select fucall.getArgument(_).getValueText() 7 | -------------------------------------------------------------------------------- /magic-values.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | 3 | class HexOrOctLiteral extends Literal{ 4 | HexOrOctLiteral(){ 5 | (this instanceof HexLiteral) or (this instanceof OctalLiteral) 6 | } 7 | } 8 | 9 | from HexOrOctLiteral lit 10 | select lit.getValueText() 11 | -------------------------------------------------------------------------------- /strtool.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | import semmle.code.cpp.dataflow.DataFlow 3 | class StringLiteralNode extends DataFlow::Node { 4 | StringLiteralNode() { this.asExpr() instanceof StringLiteral } 5 | } 6 | class MemcmpArgNode extends DataFlow::Node { 7 | MemcmpArgNode() { 8 | exists(FunctionCall fc | 9 | fc.getTarget().getName().regexpMatch(".*(str|mem|strn|b)*(cmp|str)*") and 10 | fc.getArgument(0) = this.asExpr() 11 | ) 12 | or 13 | exists(FunctionCall fc | 14 | fc.getTarget().getName().regexpMatch(".*(str|mem|strn|b)*(cmp|str)*") and 15 | fc.getArgument(1) = this.asExpr() 16 | ) 17 | } 18 | } 19 | 20 | from StringLiteralNode src, MemcmpArgNode arg 21 | where 22 | DataFlow::localFlow(src, arg) 23 | 24 | select src.asExpr().(StringLiteral).toString() 25 | -------------------------------------------------------------------------------- /regex-values.ql: -------------------------------------------------------------------------------- 1 | import cpp 2 | import semmle.code.cpp.dataflow.DataFlow 3 | class StringLiteralNode extends DataFlow::Node { 4 | StringLiteralNode() { this.asExpr() instanceof StringLiteral } 5 | } 6 | class MemcmpArgNode extends DataFlow::Node { 7 | MemcmpArgNode() { 8 | exists(FunctionCall fc | 9 | fc.getTarget().getName().regexpMatch(".*(str|mem|strn|b)*(cmp|str)*") and 10 | fc.getArgument(0) = this.asExpr() 11 | ) 12 | or 13 | exists(FunctionCall fc | 14 | fc.getTarget().getName().regexpMatch(".*(str|mem|strn|b)*(cmp|str)*") and 15 | fc.getArgument(1) = this.asExpr() 16 | ) 17 | } 18 | } 19 | 20 | from StringLiteralNode src, MemcmpArgNode arg 21 | where 22 | DataFlow::localFlow(src, arg) 23 | 24 | select src.asExpr().(StringLiteral).toString() 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FuzzingDriver 2 | 3 | [FuzzingDriver: the Missing Dictionary to Increase Code Coverage in Fuzzers, SANER'22](https://arxiv.org/pdf/2201.04853.pdf) 4 | 5 | 6 | We propose a tool, called FuzzingDriver, to generate dictionary tokens for coverage-based greybox fuzzers (CGF) from the codebase of any target program. FuzzingDriver does not add any overhead to the fuzzing job as it is run beforehand. We compared FuzzingDriver to Google dictionaries by fuzzing six open-source targets, and we found that FuzzingDriver consistently achieves higher code coverage in all tests. We also executed eight benchmarks on FuzzBench to demonstrate how utilizing FuzzingDriver's dictionaries can outperform six widely-used CGF fuzzers. In future work, investigating the impact of FuzzingDriver's dictionaries on improving bug coverage might prove important. 7 | 8 | [Video demonstration](https://www.youtube.com/watch?v=Y8j_KvfRrI8) 9 | -------------------------------------------------------------------------------- /MIT-License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2022] [FuzzingDriver] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Global-values.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-globals{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /magic-values.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-magic{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /memcmpvals.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-memcmp{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /regex-values.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-regex{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /strcmpvals.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-strcmp{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /strstrvals.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-strstr{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /array-literals.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-arrlits{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /local-variables.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ##################################################################### 4 | # FuzzingDriver # 5 | # The missing dictionary to increase code coverage in fuzzers # 6 | ##################################################################### 7 | 8 | import os 9 | import string 10 | import binascii 11 | import codecs 12 | import errno 13 | import struct 14 | import argparse 15 | import re 16 | from binascii import unhexlify 17 | 18 | 19 | def ensure_dir(dir): 20 | try: 21 | os.makedirs(dir) 22 | except OSError as e: 23 | if e.errno != errno.EEXIST: 24 | raise 25 | 26 | 27 | def parse_args(): 28 | parser = argparse.ArgumentParser( 29 | description=( 30 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python2 thisfile.py outdir str.txt" 31 | ) 32 | ) 33 | parser.add_argument( 34 | "corpdir", help="The path to the corpus directory to generate strings." 35 | ) 36 | parser.add_argument( 37 | "infile", 38 | help="Specify file output of codeql analysis - ex. ooo-atr.txt, analysis take place on this file, example : python2 thisfile.py outdir strings.txt", 39 | ) 40 | 41 | return parser.parse_args() 42 | 43 | 44 | def do_string_analysis(corpdir, infile1): 45 | with open(infile1, "r") as f1: 46 | lines = f1.readlines()[1:] 47 | f1.close() 48 | new_lst1 = [] 49 | n = 1 50 | for i, num1 in enumerate(lines): 51 | if i != 0: 52 | new_lst1.append(num1) 53 | # print("num : %s" % num1) 54 | str11 = str(num1) 55 | str11 = str11.replace("|", "") 56 | str11 = str11.replace("\n", "") 57 | str11 = str11.lstrip() 58 | str11 = str11.rstrip() 59 | str11 = str(str11) 60 | if ( 61 | (" " in str11) 62 | or (")" in str11) 63 | or ("(" in str11) 64 | or ("<" in str11) 65 | or (">" in str11) 66 | ): 67 | print("Space / Paranthesis String : %s" % str11) 68 | else: 69 | with open(corpdir + "/seed-globals{0}".format(n), "w") as file: 70 | file.write(str11) 71 | print( 72 | "Extracting : %s" 73 | % str11 74 | ) 75 | n = n + 1 76 | 77 | 78 | def main(): 79 | args = parse_args() 80 | ensure_dir(args.corpdir) 81 | do_string_analysis(args.corpdir, args.infile) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import string 4 | import binascii 5 | import codecs 6 | import errno 7 | import struct 8 | import argparse 9 | import shutil 10 | import subprocess 11 | 12 | from binascii import unhexlify 13 | 14 | 15 | def ensure_dir(dir): 16 | try: 17 | os.makedirs(dir) 18 | except OSError as e: 19 | if e.errno != errno.EEXIST: 20 | raise 21 | 22 | 23 | def parse_args(): 24 | parser = argparse.ArgumentParser( 25 | description=( 26 | "Helper - Specify input file analysis and output folder to save corpus for strings in the overall project --------------------------------------------------------------------------- Example usage : python3 thisfile.py outdir str.txt" 27 | ) 28 | ) 29 | 30 | # parser.add_argument("tokenpath", 31 | # help="Destination directory for tokens") 32 | parser.add_argument("cur", help="Current Path") 33 | parser.add_argument("db", help="CodeQL database Path") 34 | parser.add_argument("tokenpath", help="Destination directory for tokens") 35 | 36 | return parser.parse_args() 37 | 38 | 39 | def static_analysis(file, file2, cur, db): 40 | with open(cur + "/" + file, "w") as f: 41 | print(cur + "/" + file) 42 | stream = os.popen("codeql query run " + cur + "/" + file2 + " -d " + db) 43 | output = stream.read() 44 | f.write(output) 45 | f.close() 46 | 47 | 48 | def copy_tokens(cur, tokenpath): 49 | subprocess.call( 50 | ["mv " + cur + "/" + "arrlits/*" + " " + cur + "/" + tokenpath + "/."], 51 | shell=True, 52 | ) 53 | 54 | subprocess.call( 55 | ["mv " + cur + "/" + "globals/*" + " " + cur + "/" + tokenpath + "/."], 56 | shell=True, 57 | ) 58 | subprocess.call( 59 | ["mv " + cur + "/" + "locals/*" + " " + cur + "/" + tokenpath + "/."], 60 | shell=True, 61 | ) 62 | subprocess.call( 63 | ["mv " + cur + "/" + "magics/*" + " " + cur + "/" + tokenpath + "/."], shell=True 64 | ) 65 | subprocess.call( 66 | ["mv " + cur + "/" + "memcmp-vals/*" + " " + cur + "/" + tokenpath + "/."], 67 | shell=True, 68 | ) 69 | subprocess.call( 70 | ["rm -rf strcmp-strs memcmp-strs strncmp-strs lits strtool-strs"], shell=True 71 | ) 72 | subprocess.call(["rm *.out"], shell=True) 73 | subprocess.call(["find " + tokenpath + " -size 0 -delete"], shell=True) 74 | 75 | 76 | def codeql_analysis(cur, db): 77 | print("codeql analysis func") 78 | static_analysis("arrlits.out", "array-literals.ql", cur, db) 79 | static_analysis("magics.out", "magic-values.ql", cur, db) 80 | static_analysis("memcmpvals.out", "memcmpvals.ql", cur, db) 81 | static_analysis("regex.out", "regex-values.ql", cur, db) 82 | static_analysis("strcmpvals.out", "strcmpvals.ql", cur, db) 83 | static_analysis("globals.out", "Global-values.ql", cur, db) 84 | static_analysis("strstr.out", "strstrvals.ql", cur, db) 85 | static_analysis("locals.out", "local-variables.ql", cur, db) 86 | 87 | 88 | start_fd(0, cur) 89 | 90 | 91 | def start_fd 92 | (tokenpath, cur): 93 | print("At start func") 94 | command = ["python3", cur + "/array-literals.py", cur + "/arrlits/.", cur + "/arrlits.out"] 95 | worker1 = subprocess.Popen(command) 96 | print(worker1.communicate()) 97 | 98 | command1 = [ 99 | "python3", 100 | cur + "/Global-values.py", 101 | cur + "/globals/", 102 | cur + "/globals.out", 103 | ] 104 | worker2 = subprocess.Popen(command1) 105 | print(worker2.communicate()) 106 | 107 | command2 = [ 108 | "python3", 109 | cur + "/local-variables.py", 110 | cur + "/locals/", 111 | cur + "/locals.out", 112 | ] 113 | worker3 = subprocess.Popen(command2) 114 | print(worker3.communicate()) 115 | 116 | command5 = [ 117 | "python3", 118 | cur + "/magic-values.py", 119 | cur + "/magics/", 120 | cur + "/magics.out", 121 | ] 122 | worker6 = subprocess.Popen(command5) 123 | print(worker6.communicate()) 124 | 125 | command8 = [ 126 | "python3", 127 | cur + "/memcmpvals.py", 128 | cur + "/memcmpvals/", 129 | cur + "/memcmpvals.out", 130 | ] 131 | worker9 = subprocess.Popen(command8) 132 | print(worker9.communicate()) 133 | 134 | command9 = [ 135 | "python3", 136 | cur + "/regex-values.py", 137 | cur + "/regexvals/", 138 | cur + "/regex.out", 139 | ] 140 | worker7 = subprocess.Popen(command9) 141 | print(worker7.communicate()) 142 | 143 | command10 = [ 144 | "python3", 145 | cur + "/strcmpvals.py", 146 | cur + "/strcmpvals/", 147 | cur + "/strcmpvals.out", 148 | ] 149 | worker8 = subprocess.Popen(command8) 150 | print(worker8.communicate()) 151 | 152 | command11 = [ 153 | "python3", 154 | cur + "/strstrvals.py", 155 | cur + "/strstrvals/", 156 | cur + "/strstr.out", 157 | ] 158 | worker10 = subprocess.Popen(command11) 159 | print(worker10.communicate()) 160 | 161 | 162 | 163 | def main(): 164 | args = parse_args() 165 | ensure_dir(args.tokenpath) 166 | codeql_analysis(args.cur, args.db) 167 | copy_tokens(args.cur, args.tokenpath) 168 | 169 | 170 | 171 | if __name__ == "__main__": 172 | main() 173 | -------------------------------------------------------------------------------- /test-data/php_php-fuzz-parser_ranking.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 2020-10-16T15:44:23.572925 11 | image/svg+xml 12 | 13 | 14 | Matplotlib v3.3.2, https://matplotlib.org/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 48 | 49 | 50 | 56 | 57 | 58 | 64 | 65 | 66 | 72 | 73 | 74 | 80 | 81 | 82 | 88 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 145 | 165 | 171 | 202 | 232 | 248 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 360 | 381 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 434 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 520 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 570 | 571 | 583 | 602 | 635 | 661 | 682 | 691 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1018 | 1019 | 1020 | 1023 | 1024 | 1025 | 1028 | 1029 | 1030 | 1033 | 1034 | 1035 | 1038 | 1039 | 1040 | 1043 | 1044 | 1045 | 1048 | 1049 | 1050 | 1053 | 1054 | 1055 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1069 | 1075 | 1105 | 1116 | 1124 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1186 | -------------------------------------------------------------------------------- /test-data/libpcap_fuzz_both_ranking.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 2020-10-16T15:43:27.653910 11 | image/svg+xml 12 | 13 | 14 | Matplotlib v3.3.2, https://matplotlib.org/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 48 | 49 | 50 | 56 | 57 | 58 | 64 | 65 | 66 | 72 | 73 | 74 | 80 | 81 | 82 | 88 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 145 | 165 | 171 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 226 | 245 | 265 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 379 | 400 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 507 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 572 | 573 | 585 | 604 | 637 | 663 | 684 | 693 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1054 | 1055 | 1056 | 1059 | 1060 | 1061 | 1064 | 1065 | 1066 | 1069 | 1070 | 1071 | 1074 | 1075 | 1076 | 1079 | 1080 | 1081 | 1084 | 1085 | 1086 | 1089 | 1090 | 1091 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1124 | 1130 | 1160 | 1171 | 1179 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | -------------------------------------------------------------------------------- /test-data/freetype2-2017_ranking.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 2020-10-16T15:42:50.357572 11 | image/svg+xml 12 | 13 | 14 | Matplotlib v3.3.2, https://matplotlib.org/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 48 | 49 | 50 | 56 | 57 | 58 | 64 | 65 | 66 | 72 | 73 | 74 | 80 | 81 | 82 | 88 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 145 | 165 | 171 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 226 | 242 | 263 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 331 | 351 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 428 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 520 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 570 | 571 | 583 | 602 | 635 | 661 | 682 | 691 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 828 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1048 | 1049 | 1050 | 1053 | 1054 | 1055 | 1058 | 1059 | 1060 | 1063 | 1064 | 1065 | 1068 | 1069 | 1070 | 1073 | 1074 | 1075 | 1078 | 1079 | 1080 | 1083 | 1084 | 1085 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1109 | 1115 | 1145 | 1156 | 1188 | 1196 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | -------------------------------------------------------------------------------- /test-data/libxml2-v2.9.2_ranking.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 2020-10-16T15:43:45.962271 11 | image/svg+xml 12 | 13 | 14 | Matplotlib v3.3.2, https://matplotlib.org/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 48 | 49 | 50 | 56 | 57 | 58 | 64 | 65 | 66 | 72 | 73 | 74 | 80 | 81 | 82 | 88 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 145 | 165 | 171 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 226 | 245 | 265 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 393 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 467 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 532 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 572 | 573 | 585 | 604 | 637 | 663 | 684 | 693 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1040 | 1041 | 1042 | 1045 | 1046 | 1047 | 1050 | 1051 | 1052 | 1055 | 1056 | 1057 | 1060 | 1061 | 1062 | 1065 | 1066 | 1067 | 1070 | 1071 | 1072 | 1075 | 1076 | 1077 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1110 | 1124 | 1130 | 1136 | 1166 | 1177 | 1209 | 1217 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | --------------------------------------------------------------------------------