Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../include/fxcrt/fx_basic.h" | 7 #include "../../include/fxcrt/fx_basic.h" |
| 8 CFX_BasicArray::CFX_BasicArray(int unit_size, IFX_Allocator* pAllocator) | 8 CFX_BasicArray::CFX_BasicArray(int unit_size) |
| 9 : m_pAllocator(pAllocator) | 9 : m_pData(NULL) |
| 10 , m_pData(NULL) | |
| 11 , m_nSize(0) | 10 , m_nSize(0) |
| 12 , m_nMaxSize(0) | 11 , m_nMaxSize(0) |
| 13 , m_nGrowBy(0) | 12 , m_nGrowBy(0) |
| 14 { | 13 { |
| 15 if (unit_size < 0 || unit_size > (1 << 28)) { | 14 if (unit_size < 0 || unit_size > (1 << 28)) { |
| 16 m_nUnitSize = 4; | 15 m_nUnitSize = 4; |
| 17 } else { | 16 } else { |
| 18 m_nUnitSize = unit_size; | 17 m_nUnitSize = unit_size; |
| 19 } | 18 } |
| 20 } | 19 } |
| 21 CFX_BasicArray::~CFX_BasicArray() | 20 CFX_BasicArray::~CFX_BasicArray() |
| 22 { | 21 { |
| 23 FX_Allocator_Free(m_pAllocator, m_pData); | 22 FX_Free(m_pData); |
| 24 } | 23 } |
| 25 FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy) | 24 FX_BOOL CFX_BasicArray::SetSize(int nNewSize, int nGrowBy) |
| 26 { | 25 { |
| 27 if (nNewSize < 0 || nNewSize > (1 << 28) / m_nUnitSize) { | 26 if (nNewSize < 0 || nNewSize > (1 << 28) / m_nUnitSize) { |
| 28 if (m_pData != NULL) { | 27 if (m_pData != NULL) { |
| 29 FX_Allocator_Free(m_pAllocator, m_pData); | 28 FX_Free(m_pData); |
| 30 m_pData = NULL; | 29 m_pData = NULL; |
| 31 » » } | 30 } |
| 32 m_nSize = m_nMaxSize = 0; | 31 m_nSize = m_nMaxSize = 0; |
| 33 return FALSE; | 32 return FALSE; |
| 34 } | 33 } |
| 35 if (nGrowBy >= 0) { | 34 if (nGrowBy >= 0) { |
| 36 m_nGrowBy = nGrowBy; | 35 m_nGrowBy = nGrowBy; |
| 37 } | 36 } |
| 38 if (nNewSize == 0) { | 37 if (nNewSize == 0) { |
| 39 if (m_pData != NULL) { | 38 if (m_pData != NULL) { |
| 40 FX_Allocator_Free(m_pAllocator, m_pData); | 39 FX_Free(m_pData); |
| 41 m_pData = NULL; | 40 m_pData = NULL; |
| 42 } | 41 } |
| 43 m_nSize = m_nMaxSize = 0; | 42 m_nSize = m_nMaxSize = 0; |
| 44 } else if (m_pData == NULL) { | 43 } else if (m_pData == NULL) { |
| 45 m_pData = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, nNewSize * m_nUnitSi ze); | 44 m_pData = FX_Alloc(FX_BYTE, nNewSize * m_nUnitSize); |
|
palmer
2014/07/07 19:17:53
Potential integer overflow.
| |
| 46 if (!m_pData) { | 45 if (!m_pData) { |
| 47 m_nSize = m_nMaxSize = 0; | 46 m_nSize = m_nMaxSize = 0; |
| 48 return FALSE; | 47 return FALSE; |
| 49 } | 48 } |
| 50 FXSYS_memset32(m_pData, 0, nNewSize * m_nUnitSize); | 49 FXSYS_memset32(m_pData, 0, nNewSize * m_nUnitSize); |
|
palmer
2014/07/07 19:17:53
Integer overflow here and on line 53. You probably
Bo Xu
2014/07/08 19:22:16
Here should e handled by the check in line 26
On
| |
| 51 m_nSize = m_nMaxSize = nNewSize; | 50 m_nSize = m_nMaxSize = nNewSize; |
| 52 } else if (nNewSize <= m_nMaxSize) { | 51 } else if (nNewSize <= m_nMaxSize) { |
| 53 if (nNewSize > m_nSize) { | 52 if (nNewSize > m_nSize) { |
| 54 FXSYS_memset32(m_pData + m_nSize * m_nUnitSize, 0, (nNewSize - m_nSi ze) * m_nUnitSize); | 53 FXSYS_memset32(m_pData + m_nSize * m_nUnitSize, 0, (nNewSize - m_nSi ze) * m_nUnitSize); |
| 55 } | 54 } |
| 56 m_nSize = nNewSize; | 55 m_nSize = nNewSize; |
| 57 } else { | 56 } else { |
| 58 int nGrowBy = m_nGrowBy; | 57 int nGrowBy = m_nGrowBy; |
| 59 if (nGrowBy == 0) { | 58 if (nGrowBy == 0) { |
| 60 nGrowBy = m_nSize / 8; | 59 nGrowBy = m_nSize / 8; |
| 61 nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy); | 60 nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy); |
| 62 } | 61 } |
| 63 int nNewMax; | 62 int nNewMax; |
| 64 if (nNewSize < m_nMaxSize + nGrowBy) { | 63 if (nNewSize < m_nMaxSize + nGrowBy) { |
| 65 nNewMax = m_nMaxSize + nGrowBy; | 64 nNewMax = m_nMaxSize + nGrowBy; |
| 66 } else { | 65 } else { |
| 67 nNewMax = nNewSize; | 66 nNewMax = nNewSize; |
| 68 } | 67 } |
| 69 FX_LPBYTE pNewData = FX_Allocator_Realloc(m_pAllocator, FX_BYTE, m_pData , nNewMax * m_nUnitSize); | 68 FX_LPBYTE pNewData = FX_Realloc(FX_BYTE, m_pData, nNewMax * m_nUnitSize) ; |
|
palmer
2014/07/07 19:17:53
Potential integer overflow.
| |
| 70 if (pNewData == NULL) { | 69 if (pNewData == NULL) { |
| 71 return FALSE; | 70 return FALSE; |
| 72 } | 71 } |
| 73 FXSYS_memset32(pNewData + m_nSize * m_nUnitSize, 0, (nNewMax - m_nSize) * m_nUnitSize); | 72 FXSYS_memset32(pNewData + m_nSize * m_nUnitSize, 0, (nNewMax - m_nSize) * m_nUnitSize); |
|
palmer
2014/07/07 19:17:53
Potential integer overflow. Another reason to stic
Bo Xu
2014/07/08 19:31:25
Here the integer overflow has been checked by line
palmer
2014/07/08 22:24:13
I am not sure that is a sufficient check (as expla
| |
| 74 m_pData = pNewData; | 73 m_pData = pNewData; |
| 75 m_nSize = nNewSize; | 74 m_nSize = nNewSize; |
| 76 m_nMaxSize = nNewMax; | 75 m_nMaxSize = nNewMax; |
| 77 } | 76 } |
| 78 return TRUE; | 77 return TRUE; |
| 79 } | 78 } |
| 80 FX_BOOL CFX_BasicArray::Append(const CFX_BasicArray& src) | 79 FX_BOOL CFX_BasicArray::Append(const CFX_BasicArray& src) |
| 81 { | 80 { |
| 82 int nOldSize = m_nSize; | 81 int nOldSize = m_nSize; |
| 83 if (!SetSize(m_nSize + src.m_nSize, -1)) { | 82 if (!SetSize(m_nSize + src.m_nSize, -1)) { |
| 84 return FALSE; | 83 return FALSE; |
| 85 } | 84 } |
| 86 FXSYS_memcpy32(m_pData + nOldSize * m_nUnitSize, src.m_pData, src.m_nSize * m_nUnitSize); | 85 FXSYS_memcpy32(m_pData + nOldSize * m_nUnitSize, src.m_pData, src.m_nSize * m_nUnitSize); |
|
palmer
2014/07/07 19:17:53
Not sure if all this arithmetic is safe against ov
Bo Xu
2014/07/08 19:22:16
The function SetSize does the overflow check, so h
palmer
2014/07/08 22:24:13
I'm not sure. The expression "m_nSize + src.m_nSiz
| |
| 87 return TRUE; | 86 return TRUE; |
| 88 } | 87 } |
| 89 FX_BOOL CFX_BasicArray::Copy(const CFX_BasicArray& src) | 88 FX_BOOL CFX_BasicArray::Copy(const CFX_BasicArray& src) |
| 90 { | 89 { |
| 91 if (!SetSize(src.m_nSize, -1)) { | 90 if (!SetSize(src.m_nSize, -1)) { |
| 92 return FALSE; | 91 return FALSE; |
| 93 } | 92 } |
| 94 FXSYS_memcpy32(m_pData, src.m_pData, src.m_nSize * m_nUnitSize); | 93 FXSYS_memcpy32(m_pData, src.m_pData, src.m_nSize * m_nUnitSize); |
| 95 return TRUE; | 94 return TRUE; |
| 96 } | 95 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 FXSYS_memcpy32(m_pData + nStartIndex * m_nUnitSize, pNewArray->m_pData, pNew Array->m_nSize * m_nUnitSize); | 139 FXSYS_memcpy32(m_pData + nStartIndex * m_nUnitSize, pNewArray->m_pData, pNew Array->m_nSize * m_nUnitSize); |
| 141 return TRUE; | 140 return TRUE; |
| 142 } | 141 } |
| 143 const void* CFX_BasicArray::GetDataPtr(int index) const | 142 const void* CFX_BasicArray::GetDataPtr(int index) const |
| 144 { | 143 { |
| 145 if (index < 0 || index >= m_nSize || m_pData == NULL) { | 144 if (index < 0 || index >= m_nSize || m_pData == NULL) { |
| 146 return NULL; | 145 return NULL; |
| 147 } | 146 } |
| 148 return m_pData + index * m_nUnitSize; | 147 return m_pData + index * m_nUnitSize; |
| 149 } | 148 } |
| 150 CFX_BaseSegmentedArray::CFX_BaseSegmentedArray(int unit_size, int segment_units, int index_size, IFX_Allocator* pAllocator) | 149 CFX_BaseSegmentedArray::CFX_BaseSegmentedArray(int unit_size, int segment_units, int index_size) |
| 151 : m_pAllocator(pAllocator) | 150 : m_UnitSize(unit_size) |
| 152 , m_UnitSize(unit_size) | |
| 153 , m_SegmentSize(segment_units) | 151 , m_SegmentSize(segment_units) |
| 154 , m_IndexSize(index_size) | 152 , m_IndexSize(index_size) |
| 155 , m_IndexDepth(0) | 153 , m_IndexDepth(0) |
| 156 , m_DataSize(0) | 154 , m_DataSize(0) |
| 157 , m_pIndex(NULL) | 155 , m_pIndex(NULL) |
| 158 { | 156 { |
| 159 } | 157 } |
| 160 void CFX_BaseSegmentedArray::SetUnitSize(int unit_size, int segment_units, int i ndex_size) | 158 void CFX_BaseSegmentedArray::SetUnitSize(int unit_size, int segment_units, int i ndex_size) |
| 161 { | 159 { |
| 162 ASSERT(m_DataSize == 0); | 160 ASSERT(m_DataSize == 0); |
| 163 m_UnitSize = unit_size; | 161 m_UnitSize = unit_size; |
| 164 m_SegmentSize = segment_units; | 162 m_SegmentSize = segment_units; |
| 165 m_IndexSize = index_size; | 163 m_IndexSize = index_size; |
| 166 } | 164 } |
| 167 CFX_BaseSegmentedArray::~CFX_BaseSegmentedArray() | 165 CFX_BaseSegmentedArray::~CFX_BaseSegmentedArray() |
| 168 { | 166 { |
| 169 RemoveAll(); | 167 RemoveAll(); |
| 170 } | 168 } |
| 171 static void _ClearIndex(IFX_Allocator* pAllcator, int level, int size, void** pI ndex) | 169 static void _ClearIndex(int level, int size, void** pIndex) |
| 172 { | 170 { |
| 173 if (level == 0) { | 171 if (level == 0) { |
| 174 FX_Allocator_Free(pAllcator, pIndex); | 172 FX_Free(pIndex); |
| 175 return; | 173 return; |
| 176 } | 174 } |
| 177 for (int i = 0; i < size; i ++) { | 175 for (int i = 0; i < size; i++) { |
| 178 if (pIndex[i] == NULL) { | 176 if (pIndex[i] == NULL) { |
| 179 continue; | 177 continue; |
| 180 } | 178 } |
| 181 _ClearIndex(pAllcator, level - 1, size, (void**)pIndex[i]); | 179 _ClearIndex(level - 1, size, (void**)pIndex[i]); |
| 182 } | 180 } |
| 183 FX_Allocator_Free(pAllcator, pIndex); | 181 FX_Free(pIndex); |
| 184 } | 182 } |
| 185 void CFX_BaseSegmentedArray::RemoveAll() | 183 void CFX_BaseSegmentedArray::RemoveAll() |
| 186 { | 184 { |
| 187 if (m_pIndex == NULL) { | 185 if (m_pIndex == NULL) { |
| 188 return; | 186 return; |
| 189 } | 187 } |
| 190 _ClearIndex(m_pAllocator, m_IndexDepth, m_IndexSize, (void**)m_pIndex); | 188 _ClearIndex(m_IndexDepth, m_IndexSize, (void**)m_pIndex); |
| 191 m_pIndex = NULL; | 189 m_pIndex = NULL; |
| 192 m_IndexDepth = 0; | 190 m_IndexDepth = 0; |
| 193 m_DataSize = 0; | 191 m_DataSize = 0; |
| 194 } | 192 } |
| 195 void* CFX_BaseSegmentedArray::Add() | 193 void* CFX_BaseSegmentedArray::Add() |
| 196 { | 194 { |
| 197 if (m_DataSize % m_SegmentSize) { | 195 if (m_DataSize % m_SegmentSize) { |
| 198 return GetAt(m_DataSize ++); | 196 return GetAt(m_DataSize ++); |
| 199 } | 197 } |
| 200 void* pSegment = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_UnitSize * m_Se gmentSize); | 198 void* pSegment = FX_Alloc(FX_BYTE, m_UnitSize * m_SegmentSize); |
| 201 if (!pSegment) { | 199 if (!pSegment) { |
| 202 return NULL; | 200 return NULL; |
| 203 } | 201 } |
| 204 if (m_pIndex == NULL) { | 202 if (m_pIndex == NULL) { |
| 205 m_pIndex = pSegment; | 203 m_pIndex = pSegment; |
| 206 m_DataSize ++; | 204 m_DataSize ++; |
| 207 return pSegment; | 205 return pSegment; |
| 208 } | 206 } |
| 209 if (m_IndexDepth == 0) { | 207 if (m_IndexDepth == 0) { |
| 210 void** pIndex = (void**)FX_Allocator_Alloc(m_pAllocator, void*, m_IndexS ize); | 208 void** pIndex = (void**)FX_Alloc(void*, m_IndexSize); |
| 211 if (pIndex == NULL) { | 209 if (pIndex == NULL) { |
| 212 FX_Allocator_Free(m_pAllocator, pSegment); | 210 FX_Free(pSegment); |
| 213 return NULL; | 211 return NULL; |
| 214 } | 212 } |
| 215 FXSYS_memset32(pIndex, 0, sizeof(void*) * m_IndexSize); | 213 FXSYS_memset32(pIndex, 0, sizeof(void*) * m_IndexSize); |
| 216 pIndex[0] = m_pIndex; | 214 pIndex[0] = m_pIndex; |
| 217 pIndex[1] = pSegment; | 215 pIndex[1] = pSegment; |
| 218 m_pIndex = pIndex; | 216 m_pIndex = pIndex; |
| 219 m_DataSize ++; | 217 m_DataSize ++; |
| 220 m_IndexDepth ++; | 218 m_IndexDepth ++; |
| 221 return pSegment; | 219 return pSegment; |
| 222 } | 220 } |
| 223 int seg_index = m_DataSize / m_SegmentSize; | 221 int seg_index = m_DataSize / m_SegmentSize; |
| 224 if (seg_index % m_IndexSize) { | 222 if (seg_index % m_IndexSize) { |
| 225 void** pIndex = GetIndex(seg_index); | 223 void** pIndex = GetIndex(seg_index); |
| 226 pIndex[seg_index % m_IndexSize] = pSegment; | 224 pIndex[seg_index % m_IndexSize] = pSegment; |
| 227 m_DataSize ++; | 225 m_DataSize ++; |
| 228 return pSegment; | 226 return pSegment; |
| 229 } | 227 } |
| 230 int tree_size = 1; | 228 int tree_size = 1; |
| 231 int i; | 229 int i; |
| 232 for (i = 0; i < m_IndexDepth; i ++) { | 230 for (i = 0; i < m_IndexDepth; i ++) { |
| 233 tree_size *= m_IndexSize; | 231 tree_size *= m_IndexSize; |
| 234 } | 232 } |
| 235 if (m_DataSize == tree_size * m_SegmentSize) { | 233 if (m_DataSize == tree_size * m_SegmentSize) { |
| 236 void** pIndex = (void**)FX_Allocator_Alloc(m_pAllocator, void*, m_IndexS ize); | 234 void** pIndex = (void**)FX_Alloc(void*, m_IndexSize); |
| 237 if (pIndex == NULL) { | 235 if (pIndex == NULL) { |
| 238 FX_Allocator_Free(m_pAllocator, pSegment); | 236 FX_Free(pSegment); |
| 239 return NULL; | 237 return NULL; |
| 240 } | 238 } |
| 241 FXSYS_memset32(pIndex, 0, sizeof(void*) * m_IndexSize); | 239 FXSYS_memset32(pIndex, 0, sizeof(void*) * m_IndexSize); |
| 242 pIndex[0] = m_pIndex; | 240 pIndex[0] = m_pIndex; |
| 243 m_pIndex = pIndex; | 241 m_pIndex = pIndex; |
| 244 m_IndexDepth ++; | 242 m_IndexDepth ++; |
| 245 } else { | 243 } else { |
| 246 tree_size /= m_IndexSize; | 244 tree_size /= m_IndexSize; |
| 247 } | 245 } |
| 248 void** pSpot = (void**)m_pIndex; | 246 void** pSpot = (void**)m_pIndex; |
| 249 for (i = 1; i < m_IndexDepth; i ++) { | 247 for (i = 1; i < m_IndexDepth; i ++) { |
| 250 if (pSpot[seg_index / tree_size] == NULL) { | 248 if (pSpot[seg_index / tree_size] == NULL) { |
| 251 pSpot[seg_index / tree_size] = (void*)FX_Allocator_Alloc(m_pAllocato r, void*, m_IndexSize); | 249 pSpot[seg_index / tree_size] = (void*)FX_Alloc(void*, m_IndexSize); |
| 252 if (pSpot[seg_index / tree_size] == NULL) { | 250 if (pSpot[seg_index / tree_size] == NULL) { |
| 253 break; | 251 break; |
| 254 } | 252 } |
| 255 FXSYS_memset32(pSpot[seg_index / tree_size], 0, sizeof(void*) * m_In dexSize); | 253 FXSYS_memset32(pSpot[seg_index / tree_size], 0, sizeof(void*) * m_In dexSize); |
| 256 } | 254 } |
| 257 pSpot = (void**)pSpot[seg_index / tree_size]; | 255 pSpot = (void**)pSpot[seg_index / tree_size]; |
| 258 seg_index = seg_index % tree_size; | 256 seg_index = seg_index % tree_size; |
| 259 tree_size /= m_IndexSize; | 257 tree_size /= m_IndexSize; |
| 260 } | 258 } |
| 261 if (i < m_IndexDepth) { | 259 if (i < m_IndexDepth) { |
| 262 FX_Allocator_Free(m_pAllocator, pSegment); | 260 FX_Free(pSegment); |
| 263 RemoveAll(); | 261 RemoveAll(); |
| 264 return NULL; | 262 return NULL; |
| 265 } | 263 } |
| 266 pSpot[seg_index % m_IndexSize] = pSegment; | 264 pSpot[seg_index % m_IndexSize] = pSegment; |
| 267 m_DataSize ++; | 265 m_DataSize ++; |
| 268 return pSegment; | 266 return pSegment; |
| 269 } | 267 } |
| 270 void** CFX_BaseSegmentedArray::GetIndex(int seg_index) const | 268 void** CFX_BaseSegmentedArray::GetIndex(int seg_index) const |
| 271 { | 269 { |
| 272 ASSERT(m_IndexDepth != 0); | 270 ASSERT(m_IndexDepth != 0); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 for (int j = 0; j < m_UnitSize; j ++) { | 347 for (int j = 0; j < m_UnitSize; j ++) { |
| 350 pDest[j] = pSrc[j]; | 348 pDest[j] = pSrc[j]; |
| 351 } | 349 } |
| 352 } | 350 } |
| 353 int new_segs = (m_DataSize - count + m_SegmentSize - 1) / m_SegmentSize; | 351 int new_segs = (m_DataSize - count + m_SegmentSize - 1) / m_SegmentSize; |
| 354 int old_segs = (m_DataSize + m_SegmentSize - 1) / m_SegmentSize; | 352 int old_segs = (m_DataSize + m_SegmentSize - 1) / m_SegmentSize; |
| 355 if (new_segs < old_segs) { | 353 if (new_segs < old_segs) { |
| 356 if(m_IndexDepth) { | 354 if(m_IndexDepth) { |
| 357 for (i = new_segs; i < old_segs; i ++) { | 355 for (i = new_segs; i < old_segs; i ++) { |
| 358 void** pIndex = GetIndex(i); | 356 void** pIndex = GetIndex(i); |
| 359 FX_Allocator_Free(m_pAllocator, pIndex[i % m_IndexSize]); | 357 FX_Free(pIndex[i % m_IndexSize]); |
| 360 pIndex[i % m_IndexSize] = NULL; | 358 pIndex[i % m_IndexSize] = NULL; |
| 361 } | 359 } |
| 362 } else { | 360 } else { |
| 363 FX_Allocator_Free(m_pAllocator, m_pIndex); | 361 FX_Free(m_pIndex); |
| 364 m_pIndex = NULL; | 362 m_pIndex = NULL; |
| 365 } | 363 } |
| 366 } | 364 } |
| 367 m_DataSize -= count; | 365 m_DataSize -= count; |
| 368 } | 366 } |
| OLD | NEW |