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; |