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"""Removes ViewHostMsg_Close and alike from testcases. These messages are an
7annoyance for corpus distillation. They cause the browser to exit, so no
8further messages are processed. On the other hand, ViewHostMsg_Close is useful
9for fuzzing - many found bugs are related to a renderer disappearing. So the
10fuzzer should be crafting random ViewHostMsg_Close messages.
11"""
12
13import argparse
14import os
15import platform
16import shutil
17import subprocess
18import sys
19import tempfile
20
21def create_temp_file():
22  temp_file = tempfile.NamedTemporaryFile(delete=False)
23  temp_file.close()
24  return temp_file.name
25
26def main():
27  desc = 'Remove ViewHostMsg_Close and alike from the testcases.'
28  parser = argparse.ArgumentParser(description=desc)
29  parser.add_argument('--out-dir', dest='out_dir', default='out',
30                      help='ouput directory under src/ directory')
31  parser.add_argument('--build-type', dest='build_type', default='Release',
32                      help='Debug vs. Release build')
33  parser.add_argument('testcase_dir',
34                      help='Directory containing testcases')
35  parsed = parser.parse_args()
36
37  message_util_binary = 'ipc_message_util'
38
39  script_path = os.path.realpath(__file__)
40  ipc_fuzzer_dir = os.path.dirname(script_path)
41  src_dir = os.path.abspath(os.path.join(ipc_fuzzer_dir, os.pardir, os.pardir))
42  out_dir =  os.path.join(src_dir, parsed.out_dir);
43  build_dir = os.path.join(out_dir, parsed.build_type)
44
45  message_util_path = os.path.join(build_dir, message_util_binary)
46  if not os.path.exists(message_util_path):
47    print 'ipc_message_util executable not found at ', message_util_path
48    return 1
49
50  filter_command = [
51    message_util_path,
52    '--invert',
53    '--regexp=ViewHostMsg_Close|ViewHostMsg_ClosePage_ACK',
54    'input',
55    'output',
56  ]
57
58  testcase_list = os.listdir(parsed.testcase_dir)
59  testcase_count = len(testcase_list)
60  index = 0
61  for testcase in testcase_list:
62    index += 1
63    print '[%d/%d] Processing %s' % (index, testcase_count, testcase)
64    testcase_path = os.path.join(parsed.testcase_dir, testcase)
65    filtered_path = create_temp_file()
66    filter_command[-2] = testcase_path
67    filter_command[-1] = filtered_path
68    subprocess.call(filter_command)
69    shutil.move(filtered_path, testcase_path)
70
71  return 0
72
73
74if __name__ == "__main__":
75  sys.exit(main())
76