|
|
16aa34 |
commit 7894a6e684ce68ddff9f4f4919ab8e3911ac8040
|
|
|
16aa34 |
Author: Andrea Mazzoleni <amadvance@gmail.com>
|
|
|
16aa34 |
Date: Fri Jan 4 20:49:48 2019 +0100
|
|
|
16aa34 |
|
|
|
16aa34 |
Fix a buffer overflow caused by invalid chunks
|
|
|
16aa34 |
|
|
|
16aa34 |
diff --git a/pngex.cc b/pngex.cc
|
|
|
16aa34 |
index 55d16f5..3f5b49f 100644
|
|
|
16aa34 |
--- a/pngex.cc
|
|
|
16aa34 |
+++ b/pngex.cc
|
|
|
16aa34 |
@@ -163,6 +163,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
|
|
|
16aa34 |
switch (type) {
|
|
|
16aa34 |
case ADV_MNG_CN_MHDR :
|
|
|
16aa34 |
+ if (size < 28) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
cout << " width:" << be_uint32_read(data+0) << " height:" << be_uint32_read(data+4) << " frequency:" << be_uint32_read(data+8);
|
|
|
16aa34 |
cout << " simplicity:" << be_uint32_read(data+24);
|
|
|
16aa34 |
cout << "(bit";
|
|
|
16aa34 |
@@ -174,6 +178,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
cout << ")";
|
|
|
16aa34 |
break;
|
|
|
16aa34 |
case ADV_MNG_CN_DHDR :
|
|
|
16aa34 |
+ if (size < 4) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
cout << " id:" << be_uint16_read(data+0);
|
|
|
16aa34 |
switch (data[2]) {
|
|
|
16aa34 |
case 0 : cout << " img:unspecified"; break;
|
|
|
16aa34 |
@@ -243,6 +251,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
}
|
|
|
16aa34 |
break;
|
|
|
16aa34 |
case ADV_MNG_CN_DEFI :
|
|
|
16aa34 |
+ if (size < 2) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
cout << " id:" << be_uint16_read(data+0);
|
|
|
16aa34 |
if (size >= 3) {
|
|
|
16aa34 |
switch (data[2]) {
|
|
|
16aa34 |
@@ -266,6 +278,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
}
|
|
|
16aa34 |
break;
|
|
|
16aa34 |
case ADV_MNG_CN_MOVE :
|
|
|
16aa34 |
+ if (size < 13) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
cout << " id_from:" << be_uint16_read(data+0) << " id_to:" << be_uint16_read(data+2);
|
|
|
16aa34 |
switch (data[4]) {
|
|
|
16aa34 |
case 0 : cout << " type:replace"; break;
|
|
|
16aa34 |
@@ -275,6 +291,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
cout << " x:" << (int)be_uint32_read(data + 5) << " y:" << (int)be_uint32_read(data + 9);
|
|
|
16aa34 |
break;
|
|
|
16aa34 |
case ADV_MNG_CN_PPLT :
|
|
|
16aa34 |
+ if (size < 1) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
switch (data[0]) {
|
|
|
16aa34 |
case 0 : cout << " type:replacement_rgb"; break;
|
|
|
16aa34 |
case 1 : cout << " type:delta_rgb"; break;
|
|
|
16aa34 |
@@ -285,7 +305,7 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
default : cout << " type:?"; break;
|
|
|
16aa34 |
}
|
|
|
16aa34 |
i = 1;
|
|
|
16aa34 |
- while (i
|
|
|
16aa34 |
+ while (i + 1 < size) {
|
|
|
16aa34 |
unsigned ssize;
|
|
|
16aa34 |
cout << " " << (unsigned)data[i] << ":" << (unsigned)data[i+1];
|
|
|
16aa34 |
if (data[0] == 0 || data[1] == 1)
|
|
|
16aa34 |
@@ -298,6 +318,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
|
|
16aa34 |
}
|
|
|
16aa34 |
break;
|
|
|
16aa34 |
case ADV_PNG_CN_IHDR :
|
|
|
16aa34 |
+ if (size < 13) {
|
|
|
16aa34 |
+ cout << " invalid chunk size";
|
|
|
16aa34 |
+ break;
|
|
|
16aa34 |
+ }
|
|
|
16aa34 |
cout << " width:" << be_uint32_read(data) << " height:" << be_uint32_read(data + 4);
|
|
|
16aa34 |
cout << " depth:" << (unsigned)data[8];
|
|
|
16aa34 |
cout << " color_type:" << (unsigned)data[9];
|