1*3f982cf4SFabien Sanglard#!/usr/bin/env python3 2*3f982cf4SFabien Sanglard# 3*3f982cf4SFabien Sanglard# Copyright (c) 2015 The Chromium Authors. All rights reserved. 4*3f982cf4SFabien Sanglard# Use of this source code is governed by a BSD-style license that can be 5*3f982cf4SFabien Sanglard# found in the LICENSE file. 6*3f982cf4SFabien Sanglard"""Generate or update an existing config (.options file) for libfuzzer test. 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien SanglardInvoked by GN from fuzzer_test.gni. 9*3f982cf4SFabien Sanglard""" 10*3f982cf4SFabien Sanglard 11*3f982cf4SFabien Sanglardimport argparse 12*3f982cf4SFabien Sanglardimport configparser 13*3f982cf4SFabien Sanglardimport os 14*3f982cf4SFabien Sanglardimport sys 15*3f982cf4SFabien Sanglard 16*3f982cf4SFabien Sanglard 17*3f982cf4SFabien Sanglarddef AddSectionOptions(config, section_name, options): 18*3f982cf4SFabien Sanglard """Add |options| to the |section_name| section of |config|. 19*3f982cf4SFabien Sanglard 20*3f982cf4SFabien Sanglard Throws an 21*3f982cf4SFabien Sanglard assertion error if any option in |options| does not have exactly two 22*3f982cf4SFabien Sanglard elements. 23*3f982cf4SFabien Sanglard """ 24*3f982cf4SFabien Sanglard if not options: 25*3f982cf4SFabien Sanglard return 26*3f982cf4SFabien Sanglard 27*3f982cf4SFabien Sanglard config.add_section(section_name) 28*3f982cf4SFabien Sanglard for option_and_value in options: 29*3f982cf4SFabien Sanglard assert len(option_and_value) == 2, ( 30*3f982cf4SFabien Sanglard '%s is not an option, value pair' % option_and_value) 31*3f982cf4SFabien Sanglard 32*3f982cf4SFabien Sanglard config.set(section_name, *option_and_value) 33*3f982cf4SFabien Sanglard 34*3f982cf4SFabien Sanglard 35*3f982cf4SFabien Sanglarddef main(): 36*3f982cf4SFabien Sanglard parser = argparse.ArgumentParser(description='Generate fuzzer config.') 37*3f982cf4SFabien Sanglard parser.add_argument('--config', required=True) 38*3f982cf4SFabien Sanglard parser.add_argument('--dict') 39*3f982cf4SFabien Sanglard parser.add_argument('--libfuzzer_options', nargs='+', default=[]) 40*3f982cf4SFabien Sanglard parser.add_argument('--asan_options', nargs='+', default=[]) 41*3f982cf4SFabien Sanglard parser.add_argument('--msan_options', nargs='+', default=[]) 42*3f982cf4SFabien Sanglard parser.add_argument('--ubsan_options', nargs='+', default=[]) 43*3f982cf4SFabien Sanglard parser.add_argument( 44*3f982cf4SFabien Sanglard '--environment_variables', 45*3f982cf4SFabien Sanglard nargs='+', 46*3f982cf4SFabien Sanglard default=[], 47*3f982cf4SFabien Sanglard choices=['AFL_DRIVER_DONT_DEFER=1']) 48*3f982cf4SFabien Sanglard args = parser.parse_args() 49*3f982cf4SFabien Sanglard 50*3f982cf4SFabien Sanglard # Script shouldn't be invoked without any arguments, but just in case. 51*3f982cf4SFabien Sanglard if not (args.dict or args.libfuzzer_options or args.environment_variables or 52*3f982cf4SFabien Sanglard args.asan_options or args.msan_options or args.ubsan_options): 53*3f982cf4SFabien Sanglard return 54*3f982cf4SFabien Sanglard 55*3f982cf4SFabien Sanglard config = configparser.ConfigParser() 56*3f982cf4SFabien Sanglard libfuzzer_options = [] 57*3f982cf4SFabien Sanglard if args.dict: 58*3f982cf4SFabien Sanglard libfuzzer_options.append(('dict', os.path.basename(args.dict))) 59*3f982cf4SFabien Sanglard libfuzzer_options.extend( 60*3f982cf4SFabien Sanglard option.split('=') for option in args.libfuzzer_options) 61*3f982cf4SFabien Sanglard 62*3f982cf4SFabien Sanglard AddSectionOptions(config, 'libfuzzer', libfuzzer_options) 63*3f982cf4SFabien Sanglard 64*3f982cf4SFabien Sanglard AddSectionOptions(config, 'asan', 65*3f982cf4SFabien Sanglard [option.split('=') for option in args.asan_options]) 66*3f982cf4SFabien Sanglard 67*3f982cf4SFabien Sanglard AddSectionOptions(config, 'msan', 68*3f982cf4SFabien Sanglard [option.split('=') for option in args.msan_options]) 69*3f982cf4SFabien Sanglard 70*3f982cf4SFabien Sanglard AddSectionOptions(config, 'ubsan', 71*3f982cf4SFabien Sanglard [option.split('=') for option in args.ubsan_options]) 72*3f982cf4SFabien Sanglard 73*3f982cf4SFabien Sanglard AddSectionOptions( 74*3f982cf4SFabien Sanglard config, 'env', 75*3f982cf4SFabien Sanglard [option.split('=') for option in args.environment_variables]) 76*3f982cf4SFabien Sanglard 77*3f982cf4SFabien Sanglard # Generate .options file. 78*3f982cf4SFabien Sanglard config_path = args.config 79*3f982cf4SFabien Sanglard with open(config_path, 'w') as options_file: 80*3f982cf4SFabien Sanglard options_file.write( 81*3f982cf4SFabien Sanglard '# This is an automatically generated config for ClusterFuzz.\n') 82*3f982cf4SFabien Sanglard config.write(options_file) 83*3f982cf4SFabien Sanglard 84*3f982cf4SFabien Sanglard 85*3f982cf4SFabien Sanglardif __name__ == '__main__': 86*3f982cf4SFabien Sanglard main() 87