summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLode <lvandeve@gmail.com>2014-11-18 23:37:42 +0100
committerLode <lvandeve@gmail.com>2014-11-18 23:37:42 +0100
commitba274d5b98d1582bba47a1591c9e02b1ff421352 (patch)
tree63a82d5e567b17bc140d67119ce8fd417651b972
parentc7353101cea671073ba1a9f4ca9f4cf7e8dbc944 (diff)
protect against invalid chunk lengths in some tools
-rw-r--r--example_png_info.cpp4
-rw-r--r--lodepng.h6
-rw-r--r--lodepng_util.cpp5
-rw-r--r--pngdetail.cpp7
4 files changed, 19 insertions, 3 deletions
diff --git a/example_png_info.cpp b/example_png_info.cpp
index 86f664a..e7f78a2 100644
--- a/example_png_info.cpp
+++ b/example_png_info.cpp
@@ -232,6 +232,10 @@ void displayFilterTypes(const std::vector<unsigned char>& buffer)
{
const unsigned char* cdata = lodepng_chunk_data_const(chunk);
unsigned clength = lodepng_chunk_length(chunk);
+ if(chunk + clength >= end) {
+ std::cout << "invalid chunk length" << std::endl;
+ return;
+ }
for(unsigned i = 0; i < clength; i++)
{
diff --git a/lodepng.h b/lodepng.h
index ef2c820..8e2e038 100644
--- a/lodepng.h
+++ b/lodepng.h
@@ -677,7 +677,11 @@ Third byte: must be uppercase
Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
*/
-/*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/
+/*
+Gets the length of the data of the chunk. Total chunk length has 12 bytes more.
+There must be at least 4 bytes to read from. If the result value is too large,
+it may be corrupt data.
+*/
unsigned lodepng_chunk_length(const unsigned char* chunk);
/*puts the 4-byte type in null terminated string*/
diff --git a/lodepng_util.cpp b/lodepng_util.cpp
index 3784b6e..ed054f0 100644
--- a/lodepng_util.cpp
+++ b/lodepng_util.cpp
@@ -51,8 +51,10 @@ unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& size
lodepng_chunk_type(type, chunk);
if(std::string(type).size() != 4) return 1;
+ unsigned length = lodepng_chunk_length(chunk);
+ if(chunk + length >= end) return 1;
names.push_back(type);
- sizes.push_back(lodepng_chunk_length(chunk));
+ sizes.push_back(length);
chunk = lodepng_chunk_next_const(chunk);
}
@@ -180,6 +182,7 @@ unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filt
{
const unsigned char* cdata = lodepng_chunk_data_const(chunk);
unsigned clength = lodepng_chunk_length(chunk);
+ if(chunk + clength >= end) return 1; // corrupt chunk length
for(unsigned i = 0; i < clength; i++)
{
diff --git a/pngdetail.cpp b/pngdetail.cpp
index b876f71..98f03d2 100644
--- a/pngdetail.cpp
+++ b/pngdetail.cpp
@@ -304,7 +304,12 @@ Show the filtertypes of each scanline in this PNG image.
void displayFilterTypes(const std::vector<unsigned char>& buffer)
{
std::vector<std::vector<unsigned char> > types;
- lodepng::getFilterTypesInterlaced(types, buffer);
+ unsigned error = lodepng::getFilterTypesInterlaced(types, buffer);
+ if(error)
+ {
+ std::cout << "Error getting filter types" << std::endl;
+ return;
+ }
if(types.size() == 7)
{