summaryrefslogtreecommitdiff
path: root/core/fxcodec/lbmp
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-06-19 16:11:19 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-06-20 13:45:35 +0000
commitd5a13afe9265463a497db40d8c66a8a736a86bc2 (patch)
treed4d1471deadd18d7611c8fd9b678cbfdb1f8d27b /core/fxcodec/lbmp
parent3962d80bde19074227c34f4615b0446f4975a098 (diff)
downloadpdfium-d5a13afe9265463a497db40d8c66a8a736a86bc2.tar.xz
Fix signedness of height in BMP decoder
Change-Id: I8a17739538a9ecd63d713007550177579c0b72f0 Reviewed-on: https://pdfium-review.googlesource.com/6731 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fxcodec/lbmp')
-rw-r--r--core/fxcodec/lbmp/fx_bmp.cpp49
-rw-r--r--core/fxcodec/lbmp/fx_bmp.h1
2 files changed, 41 insertions, 9 deletions
diff --git a/core/fxcodec/lbmp/fx_bmp.cpp b/core/fxcodec/lbmp/fx_bmp.cpp
index 62ae681b2a..a4b97efbac 100644
--- a/core/fxcodec/lbmp/fx_bmp.cpp
+++ b/core/fxcodec/lbmp/fx_bmp.cpp
@@ -43,6 +43,7 @@ BMPDecompressor::BMPDecompressor()
out_row_bytes(0),
bitCounts(0),
color_used(0),
+ imgTB_flag(false),
pal_num(0),
pal_type(0),
pal_ptr(nullptr),
@@ -125,6 +126,7 @@ int32_t BMPDecompressor::ReadHeader() {
bitCounts = GetWord_LSBFirst(
reinterpret_cast<uint8_t*>(&bmp_core_header_ptr->bcBitCount));
compress_flag = BMP_RGB;
+ imgTB_flag = false;
} break;
case kBmpInfoHeaderSize: {
BmpInfoHeaderPtr bmp_info_header_ptr = nullptr;
@@ -133,7 +135,8 @@ int32_t BMPDecompressor::ReadHeader() {
return 2;
}
width = GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth);
- height = GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight);
+ int32_t signed_height =
+ GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight);
bitCounts =
GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount);
compress_flag =
@@ -144,6 +147,16 @@ int32_t BMPDecompressor::ReadHeader() {
(uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter);
dpi_y = (int32_t)GetDWord_LSBFirst(
(uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter);
+ if (signed_height < 0) {
+ if (signed_height == std::numeric_limits<int>::min()) {
+ Error("Unsupported height");
+ NOTREACHED();
+ }
+ height = -signed_height;
+ imgTB_flag = true;
+ } else {
+ height = signed_height;
+ }
} break;
default: {
if (img_ifh_size >
@@ -155,7 +168,8 @@ int32_t BMPDecompressor::ReadHeader() {
}
uint16_t biPlanes;
width = GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth);
- height = GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight);
+ int32_t signed_height =
+ GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight);
bitCounts =
GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount);
compress_flag =
@@ -167,6 +181,16 @@ int32_t BMPDecompressor::ReadHeader() {
(uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter);
dpi_y = GetDWord_LSBFirst(
(uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter);
+ if (signed_height < 0) {
+ if (signed_height == std::numeric_limits<int>::min()) {
+ Error("Unsupported height");
+ NOTREACHED();
+ }
+ height = -signed_height;
+ imgTB_flag = true;
+ } else {
+ height = signed_height;
+ }
if (compress_flag == BMP_RGB && biPlanes == 1 && color_used == 0)
break;
}
@@ -402,7 +426,8 @@ int32_t BMPDecompressor::DecodeRGB() {
if (!ValidateColorIndex(byte))
return 0;
}
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
}
SaveDecodingStatus(BMP_D_STATUS_TAIL);
return 1;
@@ -430,7 +455,8 @@ int32_t BMPDecompressor::DecodeRLE8() {
Error("The Bmp File Is Corrupt");
NOTREACHED();
}
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
col_num = 0;
std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
SaveDecodingStatus(BMP_D_STATUS_DATA);
@@ -438,7 +464,8 @@ int32_t BMPDecompressor::DecodeRLE8() {
}
case RLE_EOI: {
if (row_num < height) {
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
}
SaveDecodingStatus(BMP_D_STATUS_TAIL);
return 1;
@@ -457,7 +484,8 @@ int32_t BMPDecompressor::DecodeRLE8() {
}
while (row_num < bmp_row_num_next) {
std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
}
} break;
default: {
@@ -528,7 +556,8 @@ int32_t BMPDecompressor::DecodeRLE4() {
Error("The Bmp File Is Corrupt");
NOTREACHED();
}
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
col_num = 0;
std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
SaveDecodingStatus(BMP_D_STATUS_DATA);
@@ -536,7 +565,8 @@ int32_t BMPDecompressor::DecodeRLE4() {
}
case RLE_EOI: {
if (row_num < height) {
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
}
SaveDecodingStatus(BMP_D_STATUS_TAIL);
return 1;
@@ -555,7 +585,8 @@ int32_t BMPDecompressor::DecodeRLE4() {
}
while (row_num < bmp_row_num_next) {
std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
- ReadScanline(height - 1 - row_num++, out_row_buffer);
+ ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
+ out_row_buffer);
}
} break;
default: {
diff --git a/core/fxcodec/lbmp/fx_bmp.h b/core/fxcodec/lbmp/fx_bmp.h
index bf5e94fc23..e30402070b 100644
--- a/core/fxcodec/lbmp/fx_bmp.h
+++ b/core/fxcodec/lbmp/fx_bmp.h
@@ -95,6 +95,7 @@ class BMPDecompressor {
size_t out_row_bytes;
uint16_t bitCounts;
uint32_t color_used;
+ bool imgTB_flag;
int32_t pal_num;
int32_t pal_type;
uint32_t* pal_ptr;