summaryrefslogtreecommitdiff
path: root/scripts/clusterfuzz/run.py
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-11-21 15:04:29 -0800
committerGitHub <noreply@github.com>2024-11-21 15:04:29 -0800
commit4488a3e351214e038600f58e5806c31ad0bfae46 (patch)
tree1306b6a89a5fd54ec77e9ed7ce6cdcb4fd5fde1c /scripts/clusterfuzz/run.py
parent901ba6024f3ca9117c5720be3cf19ab75034070a (diff)
downloadbinaryen-4488a3e351214e038600f58e5806c31ad0bfae46.tar.gz
binaryen-4488a3e351214e038600f58e5806c31ad0bfae46.tar.bz2
binaryen-4488a3e351214e038600f58e5806c31ad0bfae46.zip
[NFC] Refactor ClusterFuzz run.py (#7101)
This just moves code around. It will allow more code reuse in a later PR. Also add a bit of test logging.
Diffstat (limited to 'scripts/clusterfuzz/run.py')
-rwxr-xr-xscripts/clusterfuzz/run.py99
1 files changed, 58 insertions, 41 deletions
diff --git a/scripts/clusterfuzz/run.py b/scripts/clusterfuzz/run.py
index 4b5e67fde..6bbb74ef8 100755
--- a/scripts/clusterfuzz/run.py
+++ b/scripts/clusterfuzz/run.py
@@ -93,17 +93,64 @@ def get_file_name(prefix, index):
system_random = random.SystemRandom()
-# Returns the contents of a .js fuzz file, given particular wasm contents that
-# we want to be executed.
-def get_js_file_contents(wasm_contents):
+# Generate a random wasm file, and return a string that creates a typed array of
+# those bytes, suitable for use in a JS file, in the form
+#
+# new Uint8Array([..wasm_contents..])
+#
+# Receives the testcase index and the output dir.
+def get_wasm_contents(i, output_dir):
+ input_data_file_path = os.path.join(output_dir, f'{i}.input')
+ wasm_file_path = os.path.join(output_dir, f'{i}.wasm')
+
+ # wasm-opt may fail to run in rare cases (when the fuzzer emits code it
+ # detects as invalid). Just try again in such a case.
+ for attempt in range(0, 100):
+ # Generate random data.
+ random_size = system_random.randint(1, MAX_RANDOM_SIZE)
+ with open(input_data_file_path, 'wb') as file:
+ file.write(os.urandom(random_size))
+
+ # Generate wasm from the random data.
+ cmd = [FUZZER_BINARY_PATH] + FUZZER_ARGS
+ cmd += ['-o', wasm_file_path, input_data_file_path]
+ try:
+ subprocess.check_call(cmd)
+ except subprocess.CalledProcessError:
+ # Try again.
+ print('(oops, retrying wasm-opt)')
+ attempt += 1
+ if attempt == 99:
+ # Something is very wrong!
+ raise
+ continue
+ # Success, leave the loop.
+ break
+
+ # Generate a testcase from the wasm
+ with open(wasm_file_path, 'rb') as file:
+ wasm_contents = file.read()
+
+ # Clean up temp files.
+ os.remove(wasm_file_path)
+ os.remove(input_data_file_path)
+
+ # Convert to a string, and wrap into a typed array.
+ wasm_contents = ','.join([str(c) for c in wasm_contents])
+ return f'new Uint8Array([{wasm_contents}])'
+
+
+# Returns the contents of a .js fuzz file, given the index of the testcase and
+# the output dir.
+def get_js_file_contents(i, output_dir):
# Start with the standard JS shell.
with open(JS_SHELL_PATH) as file:
js = file.read()
# Prepend the wasm contents, so they are used (rather than the normal
# mechanism where the wasm file's name is provided in argv).
- wasm_contents = ','.join([str(c) for c in wasm_contents])
- js = f'var binary = new Uint8Array([{wasm_contents}]);\n\n' + js
+ wasm_contents = get_wasm_contents(i, output_dir)
+ js = f'var binary = {wasm_contents};\n\n' + js
# The default JS builds and runs the wasm. Append some random additional
# operations as well, as more compiles and executions can find things. To
@@ -133,6 +180,8 @@ def get_js_file_contents(wasm_contents):
'callExports();\n',
])
+ print(f'Created {wasm_contents.count(",")} wasm bytes')
+
return js
@@ -150,39 +199,11 @@ def main(argv):
num = int(value)
for i in range(1, num + 1):
- input_data_file_path = os.path.join(output_dir, f'{i}.input')
- wasm_file_path = os.path.join(output_dir, f'{i}.wasm')
-
- # wasm-opt may fail to run in rare cases (when the fuzzer emits code it
- # detects as invalid). Just try again in such a case.
- for attempt in range(0, 100):
- # Generate random data.
- random_size = system_random.randint(1, MAX_RANDOM_SIZE)
- with open(input_data_file_path, 'wb') as file:
- file.write(os.urandom(random_size))
-
- # Generate wasm from the random data.
- cmd = [FUZZER_BINARY_PATH] + FUZZER_ARGS
- cmd += ['-o', wasm_file_path, input_data_file_path]
- try:
- subprocess.check_call(cmd)
- except subprocess.CalledProcessError:
- # Try again.
- print('(oops, retrying wasm-opt)')
- attempt += 1
- if attempt == 99:
- # Something is very wrong!
- raise
- continue
- # Success, leave the loop.
- break
-
- # Generate a testcase from the wasm
- with open(wasm_file_path, 'rb') as file:
- wasm_contents = file.read()
testcase_file_path = os.path.join(output_dir,
get_file_name(FUZZ_FILENAME_PREFIX, i))
- js_file_contents = get_js_file_contents(wasm_contents)
+
+ # Emit the JS file.
+ js_file_contents = get_js_file_contents(i, output_dir)
with open(testcase_file_path, 'w') as file:
file.write(js_file_contents)
@@ -192,11 +213,7 @@ def main(argv):
with open(flags_file_path, 'w') as file:
file.write(FUZZER_FLAGS_FILE_CONTENTS)
- print(f'Created testcase: {testcase_file_path}, {len(wasm_contents)} bytes')
-
- # Remove temporary files.
- os.remove(input_data_file_path)
- os.remove(wasm_file_path)
+ print(f'Created testcase: {testcase_file_path}')
print(f'Created {num} testcases.')