Check for integer overflow in CFX_BasicArray.
authorChris Palmer <palmer@google.com>
Wed, 23 Jul 2014 21:56:29 +0000 (14:56 -0700)
committerChris Palmer <palmer@google.com>
Wed, 23 Jul 2014 21:56:29 +0000 (14:56 -0700)
BUG=384662
R=bo_xu@foxitsoftware.com, rsesek@chromium.org

Review URL: https://codereview.chromium.org/411033003

core/src/fxcrt/fx_basic_array.cpp

index 55d27b0..f65d8ef 100644 (file)
@@ -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)
     : m_pData(NULL)
     , m_nSize(0)
@@ -23,25 +25,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_Free(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_Free(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_Alloc(FX_BYTE, nNewSize * m_nUnitSize);
+        m_pData = FX_Alloc(FX_BYTE, totalSize.ValueOrDie());
         if (!m_pData) {
             m_nSize = m_nMaxSize = 0;
             return FALSE;
@@ -64,7 +64,13 @@ FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy)
         } else {
             nNewMax = nNewSize;
         }
-        FX_LPBYTE pNewData = FX_Realloc(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;
         }
@@ -78,9 +84,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;
 }