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;