mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	Catch struct.errors when verifying png files, convert to SyntaxErrors, fixes #1755
This commit is contained in:
		
							parent
							
								
									fd7fa4e61d
								
							
						
					
					
						commit
						77da73c90f
					
				|  | @ -36,6 +36,7 @@ from __future__ import print_function | ||||||
| import logging | import logging | ||||||
| import re | import re | ||||||
| import zlib | import zlib | ||||||
|  | import struct | ||||||
| 
 | 
 | ||||||
| from PIL import Image, ImageFile, ImagePalette, _binary | from PIL import Image, ImageFile, ImagePalette, _binary | ||||||
| 
 | 
 | ||||||
|  | @ -106,7 +107,8 @@ class ChunkStream(object): | ||||||
| 
 | 
 | ||||||
|     def read(self): |     def read(self): | ||||||
|         "Fetch a new chunk. Returns header information." |         "Fetch a new chunk. Returns header information." | ||||||
| 
 |         cid = None | ||||||
|  |         try: | ||||||
|             if self.queue: |             if self.queue: | ||||||
|                 cid, pos, length = self.queue[-1] |                 cid, pos, length = self.queue[-1] | ||||||
|                 del self.queue[-1] |                 del self.queue[-1] | ||||||
|  | @ -116,6 +118,8 @@ class ChunkStream(object): | ||||||
|                 cid = s[4:] |                 cid = s[4:] | ||||||
|                 pos = self.fp.tell() |                 pos = self.fp.tell() | ||||||
|                 length = i32(s) |                 length = i32(s) | ||||||
|  |         except struct.error: | ||||||
|  |             SyntaxError("truncated PNG file (chunk %s)" % repr(cid)) | ||||||
|              |              | ||||||
|         if not is_cid(cid): |         if not is_cid(cid): | ||||||
|             raise SyntaxError("broken PNG file (chunk %s)" % repr(cid)) |             raise SyntaxError("broken PNG file (chunk %s)" % repr(cid)) | ||||||
|  | @ -138,11 +142,15 @@ class ChunkStream(object): | ||||||
|     def crc(self, cid, data): |     def crc(self, cid, data): | ||||||
|         "Read and verify checksum" |         "Read and verify checksum" | ||||||
| 
 | 
 | ||||||
|  |         try: | ||||||
|             crc1 = Image.core.crc32(data, Image.core.crc32(cid)) |             crc1 = Image.core.crc32(data, Image.core.crc32(cid)) | ||||||
|             crc2 = i16(self.fp.read(2)), i16(self.fp.read(2)) |             crc2 = i16(self.fp.read(2)), i16(self.fp.read(2)) | ||||||
|             if crc1 != crc2: |             if crc1 != crc2: | ||||||
|             raise SyntaxError("broken PNG file" |                 raise SyntaxError("broken PNG file (bad header checksum in %s)" | ||||||
|                               "(bad header checksum in %s)" % cid) |                                   % cid) | ||||||
|  |         except struct.error: | ||||||
|  |             raise SyntaxError("broken PNG file (incomplete checksum in %s)" | ||||||
|  |                               % cid) | ||||||
| 
 | 
 | ||||||
|     def crc_skip(self, cid, data): |     def crc_skip(self, cid, data): | ||||||
|         "Read checksum.  Used if the C module is not present" |         "Read checksum.  Used if the C module is not present" | ||||||
|  |  | ||||||
|  | @ -253,6 +253,22 @@ class TestFilePng(PillowTestCase): | ||||||
|         im.load() |         im.load() | ||||||
|         self.assertRaises(RuntimeError, im.verify) |         self.assertRaises(RuntimeError, im.verify) | ||||||
| 
 | 
 | ||||||
|  |     def test_verify_struct_error(self): | ||||||
|  |         # Check open/load/verify exception (#1755) | ||||||
|  | 
 | ||||||
|  |         # offsets to test, -10: breaks in i32() in read. | ||||||
|  |         #                  -13: breaks in crc, txt chunk. | ||||||
|  |         #                  -14: malformed chunk | ||||||
|  | 
 | ||||||
|  |         for offset in (-10, -13, -14): | ||||||
|  |             with open(TEST_PNG_FILE,'rb') as f: | ||||||
|  |                 test_file = f.read()[:offset] | ||||||
|  | 
 | ||||||
|  |             im = Image.open(BytesIO(test_file)) | ||||||
|  |             self.assertTrue(im.fp is not None) | ||||||
|  |             self.assertRaises(SyntaxError, im.verify) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     def test_roundtrip_dpi(self): |     def test_roundtrip_dpi(self): | ||||||
|         # Check dpi roundtripping |         # Check dpi roundtripping | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user