diff --git a/PIL/Image.py b/PIL/Image.py index c22ab3955..9910d2162 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -1042,6 +1042,20 @@ class Image(object): if box is None: return self.copy() + return self._new(self._crop(self.im, box)) + + def _crop(self, im, box): + """ + Returns a rectangular region from the core image object im. + + This is equivalent to calling im.crop((x0, y0, x1, y1)), but + includes additional sanity checks. + + :param im: a core image object + :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. + :returns: A core image object. + """ + x0, y0, x1, y1 = map(int, map(round, box)) if x0 == 0 and y0 == 0 and (x1, y1) == self.size: @@ -1052,8 +1066,10 @@ class Image(object): if y1 < y0: y1 = y0 - return self._new(self.im.crop((x0, y0, x1, y1))) + _decompression_bomb_check((x1, y1)) + return im.crop((x0, y0, x1, y1)) + def draft(self, mode, size): """ Configures the image file loader so it returns a version of the diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py index 675005d3f..5598fd9c8 100644 --- a/Tests/test_decompression_bomb.py +++ b/Tests/test_decompression_bomb.py @@ -1,4 +1,4 @@ -from helper import unittest, PillowTestCase +from helper import unittest, PillowTestCase, hopper from PIL import Image @@ -35,9 +35,24 @@ class TestDecompressionBomb(PillowTestCase): self.assertEqual(Image.MAX_IMAGE_PIXELS, 10) # Act / Assert - self.assert_warning( - Image.DecompressionBombWarning, - lambda: Image.open(TEST_FILE)) + self.assert_warning(Image.DecompressionBombWarning, + lambda: Image.open(TEST_FILE)) + +class TestDecompressionCrop(PillowTestCase): + + def setUp(self): + self.src = hopper() + Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width + + def tearDown(self): + Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT + + def testEnlargeCrop(self): + # Crops can extend the extents, therefore we should have the + # same decompression bomb warnings on them. + box = (0, 0, self.src.width * 2, self.src.height * 2) + self.assert_warning(Image.DecompressionBombWarning, + lambda: self.src.crop(box)) if __name__ == '__main__': unittest.main()