From 625e6fec9ddd1d023116f7bd22d2192ef9bc49c8 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Thu, 15 Feb 2018 17:47:09 +0000 Subject: Correctly seek when header size is larger then expected BUG=chromium:811733 Change-Id: Idce50b8ea4ca06fc77d5b3931557cd1d6fe48bd5 Reviewed-on: https://pdfium-review.googlesource.com/26710 Reviewed-by: Tom Sepez Reviewed-by: Henrique Nakashima Commit-Queue: Ryan Harrison --- core/fxcodec/bmp/cfx_bmpdecompressor.cpp | 86 +++++++++++++++++++------------- 1 file changed, 50 insertions(+), 36 deletions(-) (limited to 'core/fxcodec') 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((value16 + 1) / 2); @@ -97,16 +102,12 @@ int32_t CFX_BmpDecompressor::ReadHeader() { img_ifh_size_ = FXDWORD_GET_LSBFIRST(reinterpret_cast(&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(&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(&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(sizeof(BmpInfoHeader)))) { - BmpInfoHeader bmp_info_header; - if (!ReadData(reinterpret_cast(&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(&bmp_info_header.biWidth)); - int32_t signed_height = FXDWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biHeight)); - bit_counts_ = FXWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biBitCount)); - compress_flag_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biCompression)); - color_used_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biClrUsed)); - biPlanes = FXWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biPlanes)); - dpi_x_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast(&bmp_info_header.biXPelsPerMeter)); - dpi_y_ = FXDWORD_GET_LSBFIRST( - reinterpret_cast(&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(&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(&bmp_info_header.biWidth)); + int32_t signed_height = FXDWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biHeight)); + bit_counts_ = FXWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biBitCount)); + compress_flag_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biCompression)); + color_used_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biClrUsed)); + biPlanes = FXWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biPlanes)); + dpi_x_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast(&bmp_info_header.biXPelsPerMeter)); + dpi_y_ = FXDWORD_GET_LSBFIRST( + reinterpret_cast(&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: -- cgit v1.2.3