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