Avoid integer overflows in CFX_DIBBase::SwapXY().
Bug: chromium:1386122
Change-Id: I1a85813c9ce63e8565ddce08004d47d09f65cb02
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/101690
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index 7f5559f..21f8ee7 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -14,6 +14,7 @@
#include <vector>
#include "core/fxcrt/data_vector.h"
+#include "core/fxcrt/fx_2d_size.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
@@ -1046,28 +1047,31 @@
return nullptr;
auto pTransBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- int result_height = dest_clip.Height();
- int result_width = dest_clip.Width();
+ const int result_height = dest_clip.Height();
+ const int result_width = dest_clip.Width();
if (!pTransBitmap->Create(result_width, result_height, GetFormat()))
return nullptr;
pTransBitmap->SetPalette(GetPaletteSpan());
- int dest_pitch = pTransBitmap->GetPitch();
uint8_t* dest_buf = pTransBitmap->GetBuffer().data();
- int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
- int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
- int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
- int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
+ const int dest_pitch = pTransBitmap->GetPitch();
+ const size_t dest_size = Fx2DSizeOrDie(dest_pitch, result_height);
+ const size_t dest_last_row_offset =
+ Fx2DSizeOrDie(dest_pitch, result_height - 1);
+ const int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
+ const int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
+ const int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
+ const int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
if (GetBPP() == 1) {
- memset(dest_buf, 0xff, dest_pitch * result_height);
+ memset(dest_buf, 0xff, dest_size);
+ if (bYFlip)
+ dest_buf += dest_last_row_offset;
+ const int dest_step = bYFlip ? -dest_pitch : dest_pitch;
for (int row = row_start; row < row_end; ++row) {
const uint8_t* src_scan = GetScanline(row).data();
int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
dest_clip.left;
uint8_t* dest_scan = dest_buf;
- if (bYFlip)
- dest_scan += (result_height - 1) * dest_pitch;
- int dest_step = bYFlip ? -dest_pitch : dest_pitch;
for (int col = col_start; col < col_end; ++col) {
if (!(src_scan[col / 8] & (1 << (7 - col % 8))))
dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
@@ -1079,12 +1083,13 @@
int dest_step = bYFlip ? -dest_pitch : dest_pitch;
if (nBytes == 3)
dest_step -= 2;
+ if (bYFlip)
+ dest_buf += dest_last_row_offset;
for (int row = row_start; row < row_end; ++row) {
int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
dest_clip.left;
- uint8_t* dest_scan = dest_buf + dest_col * nBytes;
- if (bYFlip)
- dest_scan += (result_height - 1) * dest_pitch;
+ size_t dest_offset = Fx2DSizeOrDie(dest_col, nBytes);
+ uint8_t* dest_scan = dest_buf + dest_offset;
if (nBytes == 4) {
const uint32_t* src_scan =
reinterpret_cast<const uint32_t*>(GetScanline(row).data()) +
@@ -1113,20 +1118,22 @@
}
}
if (m_pAlphaMask) {
- dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
- dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer().data();
- int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+ uint8_t* desk_mask_buf = pTransBitmap->m_pAlphaMask->GetBuffer().data();
+ const int dest_mask_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
+ const int dest_mask_step = bYFlip ? -dest_mask_pitch : dest_mask_pitch;
+ const size_t dest_mask_last_row_offset =
+ Fx2DSizeOrDie(dest_mask_pitch, result_height - 1);
for (int row = row_start; row < row_end; ++row) {
int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
dest_clip.left;
- uint8_t* dest_scan = dest_buf + dest_col;
+ uint8_t* desk_mask_scan = desk_mask_buf + dest_col;
if (bYFlip)
- dest_scan += (result_height - 1) * dest_pitch;
+ desk_mask_scan += dest_mask_last_row_offset;
const uint8_t* src_scan =
m_pAlphaMask->GetScanline(row).subspan(col_start).data();
for (int col = col_start; col < col_end; ++col) {
- *dest_scan = *src_scan++;
- dest_scan += dest_step;
+ *desk_mask_scan = *src_scan++;
+ desk_mask_scan += dest_mask_step;
}
}
}