John Stiles | 9ef6927 | 2021-08-26 09:34:44 -0400 | [diff] [blame^] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright 2021 Google LLC |
| 4 | # |
| 5 | # Use of this source code is governed by a BSD-style license that can be |
| 6 | # found in the LICENSE file. |
| 7 | |
| 8 | # This tool updates the OSS-Fuzz corpus using Google Cloud's 'gsutil' tool. |
| 9 | |
| 10 | # You will need to be given access to the Google Storage fuzzer repo (at |
| 11 | # gs://skia-fuzzer/oss-fuzz/) by the Skia Infra team. |
| 12 | |
| 13 | # You will also need to set up credentials for gsutil on your machine by running: |
| 14 | # gcloud auth login |
| 15 | |
| 16 | import os |
| 17 | import subprocess |
| 18 | import tempfile |
| 19 | import zipfile |
| 20 | |
| 21 | # Locate this script in the file system. |
| 22 | startDir = os.path.dirname(os.path.abspath(__file__)) |
| 23 | fileNum = 1 |
| 24 | |
| 25 | # Prepare two scratch zip files, one for the input data as-is and another with 256-byte padding. |
| 26 | with tempfile.NamedTemporaryFile(suffix='primary.zip', delete=False, mode='w') as pathToPrimaryZip: |
| 27 | with tempfile.NamedTemporaryFile(suffix='pad.zip', delete=False, mode='w') as pathToPaddedZip: |
| 28 | with zipfile.ZipFile(pathToPrimaryZip.name, 'w', zipfile.ZIP_DEFLATED) as primaryArchive: |
| 29 | with zipfile.ZipFile(pathToPaddedZip.name, 'w', zipfile.ZIP_DEFLATED) as paddedArchive: |
| 30 | # Iterate over every file in this directory and use it to assemble our corpus. |
| 31 | for root, dirs, files in os.walk(startDir): |
| 32 | for file in files: |
| 33 | # Exclude hidden/py/txt files since they aren't useful fuzzer inputs. |
| 34 | if (not file.startswith('.') |
| 35 | and not file.endswith('.py') |
| 36 | and not file.endswith('.txt')): |
| 37 | # Prepend a number to each output filename to guarantee uniqueness. |
| 38 | pathInZip = '%d_%s' % (fileNum, file) |
| 39 | fileNum += 1 |
| 40 | with open('%s/%s' % (root, file), 'r') as skslFile: |
| 41 | # Read the SkSL text as input. |
| 42 | inputSkSL = skslFile.read() |
| 43 | # In the primary archive, write the input SkSL as-is. |
| 44 | primaryArchive.writestr(pathInZip, inputSkSL) |
| 45 | # In the padded archive, write the input SkSL with 256 bonus bytes. |
| 46 | paddedSkSL = inputSkSL + ("/" * 256) |
| 47 | paddedArchive.writestr(pathInZip, paddedSkSL) |
| 48 | |
| 49 | try: |
| 50 | # Upload both zip files to cloud storage. |
| 51 | output = subprocess.check_output( |
| 52 | ['gsutil', 'cp', pathToPrimaryZip.name, |
| 53 | 'gs://skia-fuzzer/oss-fuzz/sksl_seed_corpus.zip'], |
| 54 | stderr=subprocess.STDOUT) |
| 55 | |
| 56 | output = subprocess.check_output( |
| 57 | ['gsutil', 'cp', pathToPaddedZip.name, |
| 58 | 'gs://skia-fuzzer/oss-fuzz/sksl_with_256_padding_seed_corpus.zip'], |
| 59 | stderr=subprocess.STDOUT) |
| 60 | |
| 61 | # Make the uploaded files world-readable. |
| 62 | output = subprocess.check_output( |
| 63 | ['gsutil', 'acl', 'ch', '-u', 'AllUsers:R', |
| 64 | 'gs://skia-fuzzer/oss-fuzz/sksl_seed_corpus.zip'], |
| 65 | stderr=subprocess.STDOUT) |
| 66 | |
| 67 | output = subprocess.check_output( |
| 68 | ['gsutil', 'acl', 'ch', '-u', 'AllUsers:R', |
| 69 | 'gs://skia-fuzzer/oss-fuzz/sksl_with_256_padding_seed_corpus.zip'], |
| 70 | stderr=subprocess.STDOUT) |
| 71 | |
| 72 | except subprocess.CalledProcessError as err: |
| 73 | # Report the error. |
| 74 | print("### Unable to upload fuzzer corpus to Google Cloud:") |
| 75 | print(" " + "\n ".join(err.output.splitlines())) |
| 76 | print("\nPlease read the notes at the top of update_fuzzer.py for next steps.\n") |
| 77 | sys.exit(err.returncode) |