1 #!/usr/bin/env python 2 # Copyright 2014 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 7 """Takes the JSON files in components/domain_reliability/baked_in_configs and 8 encodes their contents as an array of C strings that gets compiled in to Chrome 9 and loaded at runtime.""" 10 11 12 import json 13 import os 14 import sys 15 16 17 # A whitelist of domains that the script will accept when baking configs in to 18 # Chrome, to ensure incorrect ones are not added accidentally. Subdomains of 19 # whitelist entries are also allowed (e.g. maps.google.com, ssl.gstatic.com). 20 DOMAIN_WHITELIST = ('2mdn.net', 'admob.com', 'doubleclick.net', 'ggpht.com', 21 'google.cn', 'google.co.uk', 'google.com', 'google.com.au', 22 'google.de', 'google.fr', 'google.it', 'google.jp', 23 'google.org', 'google.ru', 'googleadservices.com', 24 'googleapis.com', 'googlesyndication.com', 25 'googleusercontent.com', 'googlevideo.com', 'gstatic.com', 26 'gvt1.com', 'youtube.com', 'ytimg.com') 27 28 29 CC_HEADER = """// Copyright (C) 2014 The Chromium Authors. All rights reserved. 30 // Use of this source code is governed by a BSD-style license that can be 31 // found in the LICENSE file. 32 33 // AUTOGENERATED FILE. DO NOT EDIT. 34 // 35 // (Update configs in components/domain_reliability/baked_in_configs and list 36 // configs in components/domain_reliability.gypi instead.) 37 38 #include "components/domain_reliability/baked_in_configs.h" 39 40 #include <stdlib.h> 41 42 namespace domain_reliability { 43 44 const char* const kBakedInJsonConfigs[] = { 45 """ 46 47 48 CC_FOOTER = """ NULL 49 }; 50 51 } // namespace domain_reliability 52 """ 53 54 55 def domain_is_whitelisted(domain): 56 return any(domain == e or domain.endswith('.' + e) for e in DOMAIN_WHITELIST) 57 58 59 def quote_and_wrap_text(text, width=79, prefix=' "', suffix='"'): 60 max_length = width - len(prefix) - len(suffix) 61 output = prefix 62 line_length = 0 63 for c in text: 64 if c == "\"": 65 c = "\\\"" 66 elif c == "\n": 67 c = "\\n" 68 elif c == "\\": 69 c = "\\\\" 70 if line_length + len(c) > max_length: 71 output += suffix + "\n" + prefix 72 line_length = 0 73 output += c 74 line_length += len(c) 75 output += suffix 76 return output 77 78 79 def main(): 80 if len(sys.argv) < 3: 81 print >> sys.stderr, ('Usage: %s <JSON files...> <output C++ file>' % 82 sys.argv[0]) 83 print >> sys.stderr, sys.modules[__name__].__doc__ 84 return 1 85 86 cpp_code = CC_HEADER 87 found_invalid_config = False 88 for json_file in sys.argv[1:-1]: 89 with open(json_file, 'r') as f: 90 json_text = f.read() 91 config = json.loads(json_text) 92 if 'monitored_domain' not in config: 93 print >> sys.stderr, ('%s: no monitored_domain found' % json_file) 94 found_invalid_config = True 95 continue 96 domain = config['monitored_domain'] 97 if not domain_is_whitelisted(domain): 98 print >> sys.stderr, ('%s: monitored_domain "%s" not in whitelist' % 99 (json_file, domain)) 100 found_invalid_config = True 101 continue 102 cpp_code += " // " + json_file + ":\n" 103 cpp_code += quote_and_wrap_text(json_text) + ",\n" 104 cpp_code += "\n" 105 cpp_code += CC_FOOTER 106 107 if found_invalid_config: 108 return 1 109 110 with open(sys.argv[-1], 'wb') as f: 111 f.write(cpp_code) 112 113 return 0 114 115 116 if __name__ == '__main__': 117 sys.exit(main()) 118