diff options
author | Ryan Harrison <rharrison@chromium.org> | 2018-02-15 17:47:09 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-02-15 17:47:09 +0000 |
commit | 625e6fec9ddd1d023116f7bd22d2192ef9bc49c8 (patch) | |
tree | a6daac631762d837dba517b7a5b60df9a58ee3c2 | |
parent | 46f79aaad8330857e58cfd3928fdf91678112ae0 (diff) | |
download | pdfium-625e6fec9ddd1d023116f7bd22d2192ef9bc49c8.tar.xz |
Correctly seek when header size is larger then expectedchromium/3349
BUG=chromium:811733
Change-Id: Idce50b8ea4ca06fc77d5b3931557cd1d6fe48bd5
Reviewed-on: https://pdfium-review.googlesource.com/26710
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
-rw-r--r-- | core/fxcodec/bmp/cfx_bmpdecompressor.cpp | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp index d8f2b8d70b..0391258330 100644 --- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp +++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp @@ -20,6 +20,11 @@ namespace { const size_t kBmpCoreHeaderSize = 12; const size_t kBmpInfoHeaderSize = 40; +static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, + "BmpCoreHeader has wrong size"); +static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, + "BmpInfoHeader has wrong size"); + uint8_t HalfRoundUp(uint8_t value) { uint16_t value16 = value; return static_cast<uint8_t>((value16 + 1) / 2); @@ -97,16 +102,12 @@ int32_t CFX_BmpDecompressor::ReadHeader() { img_ifh_size_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_)); pal_type_ = 0; - static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, - "BmpCoreHeader has wrong size"); - static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, - "BmpInfoHeader has wrong size"); switch (img_ifh_size_) { case kBmpCoreHeaderSize: { pal_type_ = 1; BmpCoreHeader bmp_core_header; if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_core_header), - img_ifh_size_)) { + sizeof(BmpCoreHeader))) { return 2; } @@ -122,7 +123,7 @@ int32_t CFX_BmpDecompressor::ReadHeader() { case kBmpInfoHeaderSize: { BmpInfoHeader bmp_info_header; if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header), - img_ifh_size_)) { + sizeof(BmpInfoHeader))) { return 2; } @@ -143,44 +144,57 @@ int32_t CFX_BmpDecompressor::ReadHeader() { SetHeight(signed_height); } break; default: { - if (img_ifh_size_ > - std::min(kBmpInfoHeaderSize, - static_cast<size_t>(sizeof(BmpInfoHeader)))) { - BmpInfoHeader bmp_info_header; - if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header), - img_ifh_size_)) { - return 2; - } + if (img_ifh_size_ <= sizeof(BmpInfoHeader)) { + Error(); + NOTREACHED(); + } - uint16_t biPlanes; - width_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth)); - int32_t signed_height = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight)); - bit_counts_ = FXWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount)); - compress_flag_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression)); - color_used_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed)); - biPlanes = FXWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes)); - dpi_x_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)); - dpi_y_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)); - SetHeight(signed_height); - if (compress_flag_ == BMP_RGB && biPlanes == 1 && color_used_ == 0) - break; + FX_SAFE_SIZE_T new_pos = input_buffer_->GetPosition(); + BmpInfoHeader bmp_info_header; + if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header), + sizeof(bmp_info_header))) { + return 2; + } + + new_pos += img_ifh_size_; + if (!new_pos.IsValid()) { + Error(); + NOTREACHED(); + } + + if (!input_buffer_->Seek(new_pos.ValueOrDie())) + return 2; + + uint16_t biPlanes; + width_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth)); + int32_t signed_height = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight)); + bit_counts_ = FXWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount)); + compress_flag_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression)); + color_used_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed)); + biPlanes = FXWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes)); + dpi_x_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)); + dpi_y_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)); + SetHeight(signed_height); + if (compress_flag_ != BMP_RGB || biPlanes != 1 || color_used_ != 0) { + Error(); + NOTREACHED(); } - Error(); - NOTREACHED(); } } + if (width_ > BMP_MAX_WIDTH || compress_flag_ > BMP_BITFIELDS) { Error(); NOTREACHED(); } + switch (bit_counts_) { case 1: case 4: |