mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-30 23:47:27 +03:00 
			
		
		
		
	
						commit
						611a6d2330
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -88,3 +88,6 @@ Tests/images/jpeg2000 | ||||||
| Tests/images/msp | Tests/images/msp | ||||||
| Tests/images/picins | Tests/images/picins | ||||||
| Tests/images/sunraster | Tests/images/sunraster | ||||||
|  | 
 | ||||||
|  | # pyinstaller | ||||||
|  | *.spec | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								Tests/oss-fuzz/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								Tests/oss-fuzz/build.sh
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,48 @@ | ||||||
|  | #!/bin/bash -eu | ||||||
|  | # 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. | ||||||
|  | # | ||||||
|  | ################################################################################ | ||||||
|  | 
 | ||||||
|  | python3 setup.py build --build-base=/tmp/build install | ||||||
|  | 
 | ||||||
|  | # Build fuzzers in $OUT. | ||||||
|  | for fuzzer in $(find $SRC -name 'fuzz_*.py'); do | ||||||
|  |   fuzzer_basename=$(basename -s .py $fuzzer) | ||||||
|  |   fuzzer_package=${fuzzer_basename}.pkg | ||||||
|  |   pyinstaller \ | ||||||
|  |       --add-binary /usr/local/lib/libjpeg.so.9:. \ | ||||||
|  |       --add-binary /usr/local/lib/libfreetype.so.6:. \ | ||||||
|  |       --add-binary /usr/local/lib/liblcms2.so.2:. \ | ||||||
|  |       --add-binary /usr/local/lib/libopenjp2.so.7:. \ | ||||||
|  |       --add-binary /usr/local/lib/libpng16.so.16:. \ | ||||||
|  |       --add-binary /usr/local/lib/libtiff.so.5:. \ | ||||||
|  |       --add-binary /usr/local/lib/libwebp.so.7:. \ | ||||||
|  |       --add-binary /usr/local/lib/libwebpdemux.so.2:. \ | ||||||
|  |       --add-binary /usr/local/lib/libwebpmux.so.3:. \ | ||||||
|  |       --add-binary /usr/local/lib/libxcb.so.1:. \ | ||||||
|  |       --distpath $OUT --onefile --name $fuzzer_package $fuzzer | ||||||
|  | 
 | ||||||
|  |   # Create execution wrapper. | ||||||
|  |   echo "#!/bin/sh | ||||||
|  | # LLVMFuzzerTestOneInput for fuzzer detection. | ||||||
|  | this_dir=\$(dirname \"\$0\") | ||||||
|  | LD_PRELOAD=\$this_dir/sanitizer_with_fuzzer.so \ | ||||||
|  | ASAN_OPTIONS=\$ASAN_OPTIONS:symbolize=1:external_symbolizer_path=\$this_dir/llvm-symbolizer:detect_leaks=0 \ | ||||||
|  | \$this_dir/$fuzzer_package \$@" > $OUT/$fuzzer_basename | ||||||
|  |   chmod u+x $OUT/$fuzzer_basename | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | find Tests/images Tests/icc -print | zip -q $OUT/fuzz_pillow_seed_corpus.zip -@ | ||||||
|  | find Tests/fonts -print | zip -q $OUT/fuzz_font_seed_corpus.zip -@ | ||||||
							
								
								
									
										33
									
								
								Tests/oss-fuzz/build_dictionaries.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										33
									
								
								Tests/oss-fuzz/build_dictionaries.sh
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | #!/bin/bash -eu | ||||||
|  | # 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. | ||||||
|  | # | ||||||
|  | ################################################################################ | ||||||
|  | 
 | ||||||
|  | # Generate image dictionaries here for each of the fuzzers and put them in the | ||||||
|  | # $OUT directory, named for the fuzzer | ||||||
|  | 
 | ||||||
|  | git clone --depth 1 https://github.com/google/fuzzing | ||||||
|  | cat fuzzing/dictionaries/bmp.dict \ | ||||||
|  |     fuzzing/dictionaries/dds.dict \ | ||||||
|  |     fuzzing/dictionaries/gif.dict \ | ||||||
|  |     fuzzing/dictionaries/icns.dict \ | ||||||
|  |     fuzzing/dictionaries/jpeg.dict \ | ||||||
|  |     fuzzing/dictionaries/jpeg2000.dict \ | ||||||
|  |     fuzzing/dictionaries/pbm.dict \ | ||||||
|  |     fuzzing/dictionaries/png.dict \ | ||||||
|  |     fuzzing/dictionaries/psd.dict \ | ||||||
|  |     fuzzing/dictionaries/tiff.dict \ | ||||||
|  |     fuzzing/dictionaries/webp.dict \ | ||||||
|  |     > $OUT/fuzz_pillow.dict | ||||||
							
								
								
									
										40
									
								
								Tests/oss-fuzz/fuzz_font.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										40
									
								
								Tests/oss-fuzz/fuzz_font.py
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | #!/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 sys | ||||||
|  | 
 | ||||||
|  | import atheris_no_libfuzzer as atheris | ||||||
|  | import fuzzers | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def TestOneInput(data): | ||||||
|  |     try: | ||||||
|  |         fuzzers.fuzz_font(data) | ||||||
|  |     except Exception: | ||||||
|  |         # We're catching all exceptions because Pillow's exceptions are | ||||||
|  |         # directly inheriting from Exception. | ||||||
|  |         return | ||||||
|  |     return | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     fuzzers.enable_decompressionbomb_error() | ||||||
|  |     atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) | ||||||
|  |     atheris.Fuzz() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
|  | @ -14,21 +14,15 @@ | ||||||
| # See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and | ||||||
| # limitations under the License. | # limitations under the License. | ||||||
| 
 | 
 | ||||||
| import io |  | ||||||
| import sys | import sys | ||||||
| import warnings |  | ||||||
| 
 | 
 | ||||||
| import atheris_no_libfuzzer as atheris | import atheris_no_libfuzzer as atheris | ||||||
| 
 | import fuzzers | ||||||
| from PIL import Image, ImageFile, ImageFilter |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def TestOneInput(data): | def TestOneInput(data): | ||||||
|     try: |     try: | ||||||
|         with Image.open(io.BytesIO(data)) as im: |         fuzzers.fuzz_image(data) | ||||||
|             im.rotate(45) |  | ||||||
|             im.filter(ImageFilter.DETAIL) |  | ||||||
|             im.save(io.BytesIO(), "BMP") |  | ||||||
|     except Exception: |     except Exception: | ||||||
|         # We're catching all exceptions because Pillow's exceptions are |         # We're catching all exceptions because Pillow's exceptions are | ||||||
|         # directly inheriting from Exception. |         # directly inheriting from Exception. | ||||||
|  | @ -37,9 +31,7 @@ def TestOneInput(data): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     ImageFile.LOAD_TRUNCATED_IMAGES = True |     fuzzers.enable_decompressionbomb_error() | ||||||
|     warnings.filterwarnings("ignore") |  | ||||||
|     warnings.simplefilter("error", Image.DecompressionBombWarning) |  | ||||||
|     atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) |     atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) | ||||||
|     atheris.Fuzz() |     atheris.Fuzz() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								Tests/oss-fuzz/fuzzers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Tests/oss-fuzz/fuzzers.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | import io | ||||||
|  | import warnings | ||||||
|  | 
 | ||||||
|  | from PIL import Image, ImageDraw, ImageFile, ImageFilter, ImageFont | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def enable_decompressionbomb_error(): | ||||||
|  |     ImageFile.LOAD_TRUNCATED_IMAGES = True | ||||||
|  |     warnings.filterwarnings("ignore") | ||||||
|  |     warnings.simplefilter("error", Image.DecompressionBombWarning) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fuzz_image(data): | ||||||
|  |     # This will fail on some images in the corpus, as we have many | ||||||
|  |     # invalid images in the test suite. | ||||||
|  |     with Image.open(io.BytesIO(data)) as im: | ||||||
|  |         im.rotate(45) | ||||||
|  |         im.filter(ImageFilter.DETAIL) | ||||||
|  |         im.save(io.BytesIO(), "BMP") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fuzz_font(data): | ||||||
|  |     wrapper = io.BytesIO(data) | ||||||
|  |     try: | ||||||
|  |         font = ImageFont.truetype(wrapper) | ||||||
|  |     except OSError: | ||||||
|  |         # Catch pcf/pilfonts/random garbage here. They return | ||||||
|  |         # different font objects. | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     font.getsize_multiline("ABC\nAaaa") | ||||||
|  |     font.getmask("test text") | ||||||
|  |     with Image.new(mode="RGBA", size=(200, 200)) as im: | ||||||
|  |         draw = ImageDraw.Draw(im) | ||||||
|  |         draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2) | ||||||
|  |         draw.text((10, 10), "Test Text", font=font, fill="#000") | ||||||
							
								
								
									
										53
									
								
								Tests/oss-fuzz/test_fuzzers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Tests/oss-fuzz/test_fuzzers.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | ||||||
|  | import subprocess | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | import fuzzers | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | from PIL import Image | ||||||
|  | 
 | ||||||
|  | if sys.platform.startswith("win32"): | ||||||
|  |     pytest.skip("Fuzzer is linux only", allow_module_level=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.parametrize( | ||||||
|  |     "path", | ||||||
|  |     subprocess.check_output("find Tests/images -type f", shell=True).split(b"\n"), | ||||||
|  | ) | ||||||
|  | def test_fuzz_images(path): | ||||||
|  |     fuzzers.enable_decompressionbomb_error() | ||||||
|  |     try: | ||||||
|  |         with open(path, "rb") as f: | ||||||
|  |             fuzzers.fuzz_image(f.read()) | ||||||
|  |             assert True | ||||||
|  |     except ( | ||||||
|  |         OSError, | ||||||
|  |         SyntaxError, | ||||||
|  |         MemoryError, | ||||||
|  |         ValueError, | ||||||
|  |         NotImplementedError, | ||||||
|  |         OverflowError, | ||||||
|  |     ): | ||||||
|  |         # Known exceptions that are through from Pillow | ||||||
|  |         assert True | ||||||
|  |     except ( | ||||||
|  |         Image.DecompressionBombError, | ||||||
|  |         Image.DecompressionBombWarning, | ||||||
|  |         Image.UnidentifiedImageError, | ||||||
|  |     ): | ||||||
|  |         # Known Image.* exceptions | ||||||
|  |         assert True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.parametrize( | ||||||
|  |     "path", subprocess.check_output("find Tests/fonts -type f", shell=True).split(b"\n") | ||||||
|  | ) | ||||||
|  | def test_fuzz_fonts(path): | ||||||
|  |     if not path: | ||||||
|  |         return | ||||||
|  |     with open(path, "rb") as f: | ||||||
|  |         try: | ||||||
|  |             fuzzers.fuzz_font(f.read()) | ||||||
|  |         except (Image.DecompressionBombError, Image.DecompressionBombWarning): | ||||||
|  |             pass | ||||||
|  |         assert True | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user