1
1
/*
2
- LodePNG version 20191219
2
+ LodePNG version 20200112
3
3
4
- Copyright (c) 2005-2019 Lode Vandevenne
4
+ Copyright (c) 2005-2020 Lode Vandevenne
5
5
6
6
This software is provided 'as-is', without any express or implied
7
7
warranty. 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
44
44
#pragma warning( disable : 4996 ) /* VS does not like fopen, but fopen_s is not standard C so unusable here*/
45
45
#endif /* _MSC_VER */
46
46
47
- const char * LODEPNG_VERSION_STRING = " 20191219 " ;
47
+ const char * LODEPNG_VERSION_STRING = " 20200112 " ;
48
48
49
49
/*
50
50
This 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) {
135
135
#define LODEPNG_MIN (a, b ) (((a) < (b)) ? (a) : (b))
136
136
#define LODEPNG_ABS (x ) ((x) < 0 ? -(x) : (x))
137
137
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)*/
138
146
139
147
#ifdef LODEPNG_COMPILE_DECODER
140
148
/* 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) {
144
152
return (a != 0 && *result / a != b);
145
153
}
146
154
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
-
154
155
#ifdef LODEPNG_COMPILE_ZLIB
155
156
/* Safely check if a + b > c, even if overflow could happen. */
156
157
static int lodepng_gtofl (size_t a, size_t b, size_t c) {
@@ -2515,50 +2516,61 @@ void lodepng_chunk_generate_crc(unsigned char* chunk) {
2515
2516
lodepng_set32bitInt (chunk + 8 + length, CRC);
2516
2517
}
2517
2518
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*/
2519
2521
if (chunk[0 ] == 0x89 && chunk[1 ] == 0x50 && chunk[2 ] == 0x4e && chunk[3 ] == 0x47
2520
2522
&& chunk[4 ] == 0x0d && chunk[5 ] == 0x0a && chunk[6 ] == 0x1a && chunk[7 ] == 0x0a ) {
2521
2523
/* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2522
2524
return chunk + 8 ;
2523
2525
} 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;
2526
2532
}
2527
2533
}
2528
2534
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*/
2530
2537
if (chunk[0 ] == 0x89 && chunk[1 ] == 0x50 && chunk[2 ] == 0x4e && chunk[3 ] == 0x47
2531
2538
&& chunk[4 ] == 0x0d && chunk[5 ] == 0x0a && chunk[6 ] == 0x1a && chunk[7 ] == 0x0a ) {
2532
2539
/* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2533
2540
return chunk + 8 ;
2534
2541
} 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;
2537
2548
}
2538
2549
}
2539
2550
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 ]) {
2541
2552
for (;;) {
2542
- if (chunk + 12 >= end) return 0 ;
2553
+ if (chunk >= end || end - chunk < 12 ) return 0 ; /* past file end: chunk + 12 > end */
2543
2554
if (lodepng_chunk_type_equals (chunk, type)) return chunk;
2544
- chunk = lodepng_chunk_next (chunk);
2555
+ chunk = lodepng_chunk_next (chunk, end );
2545
2556
}
2546
2557
}
2547
2558
2548
2559
const unsigned char * lodepng_chunk_find_const (const unsigned char * chunk, const unsigned char * end, const char type[5 ]) {
2549
2560
for (;;) {
2550
- if (chunk + 12 >= end) return 0 ;
2561
+ if (chunk >= end || end - chunk < 12 ) return 0 ; /* past file end: chunk + 12 > end */
2551
2562
if (lodepng_chunk_type_equals (chunk, type)) return chunk;
2552
- chunk = lodepng_chunk_next_const (chunk);
2563
+ chunk = lodepng_chunk_next_const (chunk, end );
2553
2564
}
2554
2565
}
2555
2566
2556
2567
unsigned lodepng_chunk_append (unsigned char ** out, size_t * outlength, const unsigned char * chunk) {
2557
2568
unsigned i;
2558
- unsigned total_chunk_length = lodepng_chunk_length (chunk) + 12 ;
2569
+ size_t total_chunk_length, new_length ;
2559
2570
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 ;
2562
2574
2563
2575
new_buffer = (unsigned char *)lodepng_realloc (*out, new_length);
2564
2576
if (!new_buffer) return 83 ; /* alloc fail*/
@@ -2575,8 +2587,9 @@ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned l
2575
2587
const char * type, const unsigned char * data) {
2576
2588
unsigned i;
2577
2589
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 ;
2580
2593
new_buffer = (unsigned char *)lodepng_realloc (*out, new_length);
2581
2594
if (!new_buffer) return 83 ; /* alloc fail*/
2582
2595
(*out) = new_buffer;
@@ -4868,7 +4881,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
4868
4881
if (lodepng_chunk_check_crc (chunk)) CERROR_BREAK (state->error , 57 ); /* invalid CRC*/
4869
4882
}
4870
4883
4871
- if (!IEND) chunk = lodepng_chunk_next_const (chunk);
4884
+ if (!IEND) chunk = lodepng_chunk_next_const (chunk, in + insize );
4872
4885
}
4873
4886
4874
4887
if (state->info_png .color .colortype == LCT_PALETTE
@@ -5750,7 +5763,7 @@ static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t data
5750
5763
while ((size_t )(inchunk - data) < datasize) {
5751
5764
CERROR_TRY_RETURN (lodepng_chunk_append (&out->data , &out->size , inchunk));
5752
5765
out->allocsize = out->size ; /* fix the allocsize again*/
5753
- inchunk = lodepng_chunk_next (inchunk);
5766
+ inchunk = lodepng_chunk_next (inchunk, data + datasize );
5754
5767
}
5755
5768
return 0 ;
5756
5769
}
0 commit comments