Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(747)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp

Issue 2241153002: Clean up CPDF_HintTables. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_hint_tables.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 PDFium Authors. All rights reserved. 1 // Copyright 2016 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 "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h" 7 #include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h"
8 8
9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
9 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h"
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
14 #include "core/fxcrt/include/fx_safe_types.h" 15 #include "core/fxcrt/include/fx_safe_types.h"
15 16
16 namespace { 17 namespace {
17 18
18 bool CanReadFromBitStream(const CFX_BitStream* hStream, 19 bool CanReadFromBitStream(const CFX_BitStream* hStream,
19 const FX_SAFE_UINT32& num_bits) { 20 const FX_SAFE_UINT32& bits) {
20 return num_bits.IsValid() && 21 return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie();
21 hStream->BitsRemaining() >= num_bits.ValueOrDie();
22 } 22 }
23 23
24 } // namespace 24 } // namespace
25 25
26 CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail, 26 CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail,
27 CPDF_Dictionary* pLinearized) 27 CPDF_Dictionary* pLinearized)
28 : m_pDataAvail(pDataAvail), 28 : m_pDataAvail(pDataAvail),
29 m_pLinearizedDict(pLinearized), 29 m_pLinearizedDict(pLinearized),
30 m_nFirstPageSharedObjs(0), 30 m_nFirstPageSharedObjs(0),
31 m_szFirstPageObjOffset(0) {} 31 m_szFirstPageObjOffset(0) {
32 ASSERT(m_pLinearizedDict);
33 }
32 34
33 CPDF_HintTables::~CPDF_HintTables() { 35 CPDF_HintTables::~CPDF_HintTables() {}
34 m_dwDeltaNObjsArray.RemoveAll();
35 m_dwNSharedObjsArray.RemoveAll();
36 m_dwSharedObjNumArray.RemoveAll();
37 m_dwIdentifierArray.RemoveAll();
38 }
39 36
40 uint32_t CPDF_HintTables::GetItemLength( 37 uint32_t CPDF_HintTables::GetItemLength(
41 int index, 38 int index,
42 const std::vector<FX_FILESIZE>& szArray) { 39 const std::vector<FX_FILESIZE>& szArray) {
43 if (index < 0 || szArray.size() < 2 || 40 if (index < 0 || szArray.size() < 2 ||
44 static_cast<size_t>(index) > szArray.size() - 2 || 41 static_cast<size_t>(index) > szArray.size() - 2 ||
45 szArray[index] > szArray[index + 1]) { 42 szArray[index] > szArray[index + 1]) {
46 return 0; 43 return 0;
47 } 44 }
48 return szArray[index + 1] - szArray[index]; 45 return szArray[index + 1] - szArray[index];
49 } 46 }
50 47
51 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { 48 bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
52 if (!hStream || hStream->IsEOF()) 49 if (!hStream || hStream->IsEOF())
53 return FALSE; 50 return false;
54 51
55 int nStreamOffset = ReadPrimaryHintStreamOffset(); 52 int nStreamOffset = ReadPrimaryHintStreamOffset();
56 int nStreamLen = ReadPrimaryHintStreamLength(); 53 int nStreamLen = ReadPrimaryHintStreamLength();
57 if (nStreamOffset < 0 || nStreamLen < 1) 54 if (nStreamOffset < 0 || nStreamLen < 1)
58 return FALSE; 55 return false;
59 56
60 const uint32_t kHeaderSize = 288; 57 const uint32_t kHeaderSize = 288;
61 if (hStream->BitsRemaining() < kHeaderSize) 58 if (hStream->BitsRemaining() < kHeaderSize)
62 return FALSE; 59 return false;
63 60
64 // Item 1: The least number of objects in a page. 61 // Item 1: The least number of objects in a page.
65 uint32_t dwObjLeastNum = hStream->GetBits(32); 62 uint32_t dwObjLeastNum = hStream->GetBits(32);
66 63
67 // Item 2: The location of the first page's page object. 64 // Item 2: The location of the first page's page object.
68 uint32_t dwFirstObjLoc = hStream->GetBits(32); 65 uint32_t dwFirstObjLoc = hStream->GetBits(32);
69 if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) { 66 if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) {
70 FX_SAFE_UINT32 safeLoc = pdfium::base::checked_cast<uint32_t>(nStreamLen); 67 FX_SAFE_UINT32 safeLoc = pdfium::base::checked_cast<uint32_t>(nStreamLen);
71 safeLoc += dwFirstObjLoc; 68 safeLoc += dwFirstObjLoc;
72 if (!safeLoc.IsValid()) 69 if (!safeLoc.IsValid())
73 return FALSE; 70 return false;
74 m_szFirstPageObjOffset = 71 m_szFirstPageObjOffset =
75 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); 72 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie());
76 } else { 73 } else {
77 m_szFirstPageObjOffset = 74 m_szFirstPageObjOffset =
78 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); 75 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc);
79 } 76 }
80 77
81 // Item 3: The number of bits needed to represent the difference 78 // Item 3: The number of bits needed to represent the difference
82 // between the greatest and least number of objects in a page. 79 // between the greatest and least number of objects in a page.
83 uint32_t dwDeltaObjectsBits = hStream->GetBits(16); 80 uint32_t dwDeltaObjectsBits = hStream->GetBits(16);
(...skipping 22 matching lines...) Expand all
106 // where in the page's content stream the object is first referenced. 103 // where in the page's content stream the object is first referenced.
107 uint32_t dwSharedNumeratorBits = hStream->GetBits(16); 104 uint32_t dwSharedNumeratorBits = hStream->GetBits(16);
108 105
109 // Item 13: Skip Item 13 which has 16 bits. 106 // Item 13: Skip Item 13 which has 16 bits.
110 hStream->SkipBits(16); 107 hStream->SkipBits(16);
111 108
112 // The maximum number of bits allowed to represent the greatest number of 109 // The maximum number of bits allowed to represent the greatest number of
113 // shared object references. 2^39 should be more than enough. 110 // shared object references. 2^39 should be more than enough.
114 constexpr uint32_t kMaxSharedObjBits = 39; 111 constexpr uint32_t kMaxSharedObjBits = 39;
115 if (dwSharedObjBits > kMaxSharedObjBits) 112 if (dwSharedObjBits > kMaxSharedObjBits)
116 return FALSE; 113 return false;
117 114
118 CPDF_Object* pPageNum = m_pLinearizedDict->GetDirectObjectBy("N"); 115 const int nPages = GetNumberOfPages();
119 int nPages = pPageNum ? pPageNum->GetInteger() : 0;
120 if (nPages < 1) 116 if (nPages < 1)
121 return FALSE; 117 return false;
122 118
119 const uint32_t dwPages = pdfium::base::checked_cast<uint32_t>(nPages);
123 FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits; 120 FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits;
124 required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); 121 required_bits *= dwPages;
125 if (!CanReadFromBitStream(hStream, required_bits)) 122 if (!CanReadFromBitStream(hStream, required_bits))
126 return FALSE; 123 return false;
127 124
128 for (int i = 0; i < nPages; ++i) { 125 for (int i = 0; i < nPages; ++i) {
129 FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); 126 FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
130 safeDeltaObj += dwObjLeastNum; 127 safeDeltaObj += dwObjLeastNum;
131 if (!safeDeltaObj.IsValid()) 128 if (!safeDeltaObj.IsValid())
132 return FALSE; 129 return false;
133 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); 130 m_dwDeltaNObjsArray.push_back(safeDeltaObj.ValueOrDie());
134 } 131 }
135 hStream->ByteAlign(); 132 hStream->ByteAlign();
136 133
137 required_bits = dwDeltaPageLenBits; 134 required_bits = dwDeltaPageLenBits;
138 required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); 135 required_bits *= dwPages;
139 if (!CanReadFromBitStream(hStream, required_bits)) 136 if (!CanReadFromBitStream(hStream, required_bits))
140 return FALSE; 137 return false;
141 138
142 CFX_ArrayTemplate<uint32_t> dwPageLenArray; 139 CFX_ArrayTemplate<uint32_t> dwPageLenArray;
143 for (int i = 0; i < nPages; ++i) { 140 for (int i = 0; i < nPages; ++i) {
144 FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits); 141 FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits);
145 safePageLen += dwPageLeastLen; 142 safePageLen += dwPageLeastLen;
146 if (!safePageLen.IsValid()) 143 if (!safePageLen.IsValid())
147 return FALSE; 144 return false;
148 dwPageLenArray.Add(safePageLen.ValueOrDie()); 145 dwPageLenArray.Add(safePageLen.ValueOrDie());
149 } 146 }
150 147
151 CPDF_Object* pOffsetE = m_pLinearizedDict->GetDirectObjectBy("E"); 148 int nOffsetE = GetEndOfFirstPageOffset();
152 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1;
153 if (nOffsetE < 0) 149 if (nOffsetE < 0)
154 return FALSE; 150 return false;
155 151
156 CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P"); 152 int nFirstPageNum = GetFirstPageNumber();
157 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
158 for (int i = 0; i < nPages; ++i) { 153 for (int i = 0; i < nPages; ++i) {
159 if (i == nFirstPageNum) { 154 if (i == nFirstPageNum) {
160 m_szPageOffsetArray.push_back(m_szFirstPageObjOffset); 155 m_szPageOffsetArray.push_back(m_szFirstPageObjOffset);
161 } else if (i == nFirstPageNum + 1) { 156 } else if (i == nFirstPageNum + 1) {
162 if (i == 1) { 157 if (i == 1) {
163 m_szPageOffsetArray.push_back(nOffsetE); 158 m_szPageOffsetArray.push_back(nOffsetE);
164 } else { 159 } else {
165 m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] + 160 m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] +
166 dwPageLenArray[i - 2]); 161 dwPageLenArray[i - 2]);
167 } 162 }
168 } else { 163 } else {
169 if (i == 0) { 164 if (i == 0) {
170 m_szPageOffsetArray.push_back(nOffsetE); 165 m_szPageOffsetArray.push_back(nOffsetE);
171 } else { 166 } else {
172 m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] + 167 m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] +
173 dwPageLenArray[i - 1]); 168 dwPageLenArray[i - 1]);
174 } 169 }
175 } 170 }
176 } 171 }
177 172
178 if (nPages > 0) { 173 m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] +
Lei Zhang 2016/08/15 05:50:55 Always true. See line 120.
179 m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] + 174 dwPageLenArray[nPages - 1]);
180 dwPageLenArray[nPages - 1]);
181 }
182 hStream->ByteAlign(); 175 hStream->ByteAlign();
183 176
184 // Number of shared objects. 177 // Number of shared objects.
185 required_bits = dwSharedObjBits; 178 required_bits = dwSharedObjBits;
186 required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); 179 required_bits *= dwPages;
187 if (!CanReadFromBitStream(hStream, required_bits)) 180 if (!CanReadFromBitStream(hStream, required_bits))
188 return FALSE; 181 return false;
189 182
190 for (int i = 0; i < nPages; i++) 183 for (int i = 0; i < nPages; i++)
191 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); 184 m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits));
192 hStream->ByteAlign(); 185 hStream->ByteAlign();
193 186
194 // Array of identifiers, size = nshared_objects. 187 // Array of identifiers, size = nshared_objects.
195 for (int i = 0; i < nPages; i++) { 188 for (int i = 0; i < nPages; i++) {
196 required_bits = dwSharedIdBits; 189 required_bits = dwSharedIdBits;
197 required_bits *= m_dwNSharedObjsArray[i]; 190 required_bits *= m_dwNSharedObjsArray[i];
198 if (!CanReadFromBitStream(hStream, required_bits)) 191 if (!CanReadFromBitStream(hStream, required_bits))
199 return FALSE; 192 return false;
200 193
201 for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++) 194 for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++)
202 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); 195 m_dwIdentifierArray.push_back(hStream->GetBits(dwSharedIdBits));
203 } 196 }
204 hStream->ByteAlign(); 197 hStream->ByteAlign();
205 198
206 for (int i = 0; i < nPages; i++) { 199 for (int i = 0; i < nPages; i++) {
207 FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i]; 200 FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i];
208 safeSize *= dwSharedNumeratorBits; 201 safeSize *= dwSharedNumeratorBits;
209 if (!CanReadFromBitStream(hStream, safeSize)) 202 if (!CanReadFromBitStream(hStream, safeSize))
210 return FALSE; 203 return false;
211 204
212 hStream->SkipBits(safeSize.ValueOrDie()); 205 hStream->SkipBits(safeSize.ValueOrDie());
213 } 206 }
214 hStream->ByteAlign(); 207 hStream->ByteAlign();
215 208
216 FX_SAFE_UINT32 safeTotalPageLen = 209 FX_SAFE_UINT32 safeTotalPageLen = dwPages;
217 pdfium::base::checked_cast<uint32_t>(nPages);
218 safeTotalPageLen *= dwDeltaPageLenBits; 210 safeTotalPageLen *= dwDeltaPageLenBits;
219 if (!CanReadFromBitStream(hStream, safeTotalPageLen)) 211 if (!CanReadFromBitStream(hStream, safeTotalPageLen))
220 return FALSE; 212 return false;
221 213
222 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); 214 hStream->SkipBits(safeTotalPageLen.ValueOrDie());
223 hStream->ByteAlign(); 215 hStream->ByteAlign();
224 return TRUE; 216 return true;
225 } 217 }
226 218
227 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, 219 bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
228 uint32_t offset) { 220 uint32_t offset) {
229 if (!hStream || hStream->IsEOF()) 221 if (!hStream || hStream->IsEOF())
230 return FALSE; 222 return false;
231 223
232 int nStreamOffset = ReadPrimaryHintStreamOffset(); 224 int nStreamOffset = ReadPrimaryHintStreamOffset();
233 int nStreamLen = ReadPrimaryHintStreamLength(); 225 int nStreamLen = ReadPrimaryHintStreamLength();
234 if (nStreamOffset < 0 || nStreamLen < 1) 226 if (nStreamOffset < 0 || nStreamLen < 1)
235 return FALSE; 227 return false;
236 228
237 FX_SAFE_UINT32 bit_offset = offset; 229 FX_SAFE_UINT32 bit_offset = offset;
238 bit_offset *= 8; 230 bit_offset *= 8;
239 if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) 231 if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie())
240 return FALSE; 232 return false;
241 hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); 233 hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos());
242 234
243 const uint32_t kHeaderSize = 192; 235 const uint32_t kHeaderSize = 192;
244 if (hStream->BitsRemaining() < kHeaderSize) 236 if (hStream->BitsRemaining() < kHeaderSize)
245 return FALSE; 237 return false;
246 238
247 // Item 1: The object number of the first object in the shared objects 239 // Item 1: The object number of the first object in the shared objects
248 // section. 240 // section.
249 uint32_t dwFirstSharedObjNum = hStream->GetBits(32); 241 uint32_t dwFirstSharedObjNum = hStream->GetBits(32);
250 242
251 // Item 2: The location of the first object in the shared objects section. 243 // Item 2: The location of the first object in the shared objects section.
252 uint32_t dwFirstSharedObjLoc = hStream->GetBits(32); 244 uint32_t dwFirstSharedObjLoc = hStream->GetBits(32);
253 if (dwFirstSharedObjLoc > static_cast<uint32_t>(nStreamOffset)) 245 if (dwFirstSharedObjLoc > static_cast<uint32_t>(nStreamOffset))
254 dwFirstSharedObjLoc += nStreamLen; 246 dwFirstSharedObjLoc += nStreamLen;
255 247
256 // Item 3: The number of shared object entries for the first page. 248 // Item 3: The number of shared object entries for the first page.
257 m_nFirstPageSharedObjs = hStream->GetBits(32); 249 m_nFirstPageSharedObjs = hStream->GetBits(32);
258 250
259 // Item 4: The number of shared object entries for the shared objects 251 // Item 4: The number of shared object entries for the shared objects
260 // section, including the number of shared object entries for the first page. 252 // section, including the number of shared object entries for the first page.
261 uint32_t dwSharedObjTotal = hStream->GetBits(32); 253 uint32_t dwSharedObjTotal = hStream->GetBits(32);
262 254
263 // Item 5: The number of bits needed to represent the greatest number of 255 // Item 5: The number of bits needed to represent the greatest number of
264 // objects in a shared object group. Skipped. 256 // objects in a shared object group. Skipped.
265 hStream->SkipBits(16); 257 hStream->SkipBits(16);
266 258
267 // Item 6: The least length of a shared object group in bytes. 259 // Item 6: The least length of a shared object group in bytes.
268 uint32_t dwGroupLeastLen = hStream->GetBits(32); 260 uint32_t dwGroupLeastLen = hStream->GetBits(32);
269 261
270 // Item 7: The number of bits needed to represent the difference between the 262 // Item 7: The number of bits needed to represent the difference between the
271 // greatest and least length of a shared object group, in bytes. 263 // greatest and least length of a shared object group, in bytes.
272 uint32_t dwDeltaGroupLen = hStream->GetBits(16); 264 uint32_t dwDeltaGroupLen = hStream->GetBits(16);
273 CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O"); 265
274 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; 266 int nFirstPageObjNum = GetFirstPageObjectNumber();
275 if (nFirstPageObjNum < 0) 267 if (nFirstPageObjNum < 0)
276 return FALSE; 268 return false;
277 269
278 uint32_t dwPrevObjLen = 0; 270 uint32_t dwPrevObjLen = 0;
279 uint32_t dwCurObjLen = 0; 271 uint32_t dwCurObjLen = 0;
280 FX_SAFE_UINT32 required_bits = dwSharedObjTotal; 272 FX_SAFE_UINT32 required_bits = dwSharedObjTotal;
281 required_bits *= dwDeltaGroupLen; 273 required_bits *= dwDeltaGroupLen;
282 if (!CanReadFromBitStream(hStream, required_bits)) 274 if (!CanReadFromBitStream(hStream, required_bits))
283 return FALSE; 275 return false;
284 276
285 for (uint32_t i = 0; i < dwSharedObjTotal; ++i) { 277 for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
286 dwPrevObjLen = dwCurObjLen; 278 dwPrevObjLen = dwCurObjLen;
287 FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen); 279 FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen);
288 safeObjLen += dwGroupLeastLen; 280 safeObjLen += dwGroupLeastLen;
289 if (!safeObjLen.IsValid()) 281 if (!safeObjLen.IsValid())
290 return FALSE; 282 return false;
291 283
292 dwCurObjLen = safeObjLen.ValueOrDie(); 284 dwCurObjLen = safeObjLen.ValueOrDie();
293 if (i < m_nFirstPageSharedObjs) { 285 if (i < m_nFirstPageSharedObjs) {
294 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); 286 m_dwSharedObjNumArray.push_back(nFirstPageObjNum + i);
295 if (i == 0) 287 if (i == 0)
296 m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset); 288 m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset);
297 } else { 289 } else {
298 FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum; 290 FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum;
299 safeObjNum += i - m_nFirstPageSharedObjs; 291 safeObjNum += i - m_nFirstPageSharedObjs;
300 if (!safeObjNum.IsValid()) 292 if (!safeObjNum.IsValid())
301 return FALSE; 293 return false;
302 294
303 m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); 295 m_dwSharedObjNumArray.push_back(safeObjNum.ValueOrDie());
304 if (i == m_nFirstPageSharedObjs) { 296 if (i == m_nFirstPageSharedObjs) {
305 FX_SAFE_FILESIZE safeLoc = dwFirstSharedObjLoc; 297 FX_SAFE_FILESIZE safeLoc = dwFirstSharedObjLoc;
306 if (!safeLoc.IsValid()) 298 if (!safeLoc.IsValid())
307 return FALSE; 299 return false;
308 300
309 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); 301 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
310 } 302 }
311 } 303 }
312 304
313 if (i != 0 && i != m_nFirstPageSharedObjs) { 305 if (i != 0 && i != m_nFirstPageSharedObjs) {
314 FX_SAFE_FILESIZE safeLoc = dwPrevObjLen; 306 FX_SAFE_FILESIZE safeLoc = dwPrevObjLen;
315 safeLoc += m_szSharedObjOffsetArray[i - 1]; 307 safeLoc += m_szSharedObjOffsetArray[i - 1];
316 if (!safeLoc.IsValid()) 308 if (!safeLoc.IsValid())
317 return FALSE; 309 return false;
318 310
319 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); 311 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
320 } 312 }
321 } 313 }
322 314
323 if (dwSharedObjTotal > 0) { 315 if (dwSharedObjTotal > 0) {
324 FX_SAFE_FILESIZE safeLoc = dwCurObjLen; 316 FX_SAFE_FILESIZE safeLoc = dwCurObjLen;
325 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; 317 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
326 if (!safeLoc.IsValid()) 318 if (!safeLoc.IsValid())
327 return FALSE; 319 return false;
328 320
329 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); 321 m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
330 } 322 }
331 323
332 hStream->ByteAlign(); 324 hStream->ByteAlign();
333 if (hStream->BitsRemaining() < dwSharedObjTotal) 325 if (hStream->BitsRemaining() < dwSharedObjTotal)
334 return FALSE; 326 return false;
335 327
336 hStream->SkipBits(dwSharedObjTotal); 328 hStream->SkipBits(dwSharedObjTotal);
337 hStream->ByteAlign(); 329 hStream->ByteAlign();
338 return TRUE; 330 return true;
339 } 331 }
340 332
341 FX_BOOL CPDF_HintTables::GetPagePos(int index, 333 bool CPDF_HintTables::GetPagePos(int index,
342 FX_FILESIZE& szPageStartPos, 334 FX_FILESIZE* szPageStartPos,
343 FX_FILESIZE& szPageLength, 335 FX_FILESIZE* szPageLength,
344 uint32_t& dwObjNum) { 336 uint32_t* dwObjNum) {
345 if (!m_pLinearizedDict) 337 *szPageStartPos = m_szPageOffsetArray[index];
346 return FALSE; 338 *szPageLength = GetItemLength(index, m_szPageOffsetArray);
347 339
348 szPageStartPos = m_szPageOffsetArray[index]; 340 int nFirstPageObjNum = GetFirstPageObjectNumber();
349 szPageLength = GetItemLength(index, m_szPageOffsetArray); 341 if (nFirstPageObjNum < 0)
342 return false;
350 343
351 CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P"); 344 int nFirstPageNum = GetFirstPageNumber();
352 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
353
354 CPDF_Object* pFirstPageObjNum = m_pLinearizedDict->GetDirectObjectBy("O");
355 if (!pFirstPageObjNum)
356 return FALSE;
357
358 int nFirstPageObjNum = pFirstPageObjNum->GetInteger();
359 if (index == nFirstPageNum) { 345 if (index == nFirstPageNum) {
360 dwObjNum = nFirstPageObjNum; 346 *dwObjNum = nFirstPageObjNum;
361 return TRUE; 347 return true;
362 } 348 }
363 349
364 // The object number of remaining pages starts from 1. 350 // The object number of remaining pages starts from 1.
365 dwObjNum = 1; 351 *dwObjNum = 1;
366 for (int i = 0; i < index; ++i) { 352 for (int i = 0; i < index; ++i) {
367 if (i == nFirstPageNum) 353 if (i == nFirstPageNum)
368 continue; 354 continue;
369 dwObjNum += m_dwDeltaNObjsArray[i]; 355 *dwObjNum += m_dwDeltaNObjsArray[i];
370 } 356 }
371 return TRUE; 357 return true;
372 } 358 }
373 359
374 CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( 360 CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(
375 int index, 361 int index,
376 CPDF_DataAvail::DownloadHints* pHints) { 362 CPDF_DataAvail::DownloadHints* pHints) {
377 if (!m_pLinearizedDict || !pHints) 363 if (!pHints)
378 return CPDF_DataAvail::DataError; 364 return CPDF_DataAvail::DataError;
379 365
380 CPDF_Object* pFirstAvailPage = m_pLinearizedDict->GetDirectObjectBy("P"); 366 int nFirstAvailPage = GetFirstPageNumber();
381 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0;
382 if (index == nFirstAvailPage) 367 if (index == nFirstAvailPage)
383 return CPDF_DataAvail::DataAvailable; 368 return CPDF_DataAvail::DataAvailable;
384 369
385 uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray); 370 uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray);
386 // If two pages have the same offset, it should be treated as an error. 371 // If two pages have the same offset, it should be treated as an error.
387 if (!dwLength) 372 if (!dwLength)
388 return CPDF_DataAvail::DataError; 373 return CPDF_DataAvail::DataError;
389 374
390 if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints)) 375 if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints))
391 return CPDF_DataAvail::DataNotAvailable; 376 return CPDF_DataAvail::DataNotAvailable;
392 377
393 // Download data of shared objects in the page. 378 // Download data of shared objects in the page.
394 uint32_t offset = 0; 379 uint32_t offset = 0;
395 for (int i = 0; i < index; ++i) 380 for (int i = 0; i < index; ++i)
396 offset += m_dwNSharedObjsArray[i]; 381 offset += m_dwNSharedObjsArray[i];
397 382
398 CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O"); 383 int nFirstPageObjNum = GetFirstPageObjectNumber();
399 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
400 if (nFirstPageObjNum < 0) 384 if (nFirstPageObjNum < 0)
401 return CPDF_DataAvail::DataError; 385 return CPDF_DataAvail::DataError;
402 386
403 uint32_t dwIndex = 0; 387 uint32_t dwIndex = 0;
404 uint32_t dwObjNum = 0; 388 uint32_t dwObjNum = 0;
405 for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) { 389 for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
406 dwIndex = m_dwIdentifierArray[offset + j]; 390 dwIndex = m_dwIdentifierArray[offset + j];
407 if (dwIndex >= static_cast<uint32_t>(m_dwSharedObjNumArray.GetSize())) 391 if (dwIndex >= m_dwSharedObjNumArray.size())
408 return CPDF_DataAvail::DataNotAvailable; 392 return CPDF_DataAvail::DataNotAvailable;
409 393
410 dwObjNum = m_dwSharedObjNumArray[dwIndex]; 394 dwObjNum = m_dwSharedObjNumArray[dwIndex];
411 if (dwObjNum >= static_cast<uint32_t>(nFirstPageObjNum) && 395 if (dwObjNum >= static_cast<uint32_t>(nFirstPageObjNum) &&
412 dwObjNum < 396 dwObjNum <
413 static_cast<uint32_t>(nFirstPageObjNum) + m_nFirstPageSharedObjs) { 397 static_cast<uint32_t>(nFirstPageObjNum) + m_nFirstPageSharedObjs) {
414 continue; 398 continue;
415 } 399 }
416 400
417 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); 401 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
418 // If two objects have the same offset, it should be treated as an error. 402 // If two objects have the same offset, it should be treated as an error.
419 if (!dwLength) 403 if (!dwLength)
420 return CPDF_DataAvail::DataError; 404 return CPDF_DataAvail::DataError;
421 405
422 if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, 406 if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength,
423 pHints)) { 407 pHints)) {
424 return CPDF_DataAvail::DataNotAvailable; 408 return CPDF_DataAvail::DataNotAvailable;
425 } 409 }
426 } 410 }
427 return CPDF_DataAvail::DataAvailable; 411 return CPDF_DataAvail::DataAvailable;
428 } 412 }
429 413
430 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { 414 bool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
431 if (!pHintStream || !m_pLinearizedDict) 415 if (!pHintStream)
432 return FALSE; 416 return false;
433 417
434 CPDF_Dictionary* pDict = pHintStream->GetDict(); 418 CPDF_Dictionary* pDict = pHintStream->GetDict();
435 CPDF_Object* pOffset = pDict ? pDict->GetObjectBy("S") : nullptr; 419 CPDF_Object* pOffset = pDict ? pDict->GetObjectBy("S") : nullptr;
436 if (!pOffset || !pOffset->IsNumber()) 420 if (!pOffset || !pOffset->IsNumber())
437 return FALSE; 421 return false;
438 422
439 int shared_hint_table_offset = pOffset->GetInteger(); 423 int shared_hint_table_offset = pOffset->GetInteger();
440 if (shared_hint_table_offset <= 0) 424 if (shared_hint_table_offset <= 0)
441 return FALSE; 425 return false;
442 426
443 CPDF_StreamAcc acc; 427 CPDF_StreamAcc acc;
444 acc.LoadAllData(pHintStream); 428 acc.LoadAllData(pHintStream);
445 429
446 uint32_t size = acc.GetSize(); 430 uint32_t size = acc.GetSize();
447 // The header section of page offset hint table is 36 bytes. 431 // The header section of page offset hint table is 36 bytes.
448 // The header section of shared object hint table is 24 bytes. 432 // The header section of shared object hint table is 24 bytes.
449 // Hint table has at least 60 bytes. 433 // Hint table has at least 60 bytes.
450 const uint32_t kMinStreamLength = 60; 434 const uint32_t kMinStreamLength = 60;
451 if (size < kMinStreamLength) 435 if (size < kMinStreamLength)
452 return FALSE; 436 return false;
453 437
454 FX_SAFE_UINT32 safe_shared_hint_table_offset = shared_hint_table_offset; 438 FX_SAFE_UINT32 safe_shared_hint_table_offset = shared_hint_table_offset;
455 if (!safe_shared_hint_table_offset.IsValid() || 439 if (!safe_shared_hint_table_offset.IsValid() ||
456 size < safe_shared_hint_table_offset.ValueOrDie()) { 440 size < safe_shared_hint_table_offset.ValueOrDie()) {
457 return FALSE; 441 return false;
458 } 442 }
459 443
460 CFX_BitStream bs; 444 CFX_BitStream bs;
461 bs.Init(acc.GetData(), size); 445 bs.Init(acc.GetData(), size);
462 return ReadPageHintTable(&bs) && 446 return ReadPageHintTable(&bs) &&
463 ReadSharedObjHintTable(&bs, shared_hint_table_offset); 447 ReadSharedObjHintTable(&bs, shared_hint_table_offset);
464 } 448 }
465 449
450 int CPDF_HintTables::GetEndOfFirstPageOffset() const {
451 CPDF_Object* pOffsetE = m_pLinearizedDict->GetDirectObjectBy("E");
452 return pOffsetE ? pOffsetE->GetInteger() : -1;
453 }
454
455 int CPDF_HintTables::GetNumberOfPages() const {
456 CPDF_Object* pPageNum = m_pLinearizedDict->GetDirectObjectBy("N");
457 return pPageNum ? pPageNum->GetInteger() : 0;
458 }
459
460 int CPDF_HintTables::GetFirstPageObjectNumber() const {
461 CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O");
462 return pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
463 }
464
465 int CPDF_HintTables::GetFirstPageNumber() const {
466 CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P");
467 return pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
468 }
469
466 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { 470 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
467 if (!m_pLinearizedDict) 471 return ReadPrimaryHintStream(0);
468 return -1; 472 }
469 473
474 int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
475 return ReadPrimaryHintStream(1);
476 }
477
478 int CPDF_HintTables::ReadPrimaryHintStream(int index) const {
470 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); 479 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H");
471 if (!pRange) 480 if (!pRange)
472 return -1; 481 return -1;
473 482
474 CPDF_Object* pStreamOffset = pRange->GetDirectObjectAt(0); 483 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index);
475 if (!pStreamOffset) 484 return pStreamLen ? pStreamLen->GetInteger() : -1;
476 return -1;
477
478 return pStreamOffset->GetInteger();
479 } 485 }
480
481 int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
482 if (!m_pLinearizedDict)
483 return -1;
484
485 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H");
486 if (!pRange)
487 return -1;
488
489 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(1);
490 if (!pStreamLen)
491 return -1;
492
493 return pStreamLen->GetInteger();
494 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_hint_tables.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698