scott1028 / pyfpdf

Automatically exported from code.google.com/p/pyfpdf
GNU Lesser General Public License v3.0
0 stars 0 forks source link

_freadint reads only a short instead of long --> Problem with PNG-Images with chunksizes > 0xFFFF #44

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
--> Try to import a PNG-image with a chunk > 0xFFFF bytes. In my case the chunk 
size was 0x10000 (image converted to PNG using PIL).

What do you see instead?
--> _parsepng assumes a wrong chunk size and reads crap from the PNG-file. This 
leads finally to an exception.

What version of the product are you using? On what operating system?
--> FPDF 1.7, Python 2.6.6

Please provide any additional information below.

Is there a reason, why _freadint reads only the lower halfword and drops the 
upper half of the integer?
I simply changed it to read a unsigned doubleword and then importing my PNGs 
worked.

Changed: return struct.unpack('>HH',f.read(4))[1]
To:      return struct.unpack('>L', f.read(4))[0]

Original issue reported on code.google.com by mar...@googlemail.com on 30 Jan 2013 at 12:29

GoogleCodeExporter commented 9 years ago
Does this affect any other part of PyFPDF?

Could you run the test and check that everything works as expected before 
applying your patch?

Thanks !

Original comment by reingart@gmail.com on 30 Jan 2013 at 3:50

GoogleCodeExporter commented 9 years ago
Mariano,

Seems to be this function _freadint(self, f) used 3 times in PNG reading part 
(fpdf.py ~1647..1764). So it doesn't affect any other parts.

btw, i would like to change this part to something more py3 compatible.

Original comment by romiq...@gmail.com on 1 Feb 2013 at 6:35

GoogleCodeExporter commented 9 years ago
go ahead ;-)

Original comment by reingart@gmail.com on 1 Feb 2013 at 6:37

GoogleCodeExporter commented 9 years ago
Fixed in tip.

NB: http://www.libpng.org/pub/png/spec/1.2/
w=self._freadint(f)
h=self._freadint(f)
Width and height give the image dimensions in pixels. They are 4-byte integers. 
Zero is an invalid value. The maximum for each is 2^31-1 in order to 
accommodate languages that have difficulty with unsigned 4-byte values. 

n=self._freadint(f) # chunk length
A 4-byte unsigned integer giving the number of bytes in the chunk's data field. 
The length counts only the data field, not itself, the chunk type code, or the 
CRC. Zero is a valid length. Although encoders and decoders should treat the 
length as unsigned, its value must not exceed 2^31-1 bytes. 

"I" should works, but maybe "i" specificator (signed) is better .

Original comment by romiq...@gmail.com on 4 Feb 2013 at 8:24