Use checked math in RgbByteOrderTransferBitmap().
Avoid unchecked integer multiplication.
Bug: chromium:1386120
Change-Id: I9cbd34c4272aaa5234bc8416886ccb0cef4d23a0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/101610
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index e317065..8665610 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -12,6 +12,7 @@
#include <utility>
#include "build/build_config.h"
+#include "core/fxcrt/fx_safe_types.h"
#include "core/fxge/cfx_cliprgn.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/cfx_graphstatedata.h"
@@ -126,9 +127,13 @@
}
}
+size_t GetSizeOrDie(int m1, int m2) {
+ FX_SAFE_SIZE_T result = m1;
+ result *= m2;
+ return result.ValueOrDie();
+}
+
void RgbByteOrderTransferBitmap(const RetainPtr<CFX_DIBitmap>& pBitmap,
- int dest_left,
- int dest_top,
int width,
int height,
const RetainPtr<CFX_DIBBase>& pSrcBitmap,
@@ -137,22 +142,30 @@
if (!pBitmap)
return;
+ int dest_left = 0;
+ int dest_top = 0;
if (!pBitmap->GetOverlapRect(dest_left, dest_top, width, height,
pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
src_left, src_top, nullptr)) {
return;
}
- int Bpp = pBitmap->GetBPP() / 8;
- FXDIB_Format dest_format = pBitmap->GetFormat();
- FXDIB_Format src_format = pSrcBitmap->GetFormat();
- int pitch = pBitmap->GetPitch();
- uint8_t* buffer = pBitmap->GetBuffer().data();
+ const int Bpp = pBitmap->GetBPP() / 8;
+ const FXDIB_Format dest_format = pBitmap->GetFormat();
+ const FXDIB_Format src_format = pSrcBitmap->GetFormat();
+ const int dest_pitch = pBitmap->GetPitch();
+
+ const size_t dest_x_offset = GetSizeOrDie(dest_left, Bpp);
+ const size_t dest_y_offset = GetSizeOrDie(dest_top, dest_pitch);
+
+ uint8_t* dest_buf =
+ pBitmap->GetBuffer().subspan(dest_y_offset).subspan(dest_x_offset).data();
if (dest_format == src_format) {
+ const size_t src_x_offset = GetSizeOrDie(src_left, Bpp);
for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp;
+ uint8_t* dest_scan = dest_buf;
const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_left * Bpp).data();
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
if (Bpp == 4) {
for (int col = 0; col < width; col++) {
FXARGB_SETRGBORDERDIB(dest_scan,
@@ -168,23 +181,25 @@
*dest_scan++ = src_scan[0];
src_scan += 3;
}
+ dest_buf += dest_pitch;
}
return;
}
- uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp;
if (dest_format == FXDIB_Format::kRgb) {
DCHECK_EQ(src_format, FXDIB_Format::kRgb32);
+ const size_t src_x_offset = GetSizeOrDie(src_left, 4);
for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_buf + row * pitch;
+ uint8_t* dest_scan = dest_buf;
const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_left * 4).data();
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
*dest_scan++ = src_scan[2];
*dest_scan++ = src_scan[1];
*dest_scan++ = src_scan[0];
src_scan += 4;
}
+ dest_buf += dest_pitch;
}
return;
}
@@ -192,32 +207,36 @@
DCHECK(dest_format == FXDIB_Format::kArgb ||
dest_format == FXDIB_Format::kRgb32);
if (src_format == FXDIB_Format::kRgb) {
+ const size_t src_x_offset = GetSizeOrDie(src_left, 3);
for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_buf + row * pitch;
+ uint8_t* dest_scan = dest_buf;
const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_left * 3).data();
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
FXARGB_SETDIB(dest_scan,
ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
dest_scan += 4;
src_scan += 3;
}
+ dest_buf += dest_pitch;
}
return;
}
if (src_format != FXDIB_Format::kRgb32)
return;
DCHECK_EQ(dest_format, FXDIB_Format::kArgb);
+ const size_t src_x_offset = GetSizeOrDie(src_left, 4);
for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_buf + row * pitch;
+ uint8_t* dest_scan = dest_buf;
const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_left * 4).data();
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
FXARGB_SETDIB(dest_scan,
ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
src_scan += 4;
dest_scan += 4;
}
+ dest_buf += dest_pitch;
}
}
@@ -1335,8 +1354,8 @@
left = std::min(left, 0);
top = std::min(top, 0);
if (m_bRgbByteOrder) {
- RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(),
- pBack, left, top);
+ RgbByteOrderTransferBitmap(pBitmap, rect.Width(), rect.Height(), pBack,
+ left, top);
return true;
}
return pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack, left,