diff --git a/Tests/oss-fuzz/fuzz_pillow.py b/Tests/oss-fuzz/fuzz_pillow.py new file mode 100644 index 000000000..894068f63 --- /dev/null +++ b/Tests/oss-fuzz/fuzz_pillow.py @@ -0,0 +1,48 @@ +#!/usr/bin/python3 + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import io +import sys +import warnings + +import atheris_no_libfuzzer as atheris + +from PIL import Image, ImageFile, ImageFilter + + +def TestOneInput(data): + try: + with Image.open(io.BytesIO(data)) as im: + im.rotate(45) + im.filter(ImageFilter.DETAIL) + im.save(io.BytesIO(), "BMP") + except Exception: + # We're catching all exceptions because Pillow's exceptions are + # directly inheriting from Exception. + return + return + + +def main(): + ImageFile.LOAD_TRUNCATED_IMAGES = True + warnings.filterwarnings("ignore") + warnings.simplefilter("error", Image.DecompressionBombWarning) + atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) + atheris.Fuzz() + + +if __name__ == "__main__": + main() diff --git a/setup.py b/setup.py index cbc2641c5..dd1772ae0 100755 --- a/setup.py +++ b/setup.py @@ -840,7 +840,9 @@ class pil_build_ext(build_ext): def debug_build(): - return hasattr(sys, "gettotalrefcount") + return hasattr(sys, "gettotalrefcount") or os.environ.get( + "LIB_FUZZING_ENGINE", None + ) files = ["src/_imaging.c"]