From ba274d5b98d1582bba47a1591c9e02b1ff421352 Mon Sep 17 00:00:00 2001 From: Lode Date: Tue, 18 Nov 2014 23:37:42 +0100 Subject: protect against invalid chunk lengths in some tools --- example_png_info.cpp | 4 ++++ lodepng.h | 6 +++++- lodepng_util.cpp | 5 ++++- pngdetail.cpp | 7 ++++++- 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& 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& names, std::vector& 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 >& 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& buffer) { std::vector > 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) { -- cgit v1.2.3