Use spancpy() in CFX_DIBBase::Clone().
Had Clone() been coded like this originally, even without the safe
arithmetic, the issue in https://pdfium-review.googlesource.com/85510
would have caused a trap. The additional checks should be acceptable
since they occur once per scanline and not once per pixel.
Change-Id: I0b0c8b0977e6902a4c233b582cbdb01796871174
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85555
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index aabc35f..2e396a9 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -16,6 +16,7 @@
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/span_util.h"
#include "core/fxge/cfx_cliprgn.h"
#include "core/fxge/dib/cfx_bitmapstorer.h"
#include "core/fxge/dib/cfx_dibitmap.h"
@@ -641,27 +642,26 @@
}
}
} else {
- FX_SAFE_UINT32 copy_len = pNewBitmap->GetWidth();
- copy_len *= pNewBitmap->GetBPP();
- copy_len += 7;
- copy_len /= 8;
- if (!copy_len.IsValid())
+ FX_SAFE_UINT32 safe_copy_len = pNewBitmap->GetWidth();
+ safe_copy_len *= pNewBitmap->GetBPP();
+ safe_copy_len += 7;
+ safe_copy_len /= 8;
+ if (!safe_copy_len.IsValid())
return nullptr;
- copy_len = std::min<uint32_t>(m_Pitch, copy_len.ValueOrDie());
+ uint32_t copy_len = std::min<uint32_t>(m_Pitch, safe_copy_len.ValueOrDie());
- FX_SAFE_UINT32 offset = rect.left;
- offset *= GetBppFromFormat(m_Format);
- offset /= 8;
- if (!offset.IsValid())
+ FX_SAFE_UINT32 safe_offset = rect.left;
+ safe_offset *= GetBppFromFormat(m_Format);
+ safe_offset /= 8;
+ if (!safe_offset.IsValid())
return nullptr;
+ uint32_t offset = safe_offset.ValueOrDie();
+
for (int row = rect.top; row < rect.bottom; ++row) {
- const uint8_t* src_scan =
- GetScanline(row).subspan(offset.ValueOrDie()).data();
- uint8_t* dest_scan =
- pNewBitmap->GetWritableScanline(row - rect.top).data();
- memcpy(dest_scan, src_scan, copy_len.ValueOrDie());
+ fxcrt::spancpy(pNewBitmap->GetWritableScanline(row - rect.top),
+ GetScanline(row).subspan(offset, copy_len));
}
}
return pNewBitmap;