Merge pull request #2583 from wiredfool/decompression_bomb_error

Decompression bomb error
This commit is contained in:
wiredfool 2017-12-20 20:31:38 +00:00 committed by GitHub
commit 97ee3dd12b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 6 deletions

View File

@ -36,6 +36,8 @@ logger = logging.getLogger(__name__)
class DecompressionBombWarning(RuntimeWarning): class DecompressionBombWarning(RuntimeWarning):
pass pass
class DecompressionBombError(Exception):
pass
class _imaging_not_installed(object): class _imaging_not_installed(object):
# module placeholder # module placeholder
@ -2493,6 +2495,12 @@ def _decompression_bomb_check(size):
pixels = size[0] * size[1] pixels = size[0] * size[1]
if pixels > 2 * MAX_IMAGE_PIXELS:
raise DecompressionBombError(
"Image size (%d pixels) exceeds limit of %d pixels, "
"could be decompression bomb DOS attack." %
(pixels, 2* MAX_IMAGE_PIXELS))
if pixels > MAX_IMAGE_PIXELS: if pixels > MAX_IMAGE_PIXELS:
warnings.warn( warnings.warn(
"Image size (%d pixels) exceeds limit of %d pixels, " "Image size (%d pixels) exceeds limit of %d pixels, "

View File

@ -29,20 +29,26 @@ class TestDecompressionBomb(PillowTestCase):
Image.open(TEST_FILE) Image.open(TEST_FILE)
def test_warning(self): def test_warning(self):
# Arrange # Set limit to trigger warning on the test file
# Set limit to a low, easily testable value Image.MAX_IMAGE_PIXELS = 128 * 128 -1
Image.MAX_IMAGE_PIXELS = 10 self.assertEqual(Image.MAX_IMAGE_PIXELS, 128 * 128 - 1)
self.assertEqual(Image.MAX_IMAGE_PIXELS, 10)
# Act / Assert
self.assert_warning(Image.DecompressionBombWarning, self.assert_warning(Image.DecompressionBombWarning,
Image.open, TEST_FILE) Image.open, TEST_FILE)
def test_exception(self):
# Set limit to trigger exception on the test file
Image.MAX_IMAGE_PIXELS = 64 * 128 -1
self.assertEqual(Image.MAX_IMAGE_PIXELS, 64 * 128 - 1)
self.assertRaises(Image.DecompressionBombError,
lambda: Image.open(TEST_FILE))
class TestDecompressionCrop(PillowTestCase): class TestDecompressionCrop(PillowTestCase):
def setUp(self): def setUp(self):
self.src = hopper() self.src = hopper()
Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width * 4 - 1
def tearDown(self): def tearDown(self):
Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT
@ -54,5 +60,6 @@ class TestDecompressionCrop(PillowTestCase):
self.assert_warning(Image.DecompressionBombWarning, self.assert_warning(Image.DecompressionBombWarning,
self.src.crop, box) self.src.crop, box)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()