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 |