libpng error: PNG unsigned integer out of range

匿名 (未验证) 提交于 2019-12-03 02:26:02

问题:

When trying to read a PNG from memory I came across this funky error:

libpng error:: PNG unsigned integer out of range 

This error is caused by

png_read_info(png_ptr,info_ptr); 

Which uses following handler:

static void ReadDataFromBuffer(png_structp png_ptr, png_bytep outBytes,     png_size_t byteCountToRead){         PNGDataPtr dataptr=(PNGDataPtr)png_get_io_ptr(png_ptr);         png_uint_32 i;         cout<<byteCountToRead<<endl;         cout<<&outBytes<<endl;         cout<<dataptr->len<<endl;         cout<<dataptr->p<<endl;          if(byteCountToRead>dataptr->len){             png_error(png_ptr,"EOF");             return;         }          for(i=0;i<byteCountToRead;i++){              outBytes[i]=dataptr->p[i];         }         dataptr->p+=byteCountToRead;         dataptr->len-=byteCountToRead;         png_uint_32 a = png_get_uint_32(outBytes);         cout<<a<<" "<<PNG_UINT_31_MAX<<endl;  } 

Through some intensive searching I found that the error gets called by the following code in pgnrutil.c:

png_uint_32 /* PRIVATE */ png_get_uint_31(png_structp png_ptr, png_bytep buf) {     png_uint_32 i = png_get_uint_32(buf);     if (i > PNG_UINT_31_MAX)     png_error(png_ptr, "PNG unsigned integer out of range.\n");     return (i); } 

So I checked the value of png_get_uint_32(outBytes) and it was indeed higher than PNG_UINT_31_MAX, 230374511 to be exact.

How do I fix this?

Edit:

Some clarification on the PNGDataPtr:

typedef struct{     png_bytep p;     png_uint_32 len; } PNGData,*PNGDataPtr; 

When calling

png_set_read_fn(png_ptr,(png_voidp) &pngdata, ReadDataFromBuffer); 

pngdata represents a PNGData object, which has a pointer to my databuffer which contains the entire PNG in memory, and len contains the size of the entire PNG, which is between 40 and 80KB

Edit: Here's a link to a png I get when I use fwrite to save the received databuffer: https://www.dropbox.com/s/m5enp9jljglhs5c/test.png

回答1:

Previously I wrote: You've probably got your endian condition mixed up...

EDIT:
You are reading the PNG signature when you should have skipped past the first 8 bytes. Your report has a typo: the number is actually 2303741511 (you omitted a "1" from your question) which is the byte string "\211 P N G"

A workaround for this problem in your code is to use

png_set_sig_bytes(png_ptr,0) 

to inform libpng that your data pointer is pointing to the beginning of the 8-byte signature and the reader needs to skip them.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!