11/*
2- LodePNG version 20191219
2+ LodePNG version 20200112
33
4- Copyright (c) 2005-2019 Lode Vandevenne
4+ Copyright (c) 2005-2020 Lode Vandevenne
55
66This software is provided 'as-is', without any express or implied
77warranty. In no event will the authors be held liable for any damages
@@ -44,7 +44,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
4444#pragma warning( disable : 4996 ) /* VS does not like fopen, but fopen_s is not standard C so unusable here*/
4545#endif /* _MSC_VER */
4646
47- const char * LODEPNG_VERSION_STRING = " 20191219 " ;
47+ const char * LODEPNG_VERSION_STRING = " 20200112 " ;
4848
4949/*
5050This source file is built up in the following large parts. The code sections
@@ -135,6 +135,14 @@ static size_t lodepng_strlen(const char* a) {
135135#define LODEPNG_MIN (a, b ) (((a) < (b)) ? (a) : (b))
136136#define LODEPNG_ABS (x ) ((x) < 0 ? -(x) : (x))
137137
138+ #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)
139+ /* Safely check if adding two integers will overflow (no undefined
140+ behavior, compiler removing the code, etc...) and output result. */
141+ static int lodepng_addofl (size_t a, size_t b, size_t * result) {
142+ *result = a + b; /* Unsigned addition is well defined and safe in C90 */
143+ return *result < a;
144+ }
145+ #endif /* defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)*/
138146
139147#ifdef LODEPNG_COMPILE_DECODER
140148/* Safely check if multiplying two integers will overflow (no undefined
@@ -144,13 +152,6 @@ static int lodepng_mulofl(size_t a, size_t b, size_t* result) {
144152 return (a != 0 && *result / a != b);
145153}
146154
147- /* Safely check if adding two integers will overflow (no undefined
148- behavior, compiler removing the code, etc...) and output result. */
149- static int lodepng_addofl (size_t a, size_t b, size_t * result) {
150- *result = a + b; /* Unsigned addition is well defined and safe in C90 */
151- return *result < a;
152- }
153-
154155#ifdef LODEPNG_COMPILE_ZLIB
155156/* Safely check if a + b > c, even if overflow could happen. */
156157static int lodepng_gtofl (size_t a, size_t b, size_t c) {
@@ -2515,50 +2516,61 @@ void lodepng_chunk_generate_crc(unsigned char* chunk) {
25152516 lodepng_set32bitInt (chunk + 8 + length, CRC);
25162517}
25172518
2518- unsigned char * lodepng_chunk_next (unsigned char * chunk) {
2519+ unsigned char * lodepng_chunk_next (unsigned char * chunk, unsigned char * end) {
2520+ if (chunk >= end || end - chunk < 12 ) return end; /* too small to contain a chunk*/
25192521 if (chunk[0 ] == 0x89 && chunk[1 ] == 0x50 && chunk[2 ] == 0x4e && chunk[3 ] == 0x47
25202522 && chunk[4 ] == 0x0d && chunk[5 ] == 0x0a && chunk[6 ] == 0x1a && chunk[7 ] == 0x0a ) {
25212523 /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
25222524 return chunk + 8 ;
25232525 } else {
2524- unsigned total_chunk_length = lodepng_chunk_length (chunk) + 12 ;
2525- return chunk + total_chunk_length;
2526+ size_t total_chunk_length;
2527+ unsigned char * result;
2528+ if (lodepng_addofl (lodepng_chunk_length (chunk), 12 , &total_chunk_length)) return end;
2529+ result = chunk + total_chunk_length;
2530+ if (result < chunk) return end; /* pointer overflow*/
2531+ return result;
25262532 }
25272533}
25282534
2529- const unsigned char * lodepng_chunk_next_const (const unsigned char * chunk) {
2535+ const unsigned char * lodepng_chunk_next_const (const unsigned char * chunk, const unsigned char * end) {
2536+ if (chunk >= end || end - chunk < 12 ) return end; /* too small to contain a chunk*/
25302537 if (chunk[0 ] == 0x89 && chunk[1 ] == 0x50 && chunk[2 ] == 0x4e && chunk[3 ] == 0x47
25312538 && chunk[4 ] == 0x0d && chunk[5 ] == 0x0a && chunk[6 ] == 0x1a && chunk[7 ] == 0x0a ) {
25322539 /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
25332540 return chunk + 8 ;
25342541 } else {
2535- unsigned total_chunk_length = lodepng_chunk_length (chunk) + 12 ;
2536- return chunk + total_chunk_length;
2542+ size_t total_chunk_length;
2543+ const unsigned char * result;
2544+ if (lodepng_addofl (lodepng_chunk_length (chunk), 12 , &total_chunk_length)) return end;
2545+ result = chunk + total_chunk_length;
2546+ if (result < chunk) return end; /* pointer overflow*/
2547+ return result;
25372548 }
25382549}
25392550
2540- unsigned char * lodepng_chunk_find (unsigned char * chunk, const unsigned char * end, const char type[5 ]) {
2551+ unsigned char * lodepng_chunk_find (unsigned char * chunk, unsigned char * end, const char type[5 ]) {
25412552 for (;;) {
2542- if (chunk + 12 >= end) return 0 ;
2553+ if (chunk >= end || end - chunk < 12 ) return 0 ; /* past file end: chunk + 12 > end */
25432554 if (lodepng_chunk_type_equals (chunk, type)) return chunk;
2544- chunk = lodepng_chunk_next (chunk);
2555+ chunk = lodepng_chunk_next (chunk, end );
25452556 }
25462557}
25472558
25482559const unsigned char * lodepng_chunk_find_const (const unsigned char * chunk, const unsigned char * end, const char type[5 ]) {
25492560 for (;;) {
2550- if (chunk + 12 >= end) return 0 ;
2561+ if (chunk >= end || end - chunk < 12 ) return 0 ; /* past file end: chunk + 12 > end */
25512562 if (lodepng_chunk_type_equals (chunk, type)) return chunk;
2552- chunk = lodepng_chunk_next_const (chunk);
2563+ chunk = lodepng_chunk_next_const (chunk, end );
25532564 }
25542565}
25552566
25562567unsigned lodepng_chunk_append (unsigned char ** out, size_t * outlength, const unsigned char * chunk) {
25572568 unsigned i;
2558- unsigned total_chunk_length = lodepng_chunk_length (chunk) + 12 ;
2569+ size_t total_chunk_length, new_length ;
25592570 unsigned char *chunk_start, *new_buffer;
2560- size_t new_length = (*outlength) + total_chunk_length;
2561- if (new_length < total_chunk_length || new_length < (*outlength)) return 77 ; /* integer overflow happened*/
2571+
2572+ if (lodepng_addofl (lodepng_chunk_length (chunk), 12 , &total_chunk_length)) return 77 ;
2573+ if (lodepng_addofl (*outlength, total_chunk_length, &new_length)) return 77 ;
25622574
25632575 new_buffer = (unsigned char *)lodepng_realloc (*out, new_length);
25642576 if (!new_buffer) return 83 ; /* alloc fail*/
@@ -2575,8 +2587,9 @@ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned l
25752587 const char * type, const unsigned char * data) {
25762588 unsigned i;
25772589 unsigned char *chunk, *new_buffer;
2578- size_t new_length = (*outlength) + length + 12 ;
2579- if (new_length < length + 12 || new_length < (*outlength)) return 77 ; /* integer overflow happened*/
2590+ size_t new_length = *outlength;
2591+ if (lodepng_addofl (new_length, length, &new_length)) return 77 ;
2592+ if (lodepng_addofl (new_length, 12 , &new_length)) return 77 ;
25802593 new_buffer = (unsigned char *)lodepng_realloc (*out, new_length);
25812594 if (!new_buffer) return 83 ; /* alloc fail*/
25822595 (*out) = new_buffer;
@@ -4868,7 +4881,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
48684881 if (lodepng_chunk_check_crc (chunk)) CERROR_BREAK (state->error , 57 ); /* invalid CRC*/
48694882 }
48704883
4871- if (!IEND) chunk = lodepng_chunk_next_const (chunk);
4884+ if (!IEND) chunk = lodepng_chunk_next_const (chunk, in + insize );
48724885 }
48734886
48744887 if (state->info_png .color .colortype == LCT_PALETTE
@@ -5750,7 +5763,7 @@ static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t data
57505763 while ((size_t )(inchunk - data) < datasize) {
57515764 CERROR_TRY_RETURN (lodepng_chunk_append (&out->data , &out->size , inchunk));
57525765 out->allocsize = out->size ; /* fix the allocsize again*/
5753- inchunk = lodepng_chunk_next (inchunk);
5766+ inchunk = lodepng_chunk_next (inchunk, data + datasize );
57545767 }
57555768 return 0 ;
57565769}
0 commit comments