diff options
author | Chris Palmer <palmer@google.com> | 2014-07-23 14:56:29 -0700 |
---|---|---|
committer | Bo Xu <bo_xu@foxitsoftware.com> | 2014-08-07 17:41:59 -0700 |
commit | a6d03543ffaaa8487325d75e8841f9b0f3a1f10a (patch) | |
tree | 12f820fdd68e4927a3b5c8a23be88780e79cb136 | |
parent | ab6dd1460effcdc8d9ca8e30a8a6c6909adf05a2 (diff) | |
download | pdfium-a6d03543ffaaa8487325d75e8841f9b0f3a1f10a.tar.xz |
Check for integer overflow in CFX_BasicArray.
BUG=384662
R=bo_xu@foxitsoftware.com, rsesek@chromium.org
Review URL: https://codereview.chromium.org/411033003
-rw-r--r-- | core/src/fxcrt/fx_basic_array.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/core/src/fxcrt/fx_basic_array.cpp b/core/src/fxcrt/fx_basic_array.cpp index aae3a1fa1c..3de3d99ac1 100644 --- a/core/src/fxcrt/fx_basic_array.cpp +++ b/core/src/fxcrt/fx_basic_array.cpp @@ -5,6 +5,8 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../include/fxcrt/fx_basic.h" +#include "../../../third_party/numerics/safe_math.h" + CFX_BasicArray::CFX_BasicArray(int unit_size, IFX_Allocator* pAllocator) : m_pAllocator(pAllocator) , m_pData(NULL) @@ -24,25 +26,23 @@ CFX_BasicArray::~CFX_BasicArray() } FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy) { - if (nNewSize < 0 || nNewSize > (1 << 28) / m_nUnitSize) { - if (m_pData != NULL) { - FX_Allocator_Free(m_pAllocator, m_pData); - m_pData = NULL; - } + if (nNewSize <= 0) { + FX_Free(m_pData); + m_pData = NULL; m_nSize = m_nMaxSize = 0; - return FALSE; - } - if (nGrowBy >= 0) { - m_nGrowBy = nGrowBy; + return 0 == nNewSize; } - if (nNewSize == 0) { - if (m_pData != NULL) { - FX_Allocator_Free(m_pAllocator, m_pData); - m_pData = NULL; + + m_nGrowBy = nGrowBy >= 0 ? nGrowBy : m_nGrowBy; + + if (m_pData == NULL) { + base::CheckedNumeric<int> totalSize = nNewSize; + totalSize *= m_nUnitSize; + if (!totalSize.IsValid()) { + m_nSize = m_nMaxSize = 0; + return FALSE; } - m_nSize = m_nMaxSize = 0; - } else if (m_pData == NULL) { - m_pData = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, nNewSize * m_nUnitSize); + m_pData = FX_Alloc(FX_BYTE, totalSize.ValueOrDie()); if (!m_pData) { m_nSize = m_nMaxSize = 0; return FALSE; @@ -66,7 +66,13 @@ FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy) } else { nNewMax = nNewSize; } - FX_LPBYTE pNewData = FX_Allocator_Realloc(m_pAllocator, FX_BYTE, m_pData, nNewMax * m_nUnitSize); + + base::CheckedNumeric<int> totalSize = nNewMax; + totalSize *= m_nUnitSize; + if (!totalSize.IsValid() || nNewMax < m_nSize) { + return FALSE; + } + FX_LPBYTE pNewData = FX_Realloc(FX_BYTE, m_pData, totalSize.ValueOrDie()); if (pNewData == NULL) { return FALSE; } @@ -80,9 +86,12 @@ FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy) FX_BOOL CFX_BasicArray::Append(const CFX_BasicArray& src) { int nOldSize = m_nSize; - if (!SetSize(m_nSize + src.m_nSize, -1)) { + base::CheckedNumeric<int> newSize = m_nSize; + newSize += src.m_nSize; + if (m_nUnitSize != src.m_nUnitSize || !newSize.IsValid() || !SetSize(newSize.ValueOrDie(), -1)) { return FALSE; } + FXSYS_memcpy32(m_pData + nOldSize * m_nUnitSize, src.m_pData, src.m_nSize * m_nUnitSize); return TRUE; } |