diff options
author | Nicolas Pena <npm@chromium.org> | 2017-06-19 16:11:19 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-06-20 13:45:35 +0000 |
commit | d5a13afe9265463a497db40d8c66a8a736a86bc2 (patch) | |
tree | d4d1471deadd18d7611c8fd9b678cbfdb1f8d27b /core/fxcodec/lbmp | |
parent | 3962d80bde19074227c34f4615b0446f4975a098 (diff) | |
download | pdfium-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.cpp | 49 | ||||
-rw-r--r-- | core/fxcodec/lbmp/fx_bmp.h | 1 |
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; |