Encapsulate CFX_DIBBase::m_pAlphaMask.

-- provide helper methods to consolidate some operations.
-- rewrite some expressions to be sure we never add offsets to
   nullptrs (undefined behaviour at best, arbitrary memory write
   primitive at worst).

Bug: pdfium:1680
Change-Id: I7450b857cd905a8cbeadc6e1dcc1bf75829e6c1b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/79950
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index f56bcb6..02e55d6 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -844,7 +844,7 @@
 
   uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y;
   uint8_t* dest_scan_extra_alpha = nullptr;
-  RetainPtr<CFX_DIBitmap> pAlphaMask = m_pDevice->m_pAlphaMask;
+  RetainPtr<CFX_DIBitmap> pAlphaMask = m_pDevice->GetAlphaMask();
   if (pAlphaMask) {
     dest_scan_extra_alpha =
         pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y;
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 5016306..f9709ad 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -1170,8 +1170,8 @@
       return false;
   } else {
     bitmap->Clear(0);
-    if (bitmap->m_pAlphaMask)
-      bitmap->m_pAlphaMask->Clear(0);
+    if (bitmap->HasAlphaMask())
+      bitmap->GetAlphaMask()->Clear(0);
   }
   int dest_width = pixel_width;
   int a = 0;
diff --git a/core/fxge/dib/cfx_bitmapcomposer.cpp b/core/fxge/dib/cfx_bitmapcomposer.cpp
index 86066ba..d50e4b4 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.cpp
+++ b/core/fxge/dib/cfx_bitmapcomposer.cpp
@@ -55,7 +55,7 @@
   if (m_bVertical) {
     m_pScanlineV.resize(m_pBitmap->GetBPP() / 8 * width + 4);
     m_pClipScanV.resize(m_pBitmap->GetHeight());
-    if (m_pBitmap->m_pAlphaMask)
+    if (m_pBitmap->HasAlphaMask())
       m_pScanlineAlphaV.resize(width + 4);
   }
   if (m_BitmapAlpha < 255) {
@@ -109,13 +109,15 @@
                     m_pClipMask->GetPitch() +
                 (m_DestLeft - m_pClipRgn->GetBox().left);
   }
-  uint8_t* dest_scan = m_pBitmap->GetWritableScanline(line + m_DestTop) +
-                       m_DestLeft * m_pBitmap->GetBPP() / 8;
+  uint8_t* dest_scan = m_pBitmap->GetWritableScanline(line + m_DestTop);
+  if (dest_scan)
+    dest_scan += m_DestLeft * m_pBitmap->GetBPP() / 8;
+
   uint8_t* dest_alpha_scan =
-      m_pBitmap->m_pAlphaMask
-          ? m_pBitmap->m_pAlphaMask->GetWritableScanline(line + m_DestTop) +
-                m_DestLeft
-          : nullptr;
+      m_pBitmap->GetWritableAlphaMaskScanline(line + m_DestTop);
+  if (dest_alpha_scan)
+    dest_alpha_scan += m_DestLeft;
+
   DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha,
             dest_alpha_scan);
 }
@@ -125,18 +127,19 @@
                                           const uint8_t* scan_extra_alpha) {
   int Bpp = m_pBitmap->GetBPP() / 8;
   int dest_pitch = m_pBitmap->GetPitch();
-  int dest_alpha_pitch =
-      m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
+  int dest_alpha_pitch = m_pBitmap->GetAlphaMaskPitch();
   int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
-  uint8_t* dest_buf =
-      m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
-  uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask
-                                ? m_pBitmap->m_pAlphaMask->GetBuffer() +
-                                      dest_x + m_DestTop * dest_alpha_pitch
-                                : nullptr;
-  if (m_bFlipY) {
-    dest_buf += dest_pitch * (m_DestHeight - 1);
-    dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
+  uint8_t* dest_buf = m_pBitmap->GetBuffer();
+  if (dest_buf) {
+    dest_buf += dest_x * Bpp + m_DestTop * dest_pitch;
+    if (m_bFlipY)
+      dest_buf += dest_pitch * (m_DestHeight - 1);
+  }
+  uint8_t* dest_alpha_buf = m_pBitmap->GetAlphaMaskBuffer();
+  if (dest_alpha_buf) {
+    dest_alpha_buf += dest_x + m_DestTop * dest_alpha_pitch;
+    if (m_bFlipY)
+      dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
   }
   int y_step = dest_pitch;
   int y_alpha_step = dest_alpha_pitch;
diff --git a/core/fxge/dib/cfx_bitmapstorer.cpp b/core/fxge/dib/cfx_bitmapstorer.cpp
index 0871995..f57c00e 100644
--- a/core/fxge/dib/cfx_bitmapstorer.cpp
+++ b/core/fxge/dib/cfx_bitmapstorer.cpp
@@ -26,17 +26,12 @@
                                        const uint8_t* scanline,
                                        const uint8_t* scan_extra_alpha) {
   uint8_t* dest_buf = m_pBitmap->GetWritableScanline(line);
-  uint8_t* dest_alpha_buf =
-      m_pBitmap->m_pAlphaMask
-          ? m_pBitmap->m_pAlphaMask->GetWritableScanline(line)
-          : nullptr;
   if (dest_buf)
     memcpy(dest_buf, scanline, m_pBitmap->GetPitch());
 
-  if (dest_alpha_buf) {
-    memcpy(dest_alpha_buf, scan_extra_alpha,
-           m_pBitmap->m_pAlphaMask->GetPitch());
-  }
+  uint8_t* dest_alpha_buf = m_pBitmap->GetWritableAlphaMaskScanline(line);
+  if (dest_alpha_buf)
+    memcpy(dest_alpha_buf, scan_extra_alpha, m_pBitmap->GetAlphaMaskPitch());
 }
 
 bool CFX_BitmapStorer::SetInfo(int width,
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index e77be41..d8be60d 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -849,6 +849,26 @@
   }
 }
 
+uint32_t CFX_DIBBase::GetAlphaMaskPitch() const {
+  return m_pAlphaMask ? m_pAlphaMask->GetPitch() : 0;
+}
+
+const uint8_t* CFX_DIBBase::GetAlphaMaskScanline(int line) const {
+  return m_pAlphaMask ? m_pAlphaMask->GetScanline(line) : nullptr;
+}
+
+uint8_t* CFX_DIBBase::GetWritableAlphaMaskScanline(int line) {
+  return m_pAlphaMask ? m_pAlphaMask->GetWritableScanline(line) : nullptr;
+}
+
+uint8_t* CFX_DIBBase::GetAlphaMaskBuffer() {
+  return m_pAlphaMask ? m_pAlphaMask->GetBuffer() : nullptr;
+}
+
+RetainPtr<CFX_DIBitmap> CFX_DIBBase::GetAlphaMask() {
+  return m_pAlphaMask;
+}
+
 RetainPtr<CFX_DIBitmap> CFX_DIBBase::CloneAlphaMask() const {
   DCHECK_EQ(GetFormat(), FXDIB_Format::kArgb);
   FX_RECT rect(0, 0, m_Width, m_Height);
diff --git a/core/fxge/dib/cfx_dibbase.h b/core/fxge/dib/cfx_dibbase.h
index 1d3c5d9..6e97384 100644
--- a/core/fxge/dib/cfx_dibbase.h
+++ b/core/fxge/dib/cfx_dibbase.h
@@ -76,6 +76,12 @@
   RetainPtr<CFX_DIBitmap> SwapXY(bool bXFlip, bool bYFlip) const;
   RetainPtr<CFX_DIBitmap> FlipImage(bool bXFlip, bool bYFlip) const;
 
+  bool HasAlphaMask() const { return !!m_pAlphaMask; }
+  uint32_t GetAlphaMaskPitch() const;
+  const uint8_t* GetAlphaMaskScanline(int line) const;
+  uint8_t* GetWritableAlphaMaskScanline(int line);
+  uint8_t* GetAlphaMaskBuffer();
+  RetainPtr<CFX_DIBitmap> GetAlphaMask();
   RetainPtr<CFX_DIBitmap> CloneAlphaMask() const;
 
   // Copies into internally-owned mask.
@@ -96,8 +102,6 @@
   void DebugVerifyBitmapIsPreMultiplied(void* buffer) const;
 #endif
 
-  RetainPtr<CFX_DIBitmap> m_pAlphaMask;
-
  protected:
   CFX_DIBBase();
 
@@ -117,10 +121,11 @@
   int FindPalette(uint32_t color) const;
   void GetPalette(uint32_t* pal, int alpha) const;
 
+  FXDIB_Format m_Format = FXDIB_Format::kInvalid;
   int m_Width = 0;
   int m_Height = 0;
   uint32_t m_Pitch = 0;
-  FXDIB_Format m_Format = FXDIB_Format::kInvalid;
+  RetainPtr<CFX_DIBitmap> m_pAlphaMask;
   std::vector<uint32_t, FxAllocAllocator<uint32_t>> m_palette;
 };
 
diff --git a/core/fxge/dib/cfx_dibextractor.cpp b/core/fxge/dib/cfx_dibextractor.cpp
index 679ac09..ce8ca58 100644
--- a/core/fxge/dib/cfx_dibextractor.cpp
+++ b/core/fxge/dib/cfx_dibextractor.cpp
@@ -22,7 +22,7 @@
     return;
   }
   m_pBitmap->SetPalette(pOldSrc->GetPaletteSpan());
-  m_pBitmap->SetAlphaMask(pOldSrc->m_pAlphaMask, nullptr);
+  m_pBitmap->SetAlphaMask(pOldSrc->GetAlphaMask(), nullptr);
 }
 
 CFX_DIBExtractor::~CFX_DIBExtractor() = default;
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 9b77e86..92f69c2 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -79,7 +79,7 @@
     return false;
 
   SetPalette(pSrc->GetPaletteSpan());
-  SetAlphaMask(pSrc->m_pAlphaMask, nullptr);
+  SetAlphaMask(pSrc->GetAlphaMask(), nullptr);
   for (int row = 0; row < pSrc->GetHeight(); row++)
     memcpy(m_pBuffer.Get() + row * m_Pitch, pSrc->GetScanline(row), m_Pitch);
   return true;
@@ -306,8 +306,8 @@
     }
     destOffset = 2;
   }
-  if (pSrcClone->m_pAlphaMask) {
-    RetainPtr<CFX_DIBBase> pAlphaMask = pSrcClone->m_pAlphaMask;
+  if (pSrcClone->HasAlphaMask()) {
+    RetainPtr<CFX_DIBBase> pAlphaMask = pSrcClone->GetAlphaMask();
     if (pSrcClone->GetWidth() != m_Width ||
         pSrcClone->GetHeight() != m_Height) {
       if (pAlphaMask) {
@@ -792,7 +792,7 @@
   if (!bRgb && !pSrcBitmap->HasPalette())
     return false;
 
-  RetainPtr<CFX_DIBitmap> pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
+  RetainPtr<CFX_DIBitmap> pSrcAlphaMask = pSrcBitmap->GetAlphaMask();
   for (int row = 0; row < height; row++) {
     uint8_t* dest_scan =
         m_pBuffer.Get() + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp
index 191c9c1..9a328e9 100644
--- a/core/fxge/dib/cfx_imagetransformer.cpp
+++ b/core/fxge/dib/cfx_imagetransformer.cpp
@@ -243,11 +243,9 @@
   if (!pTransformed->Create(m_result.Width(), m_result.Height(), format))
     return;
 
-  const auto& pSrcMask = m_Storer.GetBitmap()->m_pAlphaMask;
-  const uint8_t* pSrcMaskBuf = pSrcMask ? pSrcMask->GetBuffer() : nullptr;
-
+  const uint8_t* pSrcMaskBuf = m_Storer.GetBitmap()->GetAlphaMaskBuffer();
   pTransformed->Clear(0);
-  auto& pDestMask = pTransformed->m_pAlphaMask;
+  RetainPtr<CFX_DIBitmap> pDestMask = pTransformed->GetAlphaMask();
   if (pDestMask)
     pDestMask->Clear(0);
 
@@ -262,7 +260,7 @@
         pDestMask.Get(),
         result2stretch,
         pSrcMaskBuf,
-        m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(),
+        m_Storer.GetBitmap()->GetAlphaMaskPitch(),
     };
     CalcMask(calc_data);
   }
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp
index 5f49e44..fd0aed2 100644
--- a/core/fxge/dib/cstretchengine.cpp
+++ b/core/fxge/dib/cstretchengine.cpp
@@ -248,7 +248,7 @@
   }
 
   m_InterBuf.resize(m_SrcClip.Height() * m_InterPitch);
-  if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) {
+  if (m_pSource && m_bHasAlpha && m_pSource->HasAlphaMask()) {
     m_ExtraAlphaBuf.resize(m_SrcClip.Height(), m_ExtraMaskPitch);
     m_DestMaskScanline.resize(m_ExtraMaskPitch);
   }
@@ -286,7 +286,7 @@
     const uint8_t* src_scan_mask = nullptr;
     uint8_t* dest_scan_mask = nullptr;
     if (!m_ExtraAlphaBuf.empty()) {
-      src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow);
+      src_scan_mask = m_pSource->GetAlphaMaskScanline(m_CurRow);
       dest_scan_mask = m_ExtraAlphaBuf.data() +
                        (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch;
     }