Get rid of longjmp() usage in CFX_BmpDecompressor.
Change CFX_BmpDecompressor::ReadHeader() and friends to return
BmpModule::Status, which is a tri-state, instead of returning a bool and
handling errors with longjmp().
Change-Id: I74d920d582b47832e60a0e00448671c86629a3a7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61670
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/bmp/bmpmodule.cpp b/core/fxcodec/bmp/bmpmodule.cpp
index d7472a8..78854c4 100644
--- a/core/fxcodec/bmp/bmpmodule.cpp
+++ b/core/fxcodec/bmp/bmpmodule.cpp
@@ -35,11 +35,9 @@
ASSERT(pAttribute);
auto* ctx = static_cast<CFX_BmpContext*>(pContext);
- if (setjmp(*ctx->m_Bmp.jmpbuf()))
- return Status::kFail;
-
- if (!ctx->m_Bmp.ReadHeader())
- return Status::kContinue;
+ Status status = ctx->m_Bmp.ReadHeader();
+ if (status != Status::kSuccess)
+ return status;
*width = ctx->m_Bmp.width();
*height = ctx->m_Bmp.height();
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index 3adda59..682c68f 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -59,10 +59,6 @@
CFX_BmpDecompressor::~CFX_BmpDecompressor() = default;
-void CFX_BmpDecompressor::Error() {
- longjmp(jmpbuf_, 1);
-}
-
void CFX_BmpDecompressor::ReadNextScanline() {
uint32_t row = img_tb_flag_ ? row_num_ : (height_ - 1 - row_num_);
context_->m_pDelegate->BmpReadScanline(row, out_row_buffer_);
@@ -73,12 +69,15 @@
return context_->m_pDelegate->BmpInputImagePositionBuf(rcd_pos);
}
-bool CFX_BmpDecompressor::ReadHeader() {
- if (decode_status_ == DecodeStatus::kHeader && !ReadBmpHeader())
- return false;
+BmpModule::Status CFX_BmpDecompressor::ReadHeader() {
+ if (decode_status_ == DecodeStatus::kHeader) {
+ BmpModule::Status status = ReadBmpHeader();
+ if (status != BmpModule::Status::kSuccess)
+ return status;
+ }
if (decode_status_ != DecodeStatus::kPal)
- return true;
+ return BmpModule::Status::kSuccess;
if (compress_flag_ == kBmpBitfields)
return ReadBmpBitfields();
@@ -86,11 +85,11 @@
return ReadBmpPalette();
}
-bool CFX_BmpDecompressor::ReadBmpHeader() {
+BmpModule::Status CFX_BmpDecompressor::ReadBmpHeader() {
BmpFileHeader bmp_header;
if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_header),
sizeof(BmpFileHeader))) {
- return false;
+ return BmpModule::Status::kContinue;
}
bmp_header.bfType =
@@ -99,39 +98,34 @@
FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
data_size_ =
FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
- if (bmp_header.bfType != kBmpSignature) {
- Error();
- NOTREACHED();
- }
+ if (bmp_header.bfType != kBmpSignature)
+ return BmpModule::Status::kFail;
size_t pos = input_buffer_->GetPosition();
if (!ReadData(reinterpret_cast<uint8_t*>(&img_ifh_size_),
sizeof(img_ifh_size_))) {
- return false;
+ return BmpModule::Status::kContinue;
}
if (!input_buffer_->Seek(pos))
- return false;
+ return BmpModule::Status::kContinue;
img_ifh_size_ =
FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
pal_type_ = 0;
- if (!ReadBmpHeaderIfh())
- return false;
+ BmpModule::Status status = ReadBmpHeaderIfh();
+ if (status != BmpModule::Status::kSuccess)
+ return status;
- if (!ReadBmpHeaderDimensions()) {
- Error();
- NOTREACHED();
- }
- return true;
+ return ReadBmpHeaderDimensions();
}
-bool CFX_BmpDecompressor::ReadBmpHeaderIfh() {
+BmpModule::Status CFX_BmpDecompressor::ReadBmpHeaderIfh() {
if (img_ifh_size_ == kBmpCoreHeaderSize) {
pal_type_ = 1;
BmpCoreHeader bmp_core_header;
if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_core_header),
sizeof(BmpCoreHeader))) {
- return false;
+ return BmpModule::Status::kContinue;
}
width_ = FXWORD_GET_LSBFIRST(
@@ -142,14 +136,14 @@
reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
compress_flag_ = kBmpRgb;
img_tb_flag_ = false;
- return true;
+ return BmpModule::Status::kSuccess;
}
if (img_ifh_size_ == kBmpInfoHeaderSize) {
BmpInfoHeader bmp_info_header;
if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
sizeof(BmpInfoHeader))) {
- return false;
+ return BmpModule::Status::kContinue;
}
width_ = FXDWORD_GET_LSBFIRST(
@@ -166,33 +160,27 @@
reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
dpi_y_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
- if (!SetHeight(signed_height)) {
- Error();
- NOTREACHED();
- }
- return true;
+ if (!SetHeight(signed_height))
+ return BmpModule::Status::kFail;
+ return BmpModule::Status::kSuccess;
}
- if (img_ifh_size_ <= sizeof(BmpInfoHeader)) {
- Error();
- NOTREACHED();
- }
+ if (img_ifh_size_ <= sizeof(BmpInfoHeader))
+ return BmpModule::Status::kFail;
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 false;
+ return BmpModule::Status::kContinue;
}
new_pos += img_ifh_size_;
- if (!new_pos.IsValid()) {
- Error();
- NOTREACHED();
- }
+ if (!new_pos.IsValid())
+ return BmpModule::Status::kFail;
if (!input_buffer_->Seek(new_pos.ValueOrDie()))
- return false;
+ return BmpModule::Status::kContinue;
uint16_t bi_planes;
width_ = FXDWORD_GET_LSBFIRST(
@@ -211,21 +199,17 @@
reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
dpi_y_ = FXDWORD_GET_LSBFIRST(
reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
- if (!SetHeight(signed_height)) {
- Error();
- NOTREACHED();
- }
- if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0) {
- Error();
- NOTREACHED();
- }
- return true;
+ if (!SetHeight(signed_height))
+ return BmpModule::Status::kFail;
+ if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0)
+ return BmpModule::Status::kFail;
+ return BmpModule::Status::kSuccess;
}
-bool CFX_BmpDecompressor::ReadBmpHeaderDimensions() {
+BmpModule::Status CFX_BmpDecompressor::ReadBmpHeaderDimensions() {
if (width_ > kBmpMaxImageDimension || height_ > kBmpMaxImageDimension ||
compress_flag_ > kBmpBitfields) {
- return false;
+ return BmpModule::Status::kFail;
}
switch (bit_counts_) {
@@ -235,17 +219,17 @@
case 16:
case 24: {
if (color_used_ > 1U << bit_counts_)
- return false;
+ return BmpModule::Status::kFail;
break;
}
case 32:
break;
default:
- return false;
+ return BmpModule::Status::kFail;
}
FX_SAFE_UINT32 stride = CalculatePitch32(bit_counts_, width_);
if (!stride.IsValid())
- return false;
+ return BmpModule::Status::kFail;
src_row_bytes_ = stride.ValueOrDie();
switch (bit_counts_) {
@@ -254,7 +238,7 @@
case 8:
stride = CalculatePitch32(8, width_);
if (!stride.IsValid())
- return false;
+ return BmpModule::Status::kFail;
out_row_bytes_ = stride.ValueOrDie();
components_ = 1;
break;
@@ -262,7 +246,7 @@
case 24:
stride = CalculatePitch32(24, width_);
if (!stride.IsValid())
- return false;
+ return BmpModule::Status::kFail;
out_row_bytes_ = stride.ValueOrDie();
components_ = 3;
break;
@@ -274,37 +258,34 @@
out_row_buffer_.clear();
if (out_row_bytes_ <= 0)
- return false;
+ return BmpModule::Status::kFail;
out_row_buffer_.resize(out_row_bytes_);
SaveDecodingStatus(DecodeStatus::kPal);
- return true;
+ return BmpModule::Status::kSuccess;
}
-bool CFX_BmpDecompressor::ReadBmpBitfields() {
- if (bit_counts_ != 16 && bit_counts_ != 32) {
- Error();
- NOTREACHED();
- }
+BmpModule::Status CFX_BmpDecompressor::ReadBmpBitfields() {
+ if (bit_counts_ != 16 && bit_counts_ != 32)
+ return BmpModule::Status::kFail;
uint32_t masks[3];
if (!ReadData(reinterpret_cast<uint8_t*>(masks), sizeof(masks)))
- return false;
+ return BmpModule::Status::kContinue;
mask_red_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
mask_green_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
mask_blue_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
mask_green_ & mask_blue_) {
- Error();
- NOTREACHED();
+ return BmpModule::Status::kFail;
}
header_offset_ = std::max(header_offset_, 26 + img_ifh_size_);
SaveDecodingStatus(DecodeStatus::kDataPre);
- return true;
+ return BmpModule::Status::kSuccess;
}
-bool CFX_BmpDecompressor::ReadBmpPalette() {
+BmpModule::Status CFX_BmpDecompressor::ReadBmpPalette() {
if (bit_counts_ == 16) {
mask_red_ = 0x7C00;
mask_green_ = 0x03E0;
@@ -319,7 +300,7 @@
std::vector<uint8_t> src_pal(src_pal_size);
uint8_t* src_pal_data = src_pal.data();
if (!ReadData(src_pal_data, src_pal_size))
- return false;
+ return BmpModule::Status::kContinue;
palette_.resize(pal_num_);
int32_t src_pal_index = 0;
@@ -340,7 +321,7 @@
header_offset_ = std::max(
header_offset_, 14 + img_ifh_size_ + pal_num_ * (pal_type_ ? 3 : 4));
SaveDecodingStatus(DecodeStatus::kDataPre);
- return true;
+ return BmpModule::Status::kSuccess;
}
bool CFX_BmpDecompressor::ValidateFlag() const {
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.h b/core/fxcodec/bmp/cfx_bmpdecompressor.h
index e9761b5..3f4e2d8 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.h
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.h
@@ -7,8 +7,6 @@
#ifndef CORE_FXCODEC_BMP_CFX_BMPDECOMPRESSOR_H_
#define CORE_FXCODEC_BMP_CFX_BMPDECOMPRESSOR_H_
-#include <setjmp.h>
-
#include <vector>
#include "core/fxcodec/bmp/bmpmodule.h"
@@ -27,13 +25,11 @@
explicit CFX_BmpDecompressor(CFX_BmpContext* context);
~CFX_BmpDecompressor();
- void Error();
BmpModule::Status DecodeImage();
- bool ReadHeader();
+ BmpModule::Status ReadHeader();
void SetInputBuffer(RetainPtr<CFX_CodecMemory> codec_memory);
FX_FILESIZE GetAvailInput() const;
- jmp_buf* jmpbuf() { return &jmpbuf_; }
const std::vector<uint32_t>* palette() const { return &palette_; }
uint32_t width() const { return width_; }
uint32_t height() const { return height_; }
@@ -52,11 +48,11 @@
kTail,
};
- bool ReadBmpHeader();
- bool ReadBmpHeaderIfh();
- bool ReadBmpHeaderDimensions();
- bool ReadBmpBitfields();
- bool ReadBmpPalette();
+ BmpModule::Status ReadBmpHeader();
+ BmpModule::Status ReadBmpHeaderIfh();
+ BmpModule::Status ReadBmpHeaderDimensions();
+ BmpModule::Status ReadBmpBitfields();
+ BmpModule::Status ReadBmpPalette();
bool GetDataPosition(uint32_t cur_pos);
void ReadNextScanline();
BmpModule::Status DecodeRGB();
@@ -68,7 +64,6 @@
bool ValidateFlag() const;
bool SetHeight(int32_t signed_height);
- jmp_buf jmpbuf_;
UnownedPtr<CFX_BmpContext> const context_;
std::vector<uint8_t> out_row_buffer_;
std::vector<uint32_t> palette_;