| Index: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
 | 
| diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
 | 
| index 7f442eb15c18eefc21d622146bbd81eec1492931..5279ab9ebb4f309b8f510c95091e287d0c5c881c 100644
 | 
| --- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
 | 
| +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
 | 
| @@ -11,7 +11,8 @@
 | 
|  #include "../../../include/fpdfapi/fpdf_pageobj.h"
 | 
|  #include "../fpdf_page/pageint.h"
 | 
|  #include "render_int.h"
 | 
| -#include <limits.h>
 | 
| +#include "../../../../third_party/numerics/safe_math.h"
 | 
| +
 | 
|  static unsigned int _GetBits8(FX_LPCBYTE pData, int bitpos, int nbits)
 | 
|  {
 | 
|      unsigned int byte = pData[bitpos / 8];
 | 
| @@ -175,27 +176,23 @@ FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CP
 | 
|      if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) {
 | 
|          return FALSE;
 | 
|      }
 | 
| -    FX_DWORD src_pitch = m_bpc;
 | 
| -    if (m_bpc != 0 && m_nComponents != 0) {
 | 
| -        if (src_pitch > 0 && m_nComponents > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return FALSE;
 | 
| -        }
 | 
| -        src_pitch *= m_nComponents;
 | 
| -        if (src_pitch > 0 && (FX_DWORD)m_Width > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return FALSE;
 | 
| -        }
 | 
| -        src_pitch *= m_Width;
 | 
| -        if (src_pitch + 7 < src_pitch) {
 | 
| -            return FALSE;
 | 
| -        }
 | 
| -        src_pitch += 7;
 | 
| -        src_pitch /= 8;
 | 
| -        if (src_pitch > 0 && (FX_DWORD)m_Height > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return FALSE;
 | 
| -        }
 | 
| +
 | 
| +    if (m_bpc == 0 || m_nComponents == 0) {
 | 
| +        return FALSE;
 | 
| +    }
 | 
| +
 | 
| +    FX_SAFE_DWORD src_pitch = m_bpc;
 | 
| +    src_pitch *= m_nComponents;
 | 
| +    src_pitch *= m_Width;
 | 
| +    src_pitch += 7;
 | 
| +    src_pitch /= 8;
 | 
| +    src_pitch *= m_Height;
 | 
| +    if (!src_pitch.IsValid()) {
 | 
| +        return FALSE;
 | 
|      }
 | 
| +
 | 
|      m_pStreamAcc = FX_NEW CPDF_StreamAcc;
 | 
| -    m_pStreamAcc->LoadAllData(pStream, FALSE, m_Height * src_pitch, TRUE);
 | 
| +    m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE);
 | 
|      if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) {
 | 
|          return FALSE;
 | 
|      }
 | 
| @@ -218,20 +215,16 @@ FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CP
 | 
|      } else {
 | 
|          m_bpp = 24;
 | 
|      }
 | 
| -    if (!m_bpc || !m_nComponents) {
 | 
| -        return FALSE;
 | 
| -    }
 | 
| -    m_Pitch = m_Width;
 | 
| -    if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) {
 | 
| -        return FALSE;
 | 
| -    }
 | 
| -    m_Pitch *= m_bpp;
 | 
| -    if (m_Pitch + 31 < m_Pitch) {
 | 
| +
 | 
| +    FX_SAFE_DWORD pitch = m_Width;
 | 
| +    pitch *= m_bpp;
 | 
| +    pitch += 31;
 | 
| +    pitch /= 8;
 | 
| +    if (!pitch.IsValid()) {
 | 
|          return FALSE;
 | 
|      }
 | 
| -    m_Pitch += 31;
 | 
| -    m_Pitch = m_Pitch / 32 * 4;
 | 
| -    m_pLineBuf = FX_Alloc(FX_BYTE, m_Pitch);
 | 
| +  
 | 
| +    m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
 | 
|      if (m_pColorSpace && bStdCS) {
 | 
|          m_pColorSpace->EnableStdConversion(TRUE);
 | 
|      }
 | 
| @@ -239,18 +232,17 @@ FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CP
 | 
|      if (m_bColorKey) {
 | 
|          m_bpp = 32;
 | 
|          m_AlphaFlag = 2;
 | 
| -        m_Pitch = m_Width;
 | 
| -        if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) {
 | 
| +        pitch = m_Width;
 | 
| +        pitch *= m_bpp;
 | 
| +        pitch += 31;
 | 
| +        pitch /= 8;
 | 
| +        if (!pitch.IsValid()) {
 | 
|              return FALSE;
 | 
|          }
 | 
| -        m_Pitch *= m_bpp;
 | 
| -        if (m_Pitch + 31 < m_Pitch) {
 | 
| -            return FALSE;
 | 
| -        }
 | 
| -        m_Pitch += 31;
 | 
| -        m_Pitch = m_Pitch / 32 * 4;
 | 
| -        m_pMaskedLine = FX_Alloc(FX_BYTE, m_Pitch);
 | 
| +
 | 
| +        m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
 | 
|      }
 | 
| +    m_Pitch = pitch.ValueOrDie();
 | 
|      if (ppMask) {
 | 
|          *ppMask = LoadMask(*pMatteColor);
 | 
|      }
 | 
| @@ -276,17 +268,14 @@ int	CPDF_DIBSource::ContinueToLoadMask()
 | 
|      if (!m_bpc || !m_nComponents) {
 | 
|          return 0;
 | 
|      }
 | 
| -    m_Pitch = m_Width;
 | 
| -    if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) {
 | 
| +    FX_SAFE_DWORD pitch = m_Width;
 | 
| +    pitch *= m_bpp;
 | 
| +    pitch += 31;
 | 
| +    pitch /= 8;
 | 
| +    if (!pitch.IsValid()) {
 | 
|          return 0;
 | 
|      }
 | 
| -    m_Pitch *= m_bpp;
 | 
| -    if (m_Pitch + 31 < m_Pitch) {
 | 
| -        return 0;
 | 
| -    }
 | 
| -    m_Pitch += 31;
 | 
| -    m_Pitch = m_Pitch / 32 * 4;
 | 
| -    m_pLineBuf = FX_Alloc(FX_BYTE, m_Pitch);
 | 
| +    m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
 | 
|      if (m_pColorSpace && m_bStdCS) {
 | 
|          m_pColorSpace->EnableStdConversion(TRUE);
 | 
|      }
 | 
| @@ -294,18 +283,16 @@ int	CPDF_DIBSource::ContinueToLoadMask()
 | 
|      if (m_bColorKey) {
 | 
|          m_bpp = 32;
 | 
|          m_AlphaFlag = 2;
 | 
| -        m_Pitch = m_Width;
 | 
| -        if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) {
 | 
| -            return 0;
 | 
| -        }
 | 
| -        m_Pitch *= m_bpp;
 | 
| -        if (m_Pitch + 31 < m_Pitch) {
 | 
| +        pitch = m_Width;
 | 
| +        pitch *= m_bpp;
 | 
| +        pitch += 31;
 | 
| +        pitch /= 8;
 | 
| +        if (!pitch.IsValid()) {
 | 
|              return 0;
 | 
|          }
 | 
| -        m_Pitch += 31;
 | 
| -        m_Pitch = m_Pitch / 32 * 4;
 | 
| -        m_pMaskedLine = FX_Alloc(FX_BYTE, m_Pitch);
 | 
| +        m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
 | 
|      }
 | 
| +    m_Pitch = pitch.ValueOrDie();
 | 
|      return 1;
 | 
|  }
 | 
|  int	CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* pStream, FX_BOOL bHasMask,
 | 
| @@ -330,27 +317,23 @@ int	CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* p
 | 
|      if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) {
 | 
|          return 0;
 | 
|      }
 | 
| -    FX_DWORD src_pitch = m_bpc;
 | 
| -    if (m_bpc != 0 && m_nComponents != 0) {
 | 
| -        if (src_pitch > 0 && m_nComponents > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return 0;
 | 
| -        }
 | 
| -        src_pitch *= m_nComponents;
 | 
| -        if (src_pitch > 0 && (FX_DWORD)m_Width > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return 0;
 | 
| -        }
 | 
| -        src_pitch *= m_Width;
 | 
| -        if (src_pitch + 7 < src_pitch) {
 | 
| -            return 0;
 | 
| -        }
 | 
| -        src_pitch += 7;
 | 
| -        src_pitch /= 8;
 | 
| -        if (src_pitch > 0 && (FX_DWORD)m_Height > (unsigned)INT_MAX / src_pitch) {
 | 
| -            return 0;
 | 
| -        }
 | 
| +
 | 
| +    if (m_bpc == 0 || m_nComponents == 0) {
 | 
| +        return 0;
 | 
|      }
 | 
| +
 | 
| +    FX_SAFE_DWORD src_pitch = m_bpc;
 | 
| +    src_pitch *= m_nComponents;
 | 
| +    src_pitch *= m_Width;
 | 
| +    src_pitch += 7;
 | 
| +    src_pitch /= 8;
 | 
| +    src_pitch *= m_Height;
 | 
| +    if (!src_pitch.IsValid()) {
 | 
| +        return 0;
 | 
| +    }
 | 
| +
 | 
|      m_pStreamAcc = FX_NEW CPDF_StreamAcc;
 | 
| -    m_pStreamAcc->LoadAllData(pStream, FALSE, m_Height * src_pitch, TRUE);
 | 
| +    m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE);
 | 
|      if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) {
 | 
|          return 0;
 | 
|      }
 | 
| @@ -1182,16 +1165,35 @@ FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const
 | 
|  void CPDF_DIBSource::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
 | 
|                                          int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
 | 
|  {
 | 
| +    if (line < 0 || dest_scan == NULL || dest_bpp <= 0 ||
 | 
| +        dest_width <= 0 || clip_left < 0 || clip_width <= 0) {
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
|      FX_DWORD bpc = GetValidBpc();
 | 
|      FX_DWORD src_width = m_Width;
 | 
| -    FX_DWORD src_pitch = (src_width * bpc * m_nComponents + 7) / 8;
 | 
| +    FX_SAFE_DWORD pitch = src_width;
 | 
| +    pitch *= bpc;
 | 
| +    pitch *= m_nComponents;
 | 
| +    pitch += 7;
 | 
| +    pitch /= 8;
 | 
| +    if (!pitch.IsValid()) { 
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
|      FX_LPCBYTE pSrcLine = NULL;
 | 
|      if (m_pCachedBitmap) {
 | 
|          pSrcLine = m_pCachedBitmap->GetScanline(line);
 | 
|      } else if (m_pDecoder) {
 | 
|          pSrcLine = m_pDecoder->GetScanline(line);
 | 
|      } else {
 | 
| -        if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch) {
 | 
| +        FX_DWORD src_pitch = pitch.ValueOrDie();
 | 
| +        pitch *= (line+1);
 | 
| +        if (!pitch.IsValid()) { 
 | 
| +            return;
 | 
| +        }
 | 
| + 
 | 
| +        if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) {
 | 
|              pSrcLine = m_pStreamAcc->GetData() + line * src_pitch;
 | 
|          }
 | 
|      }
 | 
| @@ -1201,6 +1203,15 @@ void CPDF_DIBSource::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_
 | 
|          FXSYS_memset32(dest_scan, 0xff, dest_Bpp * clip_width);
 | 
|          return;
 | 
|      }
 | 
| +
 | 
| +    FX_SAFE_INT max_src_x = clip_left;
 | 
| +    max_src_x += clip_width - 1;
 | 
| +    max_src_x *= src_width;
 | 
| +    max_src_x /= dest_width;
 | 
| +    if (!max_src_x.IsValid()) {
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
|      CFX_FixedBufGrow<FX_BYTE, 128> temp(orig_Bpp);
 | 
|      if (bpc * m_nComponents == 1) {
 | 
|          FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0;
 | 
| 
 |