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

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 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
OLDNEW
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 <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "../../../include/fpdfapi/fpdf_module.h" 10 #include "../../../include/fpdfapi/fpdf_module.h"
11 #include "../../../include/fpdfapi/fpdf_page.h" 11 #include "../../../include/fpdfapi/fpdf_page.h"
12 #include "../../../include/fpdfapi/fpdf_parser.h" 12 #include "../../../include/fpdfapi/fpdf_parser.h"
13 #include "../../../include/fxcrt/fx_safe_types.h" 13 #include "../../../include/fxcrt/fx_safe_types.h"
14 #include "../fpdf_page/pageint.h" 14 #include "../fpdf_page/pageint.h"
15 15
16 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) 16 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) {
17 { 17 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));
18 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); 18 if (!pType) {
19 pType = pDict->GetElementValue(FX_BSTRC("FT"));
19 if (!pType) { 20 if (!pType) {
20 pType = pDict->GetElementValue(FX_BSTRC("FT")); 21 return FALSE;
21 if (!pType) { 22 }
22 return FALSE; 23 }
23 } 24 if (pType->GetString() == FX_BSTRC("Sig")) {
24 } 25 return TRUE;
25 if (pType->GetString() == FX_BSTRC("Sig")) { 26 }
26 return TRUE; 27 return FALSE;
27 } 28 }
28 return FALSE; 29 static int _CompareFileSize(const void* p1, const void* p2) {
29 } 30 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2);
30 static int _CompareFileSize(const void* p1, const void* p2) 31 if (ret > 0) {
31 { 32 return 1;
32 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2); 33 }
33 if (ret > 0) { 34 if (ret < 0) {
34 return 1; 35 return -1;
35 } 36 }
36 if (ret < 0) { 37 return 0;
37 return -1; 38 }
38 } 39
39 return 0; 40 CPDF_Parser::CPDF_Parser() {
40 } 41 m_pDocument = NULL;
41 42 m_pTrailer = NULL;
42 CPDF_Parser::CPDF_Parser() 43 m_pEncryptDict = NULL;
43 { 44 m_pSecurityHandler = NULL;
45 m_pLinearized = NULL;
46 m_dwFirstPageNo = 0;
47 m_dwXrefStartObjNum = 0;
48 m_bOwnFileRead = TRUE;
49 m_FileVersion = 0;
50 m_bForceUseSecurityHandler = FALSE;
51 }
52 CPDF_Parser::~CPDF_Parser() {
53 CloseParser(FALSE);
54 }
55 FX_DWORD CPDF_Parser::GetLastObjNum() {
56 FX_DWORD dwSize = m_CrossRef.GetSize();
57 return dwSize ? dwSize - 1 : 0;
58 }
59 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) {
60 m_pEncryptDict = pDict;
61 }
62 void CPDF_Parser::CloseParser(FX_BOOL bReParse) {
63 m_bVersionUpdated = FALSE;
64 if (!bReParse) {
65 delete m_pDocument;
44 m_pDocument = NULL; 66 m_pDocument = NULL;
67 }
68 if (m_pTrailer) {
69 m_pTrailer->Release();
45 m_pTrailer = NULL; 70 m_pTrailer = NULL;
46 m_pEncryptDict = NULL; 71 }
47 m_pSecurityHandler = NULL; 72 ReleaseEncryptHandler();
73 SetEncryptDictionary(NULL);
74 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) {
75 m_Syntax.m_pFileAccess->Release();
76 m_Syntax.m_pFileAccess = NULL;
77 }
78 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
79 while (pos) {
80 void* objnum;
81 CPDF_StreamAcc* pStream;
82 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
83 delete pStream;
84 }
85 m_ObjectStreamMap.RemoveAll();
86 m_SortedOffset.RemoveAll();
87 m_CrossRef.RemoveAll();
88 m_V5Type.RemoveAll();
89 m_ObjVersion.RemoveAll();
90 int32_t iLen = m_Trailers.GetSize();
91 for (int32_t i = 0; i < iLen; ++i) {
92 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i))
93 trailer->Release();
94 }
95 m_Trailers.RemoveAll();
96 if (m_pLinearized) {
97 m_pLinearized->Release();
48 m_pLinearized = NULL; 98 m_pLinearized = NULL;
49 m_dwFirstPageNo = 0; 99 }
50 m_dwXrefStartObjNum = 0; 100 }
51 m_bOwnFileRead = TRUE; 101 static int32_t GetHeaderOffset(IFX_FileRead* pFile) {
52 m_FileVersion = 0; 102 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
53 m_bForceUseSecurityHandler = FALSE; 103 uint8_t buf[4];
54 } 104 int32_t offset = 0;
55 CPDF_Parser::~CPDF_Parser() 105 while (1) {
56 { 106 if (!pFile->ReadBlock(buf, offset, 4)) {
57 CloseParser(FALSE); 107 return -1;
58 } 108 }
59 FX_DWORD CPDF_Parser::GetLastObjNum() 109 if (*(FX_DWORD*)buf == tag) {
60 { 110 return offset;
61 FX_DWORD dwSize = m_CrossRef.GetSize(); 111 }
62 return dwSize ? dwSize - 1 : 0; 112 offset++;
63 } 113 if (offset > 1024) {
64 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) 114 return -1;
65 { 115 }
66 m_pEncryptDict = pDict; 116 }
67 } 117 return -1;
68 void CPDF_Parser::CloseParser(FX_BOOL bReParse) 118 }
69 { 119 FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse) {
70 m_bVersionUpdated = FALSE; 120 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
71 if (!bReParse) { 121 if (!pFileAccess) {
72 delete m_pDocument; 122 return PDFPARSE_ERROR_FILE;
73 m_pDocument = NULL; 123 }
74 } 124 return StartParse(pFileAccess, bReParse);
75 if (m_pTrailer) { 125 }
76 m_pTrailer->Release(); 126 FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse) {
77 m_pTrailer = NULL; 127 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
78 } 128 if (!pFileAccess) {
79 ReleaseEncryptHandler(); 129 return PDFPARSE_ERROR_FILE;
80 SetEncryptDictionary(NULL); 130 }
81 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { 131 return StartParse(pFileAccess, bReParse);
82 m_Syntax.m_pFileAccess->Release();
83 m_Syntax.m_pFileAccess = NULL;
84 }
85 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
86 while (pos) {
87 void* objnum;
88 CPDF_StreamAcc* pStream;
89 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
90 delete pStream;
91 }
92 m_ObjectStreamMap.RemoveAll();
93 m_SortedOffset.RemoveAll();
94 m_CrossRef.RemoveAll();
95 m_V5Type.RemoveAll();
96 m_ObjVersion.RemoveAll();
97 int32_t iLen = m_Trailers.GetSize();
98 for (int32_t i = 0; i < iLen; ++i) {
99 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i))
100 trailer->Release();
101 }
102 m_Trailers.RemoveAll();
103 if (m_pLinearized) {
104 m_pLinearized->Release();
105 m_pLinearized = NULL;
106 }
107 }
108 static int32_t GetHeaderOffset(IFX_FileRead* pFile)
109 {
110 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
111 uint8_t buf[4];
112 int32_t offset = 0;
113 while (1) {
114 if (!pFile->ReadBlock(buf, offset, 4)) {
115 return -1;
116 }
117 if (*(FX_DWORD*)buf == tag) {
118 return offset;
119 }
120 offset ++;
121 if (offset > 1024) {
122 return -1;
123 }
124 }
125 return -1;
126 }
127 FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse)
128 {
129 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
130 if (!pFileAccess) {
131 return PDFPARSE_ERROR_FILE;
132 }
133 return StartParse(pFileAccess, bReParse);
134 }
135 FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse)
136 {
137 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
138 if (!pFileAccess) {
139 return PDFPARSE_ERROR_FILE;
140 }
141 return StartParse(pFileAccess, bReParse);
142 } 132 }
143 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); 133 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler();
144 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); 134 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*);
145 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX _BOOL bOwnFileRead) 135 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess,
146 { 136 FX_BOOL bReParse,
147 CloseParser(bReParse); 137 FX_BOOL bOwnFileRead) {
148 m_bXRefStream = FALSE; 138 CloseParser(bReParse);
149 m_LastXRefOffset = 0; 139 m_bXRefStream = FALSE;
150 m_bOwnFileRead = bOwnFileRead; 140 m_LastXRefOffset = 0;
151 int32_t offset = GetHeaderOffset(pFileAccess); 141 m_bOwnFileRead = bOwnFileRead;
152 if (offset == -1) { 142 int32_t offset = GetHeaderOffset(pFileAccess);
153 if (bOwnFileRead && pFileAccess) { 143 if (offset == -1) {
154 pFileAccess->Release(); 144 if (bOwnFileRead && pFileAccess) {
155 } 145 pFileAccess->Release();
146 }
147 return PDFPARSE_ERROR_FORMAT;
148 }
149 m_Syntax.InitParser(pFileAccess, offset);
150 uint8_t ch;
151 if (!m_Syntax.GetCharAt(5, ch)) {
152 return PDFPARSE_ERROR_FORMAT;
153 }
154 if (ch >= '0' && ch <= '9') {
155 m_FileVersion = (ch - '0') * 10;
156 }
157 if (!m_Syntax.GetCharAt(7, ch)) {
158 return PDFPARSE_ERROR_FORMAT;
159 }
160 if (ch >= '0' && ch <= '9') {
161 m_FileVersion += ch - '0';
162 }
163 if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) {
164 return PDFPARSE_ERROR_FORMAT;
165 }
166 m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9);
167 if (!bReParse) {
168 m_pDocument = new CPDF_Document(this);
169 }
170 FX_BOOL bXRefRebuilt = FALSE;
171 if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) {
172 FX_FILESIZE startxref_offset = m_Syntax.SavePos();
173 void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(),
174 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
175 _CompareFileSize);
176 if (pResult == NULL) {
177 m_SortedOffset.Add(startxref_offset);
178 }
179 m_Syntax.GetKeyword();
180 FX_BOOL bNumber;
181 CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber);
182 if (!bNumber) {
183 return PDFPARSE_ERROR_FORMAT;
184 }
185 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
186 if (!LoadAllCrossRefV4(m_LastXRefOffset) &&
187 !LoadAllCrossRefV5(m_LastXRefOffset)) {
188 if (!RebuildCrossRef()) {
156 return PDFPARSE_ERROR_FORMAT; 189 return PDFPARSE_ERROR_FORMAT;
157 } 190 }
158 m_Syntax.InitParser(pFileAccess, offset); 191 bXRefRebuilt = TRUE;
159 uint8_t ch; 192 m_LastXRefOffset = 0;
160 if (!m_Syntax.GetCharAt(5, ch)) { 193 }
161 return PDFPARSE_ERROR_FORMAT; 194 } else {
162 } 195 if (!RebuildCrossRef()) {
163 if (ch >= '0' && ch <= '9') { 196 return PDFPARSE_ERROR_FORMAT;
164 m_FileVersion = (ch - '0') * 10; 197 }
165 } 198 bXRefRebuilt = TRUE;
166 if (!m_Syntax.GetCharAt(7, ch)) { 199 }
167 return PDFPARSE_ERROR_FORMAT; 200 FX_DWORD dwRet = SetEncryptHandler();
168 } 201 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
169 if (ch >= '0' && ch <= '9') { 202 return dwRet;
170 m_FileVersion += ch - '0'; 203 }
171 } 204 m_pDocument->LoadDoc();
172 if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) { 205 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
173 return PDFPARSE_ERROR_FORMAT; 206 if (bXRefRebuilt) {
174 } 207 return PDFPARSE_ERROR_FORMAT;
175 m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9); 208 }
176 if (!bReParse) { 209 ReleaseEncryptHandler();
177 m_pDocument = new CPDF_Document(this); 210 if (!RebuildCrossRef()) {
178 } 211 return PDFPARSE_ERROR_FORMAT;
179 FX_BOOL bXRefRebuilt = FALSE; 212 }
180 if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) { 213 dwRet = SetEncryptHandler();
181 FX_FILESIZE startxref_offset = m_Syntax.SavePos(); 214 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
182 void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData( ), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); 215 return dwRet;
216 }
217 m_pDocument->LoadDoc();
218 if (m_pDocument->GetRoot() == NULL) {
219 return PDFPARSE_ERROR_FORMAT;
220 }
221 }
222 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
223 sizeof(FX_FILESIZE), _CompareFileSize);
224 FX_DWORD RootObjNum = GetRootObjNum();
225 if (RootObjNum == 0) {
226 ReleaseEncryptHandler();
227 RebuildCrossRef();
228 RootObjNum = GetRootObjNum();
229 if (RootObjNum == 0) {
230 return PDFPARSE_ERROR_FORMAT;
231 }
232 dwRet = SetEncryptHandler();
233 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
234 return dwRet;
235 }
236 }
237 if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {
238 CPDF_Reference* pMetadata =
239 (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(
240 FX_BSTRC("Metadata"));
241 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
242 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();
243 }
244 }
245 return PDFPARSE_ERROR_SUCCESS;
246 }
247 FX_DWORD CPDF_Parser::SetEncryptHandler() {
248 ReleaseEncryptHandler();
249 SetEncryptDictionary(NULL);
250 if (m_pTrailer == NULL) {
251 return PDFPARSE_ERROR_FORMAT;
252 }
253 CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt"));
254 if (pEncryptObj) {
255 if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) {
256 SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj);
257 } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) {
258 pEncryptObj = m_pDocument->GetIndirectObject(
259 ((CPDF_Reference*)pEncryptObj)->GetRefObjNum());
260 if (pEncryptObj) {
261 SetEncryptDictionary(pEncryptObj->GetDict());
262 }
263 }
264 }
265 if (m_bForceUseSecurityHandler) {
266 FX_DWORD err = PDFPARSE_ERROR_HANDLER;
267 if (m_pSecurityHandler == NULL) {
268 return PDFPARSE_ERROR_HANDLER;
269 }
270 if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) {
271 return err;
272 }
273 CPDF_CryptoHandler* pCryptoHandler =
274 m_pSecurityHandler->CreateCryptoHandler();
275 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
276 delete pCryptoHandler;
277 pCryptoHandler = NULL;
278 return PDFPARSE_ERROR_HANDLER;
279 }
280 m_Syntax.SetEncrypt(pCryptoHandler);
281 } else if (m_pEncryptDict) {
282 CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter"));
283 CPDF_SecurityHandler* pSecurityHandler = NULL;
284 FX_DWORD err = PDFPARSE_ERROR_HANDLER;
285 if (filter == FX_BSTRC("Standard")) {
286 pSecurityHandler = FPDF_CreateStandardSecurityHandler();
287 err = PDFPARSE_ERROR_PASSWORD;
288 }
289 if (pSecurityHandler == NULL) {
290 return PDFPARSE_ERROR_HANDLER;
291 }
292 if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) {
293 delete pSecurityHandler;
294 pSecurityHandler = NULL;
295 return err;
296 }
297 m_pSecurityHandler = pSecurityHandler;
298 CPDF_CryptoHandler* pCryptoHandler =
299 pSecurityHandler->CreateCryptoHandler();
300 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
301 delete pCryptoHandler;
302 pCryptoHandler = NULL;
303 return PDFPARSE_ERROR_HANDLER;
304 }
305 m_Syntax.SetEncrypt(pCryptoHandler);
306 }
307 return PDFPARSE_ERROR_SUCCESS;
308 }
309 void CPDF_Parser::ReleaseEncryptHandler() {
310 delete m_Syntax.m_pCryptoHandler;
311 m_Syntax.m_pCryptoHandler = NULL;
312 if (!m_bForceUseSecurityHandler) {
313 delete m_pSecurityHandler;
314 m_pSecurityHandler = NULL;
315 }
316 }
317 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) {
318 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
319 return 0;
320 }
321 if (m_V5Type[objnum] == 1) {
322 return m_CrossRef[objnum];
323 }
324 if (m_V5Type[objnum] == 2) {
325 return m_CrossRef[(int32_t)m_CrossRef[objnum]];
326 }
327 return 0;
328 }
329 static int32_t GetDirectInteger(CPDF_Dictionary* pDict,
330 const CFX_ByteStringC& key) {
331 CPDF_Object* pObj = pDict->GetElement(key);
332 if (pObj == NULL) {
333 return 0;
334 }
335 if (pObj->GetType() == PDFOBJ_NUMBER) {
336 return ((CPDF_Number*)pObj)->GetInteger();
337 }
338 return 0;
339 }
340 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict,
341 const CFX_ByteStringC& key,
342 int32_t iType) {
343 CPDF_Object* pObj = pDict->GetElement(key);
344 if (!pObj) {
345 return TRUE;
346 }
347 return pObj->GetType() == iType;
348 }
349 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) {
350 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {
351 return FALSE;
352 }
353 m_pTrailer = LoadTrailerV4();
354 if (m_pTrailer == NULL) {
355 return FALSE;
356 }
357 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
358 if (xrefsize <= 0 || xrefsize > (1 << 20)) {
359 return FALSE;
360 }
361 m_CrossRef.SetSize(xrefsize);
362 m_V5Type.SetSize(xrefsize);
363 CFX_FileSizeArray CrossRefList, XRefStreamList;
364 CrossRefList.Add(xrefpos);
365 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
366 if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
367 return FALSE;
368 }
369 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
370 if (newxrefpos == xrefpos) {
371 return FALSE;
372 }
373 xrefpos = newxrefpos;
374 while (xrefpos) {
375 CrossRefList.InsertAt(0, xrefpos);
376 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
377 CPDF_Dictionary* pDict = LoadTrailerV4();
378 if (pDict == NULL) {
379 return FALSE;
380 }
381 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
382 pDict->Release();
383 return FALSE;
384 }
385 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
386 if (newxrefpos == xrefpos) {
387 pDict->Release();
388 return FALSE;
389 }
390 xrefpos = newxrefpos;
391 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
392 m_Trailers.Add(pDict);
393 }
394 for (int32_t i = 0; i < CrossRefList.GetSize(); i++)
395 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
396 return FALSE;
397 }
398 return TRUE;
399 }
400 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos,
401 FX_DWORD dwObjCount) {
402 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) {
403 return FALSE;
404 }
405 m_pTrailer = LoadTrailerV4();
406 if (m_pTrailer == NULL) {
407 return FALSE;
408 }
409 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
410 if (xrefsize == 0) {
411 return FALSE;
412 }
413 CFX_FileSizeArray CrossRefList, XRefStreamList;
414 CrossRefList.Add(xrefpos);
415 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
416 xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
417 while (xrefpos) {
418 CrossRefList.InsertAt(0, xrefpos);
419 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
420 CPDF_Dictionary* pDict = LoadTrailerV4();
421 if (pDict == NULL) {
422 return FALSE;
423 }
424 xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
425 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
426 m_Trailers.Add(pDict);
427 }
428 for (int32_t i = 1; i < CrossRefList.GetSize(); i++)
429 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
430 return FALSE;
431 }
432 return TRUE;
433 }
434 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
435 FX_DWORD dwObjCount) {
436 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset;
437 m_Syntax.RestorePos(dwStartPos);
438 void* pResult =
439 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
440 sizeof(FX_FILESIZE), _CompareFileSize);
441 if (pResult == NULL) {
442 m_SortedOffset.Add(pos);
443 }
444 FX_DWORD start_objnum = 0;
445 FX_DWORD count = dwObjCount;
446 FX_FILESIZE SavedPos = m_Syntax.SavePos();
447 int32_t recordsize = 20;
448 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
449 pBuf[1024 * recordsize] = '\0';
450 int32_t nBlocks = count / 1024 + 1;
451 for (int32_t block = 0; block < nBlocks; block++) {
452 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
453 FX_DWORD dwReadSize = block_size * recordsize;
454 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) {
455 FX_Free(pBuf);
456 return FALSE;
457 }
458 if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) {
459 FX_Free(pBuf);
460 return FALSE;
461 }
462 for (int32_t i = 0; i < block_size; i++) {
463 FX_DWORD objnum = start_objnum + block * 1024 + i;
464 char* pEntry = pBuf + i * recordsize;
465 if (pEntry[17] == 'f') {
466 m_CrossRef.SetAtGrow(objnum, 0);
467 m_V5Type.SetAtGrow(objnum, 0);
468 } else {
469 int32_t offset = FXSYS_atoi(pEntry);
470 if (offset == 0) {
471 for (int32_t c = 0; c < 10; c++) {
472 if (pEntry[c] < '0' || pEntry[c] > '9') {
473 FX_Free(pBuf);
474 return FALSE;
475 }
476 }
477 }
478 m_CrossRef.SetAtGrow(objnum, offset);
479 int32_t version = FXSYS_atoi(pEntry + 11);
480 if (version >= 1) {
481 m_bVersionUpdated = TRUE;
482 }
483 m_ObjVersion.SetAtGrow(objnum, version);
484 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
485 void* pResult = FXSYS_bsearch(
486 &m_CrossRef[objnum], m_SortedOffset.GetData(),
487 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
488 if (pResult == NULL) {
489 m_SortedOffset.Add(m_CrossRef[objnum]);
490 }
491 }
492 m_V5Type.SetAtGrow(objnum, 1);
493 }
494 }
495 }
496 FX_Free(pBuf);
497 m_Syntax.RestorePos(SavedPos + count * recordsize);
498 return TRUE;
499 }
500 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
501 FX_FILESIZE streampos,
502 FX_BOOL bSkip,
503 FX_BOOL bFirst) {
504 m_Syntax.RestorePos(pos);
505 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {
506 return FALSE;
507 }
508 void* pResult =
509 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
510 sizeof(FX_FILESIZE), _CompareFileSize);
511 if (pResult == NULL) {
512 m_SortedOffset.Add(pos);
513 }
514 if (streampos) {
515 void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(),
516 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
517 _CompareFileSize);
518 if (pResult == NULL) {
519 m_SortedOffset.Add(streampos);
520 }
521 }
522 while (1) {
523 FX_FILESIZE SavedPos = m_Syntax.SavePos();
524 FX_BOOL bIsNumber;
525 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
526 if (word.IsEmpty()) {
527 return FALSE;
528 }
529 if (!bIsNumber) {
530 m_Syntax.RestorePos(SavedPos);
531 break;
532 }
533 FX_DWORD start_objnum = FXSYS_atoi(word);
534 if (start_objnum >= (1 << 20)) {
535 return FALSE;
536 }
537 FX_DWORD count = m_Syntax.GetDirectNum();
538 m_Syntax.ToNextWord();
539 SavedPos = m_Syntax.SavePos();
540 FX_BOOL bFirstItem = FALSE;
541 int32_t recordsize = 20;
542 if (bFirst) {
543 bFirstItem = TRUE;
544 }
545 m_dwXrefStartObjNum = start_objnum;
546 if (!bSkip) {
547 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
548 pBuf[1024 * recordsize] = '\0';
549 int32_t nBlocks = count / 1024 + 1;
550 FX_BOOL bFirstBlock = TRUE;
551 for (int32_t block = 0; block < nBlocks; block++) {
552 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
553 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize);
554 for (int32_t i = 0; i < block_size; i++) {
555 FX_DWORD objnum = start_objnum + block * 1024 + i;
556 char* pEntry = pBuf + i * recordsize;
557 if (pEntry[17] == 'f') {
558 if (bFirstItem) {
559 objnum = 0;
560 bFirstItem = FALSE;
561 }
562 if (bFirstBlock) {
563 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
564 int32_t version = FXSYS_atoi(pEntry + 11);
565 if (offset == 0 && version == 65535 && start_objnum != 0) {
566 start_objnum--;
567 objnum = 0;
568 }
569 }
570 m_CrossRef.SetAtGrow(objnum, 0);
571 m_V5Type.SetAtGrow(objnum, 0);
572 } else {
573 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
574 if (offset == 0) {
575 for (int32_t c = 0; c < 10; c++) {
576 if (pEntry[c] < '0' || pEntry[c] > '9') {
577 FX_Free(pBuf);
578 return FALSE;
579 }
580 }
581 }
582 m_CrossRef.SetAtGrow(objnum, offset);
583 int32_t version = FXSYS_atoi(pEntry + 11);
584 if (version >= 1) {
585 m_bVersionUpdated = TRUE;
586 }
587 m_ObjVersion.SetAtGrow(objnum, version);
588 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
589 void* pResult =
590 FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(),
591 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
592 _CompareFileSize);
593 if (pResult == NULL) {
594 m_SortedOffset.Add(m_CrossRef[objnum]);
595 }
596 }
597 m_V5Type.SetAtGrow(objnum, 1);
598 }
599 if (bFirstBlock) {
600 bFirstBlock = FALSE;
601 }
602 }
603 }
604 FX_Free(pBuf);
605 }
606 m_Syntax.RestorePos(SavedPos + count * recordsize);
607 }
608 if (streampos)
609 if (!LoadCrossRefV5(streampos, streampos, FALSE)) {
610 return FALSE;
611 }
612 return TRUE;
613 }
614 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) {
615 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {
616 return FALSE;
617 }
618 while (xrefpos)
619 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
620 return FALSE;
621 }
622 m_ObjectStreamMap.InitHashTable(101, FALSE);
623 m_bXRefStream = TRUE;
624 return TRUE;
625 }
626 FX_BOOL CPDF_Parser::RebuildCrossRef() {
627 m_CrossRef.RemoveAll();
628 m_V5Type.RemoveAll();
629 m_SortedOffset.RemoveAll();
630 m_ObjVersion.RemoveAll();
631 if (m_pTrailer) {
632 m_pTrailer->Release();
633 m_pTrailer = NULL;
634 }
635 int32_t status = 0;
636 int32_t inside_index = 0;
637 FX_DWORD objnum = 0, gennum = 0;
638 int32_t depth = 0;
639 uint8_t* buffer = FX_Alloc(uint8_t, 4096);
640 FX_FILESIZE pos = m_Syntax.m_HeaderOffset;
641 FX_FILESIZE start_pos = 0, start_pos1 = 0;
642 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;
643 while (pos < m_Syntax.m_FileLen) {
644 FX_BOOL bOverFlow = FALSE;
645 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);
646 if (size > 4096) {
647 size = 4096;
648 }
649 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {
650 break;
651 }
652 for (FX_DWORD i = 0; i < size; i++) {
653 uint8_t byte = buffer[i];
654 switch (status) {
655 case 0:
656 if (PDF_CharType[byte] == 'W') {
657 status = 1;
658 }
659 if (byte <= '9' && byte >= '0') {
660 --i;
661 status = 1;
662 }
663 if (byte == '%') {
664 inside_index = 0;
665 status = 9;
666 }
667 if (byte == '(') {
668 status = 10;
669 depth = 1;
670 }
671 if (byte == '<') {
672 inside_index = 1;
673 status = 11;
674 }
675 if (byte == '\\') {
676 status = 13;
677 }
678 if (byte == 't') {
679 status = 7;
680 inside_index = 1;
681 }
682 break;
683 case 1:
684 if (PDF_CharType[byte] == 'W') {
685 break;
686 } else if (byte <= '9' && byte >= '0') {
687 start_pos = pos + i;
688 status = 2;
689 objnum = byte - '0';
690 } else if (byte == 't') {
691 status = 7;
692 inside_index = 1;
693 } else if (byte == 'x') {
694 status = 8;
695 inside_index = 1;
696 } else {
697 --i;
698 status = 0;
699 }
700 break;
701 case 2:
702 if (byte <= '9' && byte >= '0') {
703 objnum = objnum * 10 + byte - '0';
704 break;
705 } else if (PDF_CharType[byte] == 'W') {
706 status = 3;
707 } else {
708 --i;
709 status = 14;
710 inside_index = 0;
711 }
712 break;
713 case 3:
714 if (byte <= '9' && byte >= '0') {
715 start_pos1 = pos + i;
716 status = 4;
717 gennum = byte - '0';
718 } else if (PDF_CharType[byte] == 'W') {
719 break;
720 } else if (byte == 't') {
721 status = 7;
722 inside_index = 1;
723 } else {
724 --i;
725 status = 0;
726 }
727 break;
728 case 4:
729 if (byte <= '9' && byte >= '0') {
730 gennum = gennum * 10 + byte - '0';
731 break;
732 } else if (PDF_CharType[byte] == 'W') {
733 status = 5;
734 } else {
735 --i;
736 status = 0;
737 }
738 break;
739 case 5:
740 if (byte == 'o') {
741 status = 6;
742 inside_index = 1;
743 } else if (PDF_CharType[byte] == 'W') {
744 break;
745 } else if (byte <= '9' && byte >= '0') {
746 objnum = gennum;
747 gennum = byte - '0';
748 start_pos = start_pos1;
749 start_pos1 = pos + i;
750 status = 4;
751 } else if (byte == 't') {
752 status = 7;
753 inside_index = 1;
754 } else {
755 --i;
756 status = 0;
757 }
758 break;
759 case 6:
760 switch (inside_index) {
761 case 1:
762 if (byte != 'b') {
763 --i;
764 status = 0;
765 } else {
766 inside_index++;
767 }
768 break;
769 case 2:
770 if (byte != 'j') {
771 --i;
772 status = 0;
773 } else {
774 inside_index++;
775 }
776 break;
777 case 3:
778 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') {
779 if (objnum > 0x1000000) {
780 status = 0;
781 break;
782 }
783 FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset;
784 last_obj = start_pos;
785 void* pResult =
786 FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(),
787 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
788 _CompareFileSize);
789 if (pResult == NULL) {
790 m_SortedOffset.Add(obj_pos);
791 }
792 FX_FILESIZE obj_end = 0;
793 CPDF_Object* pObject = ParseIndirectObjectAtByStrict(
794 m_pDocument, obj_pos, objnum, NULL, &obj_end);
795 if (pObject) {
796 int iType = pObject->GetType();
797 if (iType == PDFOBJ_STREAM) {
798 CPDF_Stream* pStream = (CPDF_Stream*)pObject;
799 CPDF_Dictionary* pDict = pStream->GetDict();
800 if (pDict) {
801 if (pDict->KeyExist(FX_BSTRC("Type"))) {
802 CFX_ByteString bsValue =
803 pDict->GetString(FX_BSTRC("Type"));
804 if (bsValue == FX_BSTRC("XRef") &&
805 pDict->KeyExist(FX_BSTRC("Size"))) {
806 CPDF_Object* pRoot =
807 pDict->GetElement(FX_BSTRC("Root"));
808 if (pRoot && pRoot->GetDict() &&
809 pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) {
810 if (m_pTrailer) {
811 m_pTrailer->Release();
812 }
813 m_pTrailer = (CPDF_Dictionary*)pDict->Clone();
814 }
815 }
816 }
817 }
818 }
819 }
820 FX_FILESIZE offset = 0;
821 m_Syntax.RestorePos(obj_pos);
822 offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0);
823 if (offset == -1) {
824 offset = 0;
825 } else {
826 offset += 3;
827 }
828 FX_FILESIZE nLen = obj_end - obj_pos - offset;
829 if ((FX_DWORD)nLen > size - i) {
830 pos = obj_end + m_Syntax.m_HeaderOffset;
831 bOverFlow = TRUE;
832 } else {
833 i += (FX_DWORD)nLen;
834 }
835 if (m_CrossRef.GetSize() > (int32_t)objnum &&
836 m_CrossRef[objnum]) {
837 if (pObject) {
838 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum);
839 m_CrossRef[objnum] = obj_pos;
840 m_ObjVersion.SetAt(objnum, (int16_t)gennum);
841 if (oldgen != gennum) {
842 m_bVersionUpdated = TRUE;
843 }
844 }
845 } else {
846 m_CrossRef.SetAtGrow(objnum, obj_pos);
847 m_V5Type.SetAtGrow(objnum, 1);
848 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum);
849 }
850 if (pObject) {
851 pObject->Release();
852 }
853 }
854 --i;
855 status = 0;
856 break;
857 }
858 break;
859 case 7:
860 if (inside_index == 7) {
861 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') {
862 last_trailer = pos + i - 7;
863 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset);
864 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
865 if (pObj) {
866 if (pObj->GetType() != PDFOBJ_DICTIONARY &&
867 pObj->GetType() != PDFOBJ_STREAM) {
868 pObj->Release();
869 } else {
870 CPDF_Dictionary* pTrailer = NULL;
871 if (pObj->GetType() == PDFOBJ_STREAM) {
872 pTrailer = ((CPDF_Stream*)pObj)->GetDict();
873 } else {
874 pTrailer = (CPDF_Dictionary*)pObj;
875 }
876 if (pTrailer) {
877 if (m_pTrailer) {
878 CPDF_Object* pRoot =
879 pTrailer->GetElement(FX_BSTRC("Root"));
880 if (pRoot == NULL ||
881 (pRoot->GetType() == PDFOBJ_REFERENCE &&
882 (FX_DWORD)m_CrossRef.GetSize() >
883 ((CPDF_Reference*)pRoot)->GetRefObjNum() &&
884 m_CrossRef.GetAt(((CPDF_Reference*)pRoot)
885 ->GetRefObjNum()) != 0)) {
886 FX_POSITION pos = pTrailer->GetStartPos();
887 while (pos) {
888 CFX_ByteString key;
889 CPDF_Object* pObj =
890 pTrailer->GetNextElement(pos, key);
891 m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument);
892 }
893 pObj->Release();
894 } else {
895 pObj->Release();
896 }
897 } else {
898 if (pObj->GetType() == PDFOBJ_STREAM) {
899 m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone();
900 pObj->Release();
901 } else {
902 m_pTrailer = pTrailer;
903 }
904 FX_FILESIZE dwSavePos = m_Syntax.SavePos();
905 CFX_ByteString strWord = m_Syntax.GetKeyword();
906 if (!strWord.Compare(FX_BSTRC("startxref"))) {
907 FX_BOOL bNumber = FALSE;
908 CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber);
909 if (bNumber) {
910 m_LastXRefOffset = FXSYS_atoi(bsOffset);
911 }
912 }
913 m_Syntax.RestorePos(dwSavePos);
914 }
915 } else {
916 pObj->Release();
917 }
918 }
919 }
920 }
921 --i;
922 status = 0;
923 } else if (byte == "trailer"[inside_index]) {
924 inside_index++;
925 } else {
926 --i;
927 status = 0;
928 }
929 break;
930 case 8:
931 if (inside_index == 4) {
932 last_xref = pos + i - 4;
933 status = 1;
934 } else if (byte == "xref"[inside_index]) {
935 inside_index++;
936 } else {
937 --i;
938 status = 0;
939 }
940 break;
941 case 9:
942 if (byte == '\r' || byte == '\n') {
943 status = 0;
944 }
945 break;
946 case 10:
947 if (byte == ')') {
948 if (depth > 0) {
949 depth--;
950 }
951 } else if (byte == '(') {
952 depth++;
953 }
954 if (!depth) {
955 status = 0;
956 }
957 break;
958 case 11:
959 if (byte == '<' && inside_index == 1) {
960 status = 12;
961 } else if (byte == '>') {
962 status = 0;
963 }
964 inside_index = 0;
965 break;
966 case 12:
967 --i;
968 status = 0;
969 break;
970 case 13:
971 if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W') {
972 --i;
973 status = 0;
974 }
975 break;
976 case 14:
977 if (PDF_CharType[byte] == 'W') {
978 status = 0;
979 } else if (byte == '%' || byte == '(' || byte == '<' ||
980 byte == '\\') {
981 status = 0;
982 --i;
983 } else if (inside_index == 6) {
984 status = 0;
985 --i;
986 } else if (byte == "endobj"[inside_index]) {
987 inside_index++;
988 }
989 break;
990 }
991 if (bOverFlow) {
992 size = 0;
993 break;
994 }
995 }
996 pos += size;
997 }
998 if (last_xref != -1 && last_xref > last_obj) {
999 last_trailer = last_xref;
1000 } else if (last_trailer == -1 || last_xref < last_obj) {
1001 last_trailer = m_Syntax.m_FileLen;
1002 }
1003 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;
1004 void* pResult =
1005 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
1006 sizeof(FX_FILESIZE), _CompareFileSize);
1007 if (pResult == NULL) {
1008 m_SortedOffset.Add(offset);
1009 }
1010 FX_Free(buffer);
1011 return TRUE;
1012 }
1013 static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) {
1014 FX_DWORD result = 0;
1015 for (int32_t i = 0; i < n; i++) {
1016 result = result * 256 + p[i];
1017 }
1018 return result;
1019 }
1020 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos,
1021 FX_FILESIZE& prev,
1022 FX_BOOL bMainXRef) {
1023 CPDF_Stream* pStream =
1024 (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL);
1025 if (!pStream) {
1026 return FALSE;
1027 }
1028 if (m_pDocument) {
1029 CPDF_Dictionary* pDict = m_pDocument->GetRoot();
1030 if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) {
1031 m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream);
1032 } else {
1033 if (pStream->GetType() == PDFOBJ_STREAM) {
1034 pStream->Release();
1035 }
1036 return FALSE;
1037 }
1038 }
1039 if (pStream->GetType() != PDFOBJ_STREAM) {
1040 return FALSE;
1041 }
1042 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev"));
1043 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size"));
1044 if (size < 0) {
1045 pStream->Release();
1046 return FALSE;
1047 }
1048 if (bMainXRef) {
1049 m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone();
1050 m_CrossRef.SetSize(size);
1051 if (m_V5Type.SetSize(size)) {
1052 FXSYS_memset(m_V5Type.GetData(), 0, size);
1053 }
1054 } else {
1055 m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone());
1056 }
1057 std::vector<std::pair<int32_t, int32_t> > arrIndex;
1058 CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index"));
1059 if (pArray) {
1060 FX_DWORD nPairSize = pArray->GetCount() / 2;
1061 for (FX_DWORD i = 0; i < nPairSize; i++) {
1062 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2);
1063 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1);
1064 if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER &&
1065 pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) {
1066 int nStartNum = pStartNumObj->GetInteger();
1067 int nCount = pCountObj->GetInteger();
1068 if (nStartNum >= 0 && nCount > 0) {
1069 arrIndex.push_back(std::make_pair(nStartNum, nCount));
1070 }
1071 }
1072 }
1073 }
1074 if (arrIndex.size() == 0) {
1075 arrIndex.push_back(std::make_pair(0, size));
1076 }
1077 pArray = pStream->GetDict()->GetArray(FX_BSTRC("W"));
1078 if (pArray == NULL) {
1079 pStream->Release();
1080 return FALSE;
1081 }
1082 CFX_DWordArray WidthArray;
1083 FX_SAFE_DWORD dwAccWidth = 0;
1084 for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
1085 WidthArray.Add(pArray->GetInteger(i));
1086 dwAccWidth += WidthArray[i];
1087 }
1088 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) {
1089 pStream->Release();
1090 return FALSE;
1091 }
1092 FX_DWORD totalWidth = dwAccWidth.ValueOrDie();
1093 CPDF_StreamAcc acc;
1094 acc.LoadAllData(pStream);
1095 const uint8_t* pData = acc.GetData();
1096 FX_DWORD dwTotalSize = acc.GetSize();
1097 FX_DWORD segindex = 0;
1098 for (FX_DWORD i = 0; i < arrIndex.size(); i++) {
1099 int32_t startnum = arrIndex[i].first;
1100 if (startnum < 0) {
1101 continue;
1102 }
1103 m_dwXrefStartObjNum =
1104 pdfium::base::checked_cast<FX_DWORD, int32_t>(startnum);
1105 FX_DWORD count =
1106 pdfium::base::checked_cast<FX_DWORD, int32_t>(arrIndex[i].second);
1107 FX_SAFE_DWORD dwCaculatedSize = segindex;
1108 dwCaculatedSize += count;
1109 dwCaculatedSize *= totalWidth;
1110 if (!dwCaculatedSize.IsValid() ||
1111 dwCaculatedSize.ValueOrDie() > dwTotalSize) {
1112 continue;
1113 }
1114 const uint8_t* segstart = pData + segindex * totalWidth;
1115 FX_SAFE_DWORD dwMaxObjNum = startnum;
1116 dwMaxObjNum += count;
1117 FX_DWORD dwV5Size =
1118 pdfium::base::checked_cast<FX_DWORD, int32_t>(m_V5Type.GetSize());
1119 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) {
1120 continue;
1121 }
1122 for (FX_DWORD j = 0; j < count; j++) {
1123 int32_t type = 1;
1124 const uint8_t* entrystart = segstart + j * totalWidth;
1125 if (WidthArray[0]) {
1126 type = _GetVarInt(entrystart, WidthArray[0]);
1127 }
1128 if (m_V5Type[startnum + j] == 255) {
1129 FX_FILESIZE offset =
1130 _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
1131 m_CrossRef[startnum + j] = offset;
1132 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
1133 m_SortedOffset.GetSize(),
1134 sizeof(FX_FILESIZE), _CompareFileSize);
183 if (pResult == NULL) { 1135 if (pResult == NULL) {
184 m_SortedOffset.Add(startxref_offset); 1136 m_SortedOffset.Add(offset);
185 } 1137 }
186 m_Syntax.GetKeyword(); 1138 continue;
187 FX_BOOL bNumber; 1139 }
188 CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber); 1140 if (m_V5Type[startnum + j]) {
189 if (!bNumber) { 1141 continue;
190 return PDFPARSE_ERROR_FORMAT; 1142 }
191 } 1143 m_V5Type[startnum + j] = type;
192 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); 1144 if (type == 0) {
193 if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRe fOffset)) { 1145 m_CrossRef[startnum + j] = 0;
194 if (!RebuildCrossRef()) { 1146 } else {
195 return PDFPARSE_ERROR_FORMAT; 1147 FX_FILESIZE offset =
196 } 1148 _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
197 bXRefRebuilt = TRUE; 1149 m_CrossRef[startnum + j] = offset;
198 m_LastXRefOffset = 0; 1150 if (type == 1) {
199 } 1151 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
200 } else { 1152 m_SortedOffset.GetSize(),
201 if (!RebuildCrossRef()) { 1153 sizeof(FX_FILESIZE), _CompareFileSize);
202 return PDFPARSE_ERROR_FORMAT; 1154 if (pResult == NULL) {
203 } 1155 m_SortedOffset.Add(offset);
204 bXRefRebuilt = TRUE; 1156 }
205 } 1157 } else {
206 FX_DWORD dwRet = SetEncryptHandler(); 1158 if (offset < 0 || offset >= m_V5Type.GetSize()) {
207 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 1159 pStream->Release();
208 return dwRet; 1160 return FALSE;
209 } 1161 }
210 m_pDocument->LoadDoc(); 1162 m_V5Type[offset] = 255;
211 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { 1163 }
212 if (bXRefRebuilt) { 1164 }
213 return PDFPARSE_ERROR_FORMAT; 1165 }
214 } 1166 segindex += count;
215 ReleaseEncryptHandler(); 1167 }
216 if (!RebuildCrossRef()) { 1168 pStream->Release();
217 return PDFPARSE_ERROR_FORMAT; 1169 return TRUE;
218 } 1170 }
219 dwRet = SetEncryptHandler(); 1171 CPDF_Array* CPDF_Parser::GetIDArray() {
220 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 1172 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL;
221 return dwRet; 1173 if (pID == NULL) {
222 } 1174 return NULL;
223 m_pDocument->LoadDoc(); 1175 }
224 if (m_pDocument->GetRoot() == NULL) { 1176 if (pID->GetType() == PDFOBJ_REFERENCE) {
225 return PDFPARSE_ERROR_FORMAT; 1177 pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());
226 } 1178 m_pTrailer->SetAt(FX_BSTRC("ID"), pID);
227 } 1179 }
228 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI LESIZE), _CompareFileSize); 1180 if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {
229 FX_DWORD RootObjNum = GetRootObjNum(); 1181 return NULL;
230 if (RootObjNum == 0) { 1182 }
231 ReleaseEncryptHandler(); 1183 return (CPDF_Array*)pID;
232 RebuildCrossRef(); 1184 }
233 RootObjNum = GetRootObjNum(); 1185 FX_DWORD CPDF_Parser::GetRootObjNum() {
234 if (RootObjNum == 0) { 1186 CPDF_Object* pRef =
235 return PDFPARSE_ERROR_FORMAT; 1187 m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL;
236 } 1188 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
237 dwRet = SetEncryptHandler();
238 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
239 return dwRet;
240 }
241 }
242 if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {
243 CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->Get Element(FX_BSTRC("Metadata"));
244 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
245 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();
246 }
247 }
248 return PDFPARSE_ERROR_SUCCESS;
249 }
250 FX_DWORD CPDF_Parser::SetEncryptHandler()
251 {
252 ReleaseEncryptHandler();
253 SetEncryptDictionary(NULL);
254 if (m_pTrailer == NULL) {
255 return PDFPARSE_ERROR_FORMAT;
256 }
257 CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt"));
258 if (pEncryptObj) {
259 if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) {
260 SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj);
261 } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) {
262 pEncryptObj = m_pDocument->GetIndirectObject(((CPDF_Reference*)pEncr yptObj)->GetRefObjNum());
263 if (pEncryptObj) {
264 SetEncryptDictionary(pEncryptObj->GetDict());
265 }
266 }
267 }
268 if (m_bForceUseSecurityHandler) {
269 FX_DWORD err = PDFPARSE_ERROR_HANDLER;
270 if (m_pSecurityHandler == NULL) {
271 return PDFPARSE_ERROR_HANDLER;
272 }
273 if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) {
274 return err;
275 }
276 CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHan dler();
277 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
278 delete pCryptoHandler;
279 pCryptoHandler = NULL;
280 return PDFPARSE_ERROR_HANDLER;
281 }
282 m_Syntax.SetEncrypt(pCryptoHandler);
283 } else if (m_pEncryptDict) {
284 CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter"));
285 CPDF_SecurityHandler* pSecurityHandler = NULL;
286 FX_DWORD err = PDFPARSE_ERROR_HANDLER;
287 if (filter == FX_BSTRC("Standard")) {
288 pSecurityHandler = FPDF_CreateStandardSecurityHandler();
289 err = PDFPARSE_ERROR_PASSWORD;
290 }
291 if (pSecurityHandler == NULL) {
292 return PDFPARSE_ERROR_HANDLER;
293 }
294 if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) {
295 delete pSecurityHandler;
296 pSecurityHandler = NULL;
297 return err;
298 }
299 m_pSecurityHandler = pSecurityHandler;
300 CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandl er();
301 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
302 delete pCryptoHandler;
303 pCryptoHandler = NULL;
304 return PDFPARSE_ERROR_HANDLER;
305 }
306 m_Syntax.SetEncrypt(pCryptoHandler);
307 }
308 return PDFPARSE_ERROR_SUCCESS;
309 }
310 void CPDF_Parser::ReleaseEncryptHandler()
311 {
312 delete m_Syntax.m_pCryptoHandler;
313 m_Syntax.m_pCryptoHandler = NULL;
314 if (!m_bForceUseSecurityHandler) {
315 delete m_pSecurityHandler;
316 m_pSecurityHandler = NULL;
317 }
318 }
319 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum)
320 {
321 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
322 return 0;
323 }
324 if (m_V5Type[objnum] == 1) {
325 return m_CrossRef[objnum];
326 }
327 if (m_V5Type[objnum] == 2) {
328 return m_CrossRef[(int32_t)m_CrossRef[objnum]];
329 }
330 return 0; 1189 return 0;
331 } 1190 }
332 static int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteStringC& k ey) 1191 return ((CPDF_Reference*)pRef)->GetRefObjNum();
333 { 1192 }
334 CPDF_Object* pObj = pDict->GetElement(key); 1193 FX_DWORD CPDF_Parser::GetInfoObjNum() {
335 if (pObj == NULL) { 1194 CPDF_Object* pRef =
336 return 0; 1195 m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL;
337 } 1196 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
338 if (pObj->GetType() == PDFOBJ_NUMBER) {
339 return ((CPDF_Number*)pObj)->GetInteger();
340 }
341 return 0; 1197 return 0;
342 } 1198 }
343 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, const CFX_ByteStringC& ke y, int32_t iType) 1199 return ((CPDF_Reference*)pRef)->GetRefObjNum();
344 { 1200 }
345 CPDF_Object* pObj = pDict->GetElement(key); 1201 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) {
346 if (!pObj) { 1202 bForm = FALSE;
347 return TRUE; 1203 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
348 }
349 return pObj->GetType() == iType;
350 }
351 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos)
352 {
353 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {
354 return FALSE;
355 }
356 m_pTrailer = LoadTrailerV4();
357 if (m_pTrailer == NULL) {
358 return FALSE;
359 }
360 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
361 if (xrefsize <= 0 || xrefsize > (1 << 20)) {
362 return FALSE;
363 }
364 m_CrossRef.SetSize(xrefsize);
365 m_V5Type.SetSize(xrefsize);
366 CFX_FileSizeArray CrossRefList, XRefStreamList;
367 CrossRefList.Add(xrefpos);
368 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
369 if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
370 return FALSE;
371 }
372 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
373 if (newxrefpos == xrefpos) {
374 return FALSE;
375 }
376 xrefpos = newxrefpos;
377 while (xrefpos) {
378 CrossRefList.InsertAt(0, xrefpos);
379 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
380 CPDF_Dictionary* pDict = LoadTrailerV4();
381 if (pDict == NULL) {
382 return FALSE;
383 }
384 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
385 pDict->Release();
386 return FALSE;
387 }
388 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
389 if (newxrefpos == xrefpos) {
390 pDict->Release();
391 return FALSE;
392 }
393 xrefpos = newxrefpos;
394 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
395 m_Trailers.Add(pDict);
396 }
397 for (int32_t i = 0; i < CrossRefList.GetSize(); i ++)
398 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
399 return FALSE;
400 }
401 return TRUE; 1204 return TRUE;
402 } 1205 }
403 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD d wObjCount) 1206 if (m_V5Type[objnum] == 0) {
404 {
405 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) {
406 return FALSE;
407 }
408 m_pTrailer = LoadTrailerV4();
409 if (m_pTrailer == NULL) {
410 return FALSE;
411 }
412 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
413 if (xrefsize == 0) {
414 return FALSE;
415 }
416 CFX_FileSizeArray CrossRefList, XRefStreamList;
417 CrossRefList.Add(xrefpos);
418 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
419 xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
420 while (xrefpos) {
421 CrossRefList.InsertAt(0, xrefpos);
422 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
423 CPDF_Dictionary* pDict = LoadTrailerV4();
424 if (pDict == NULL) {
425 return FALSE;
426 }
427 xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
428 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
429 m_Trailers.Add(pDict);
430 }
431 for (int32_t i = 1; i < CrossRefList.GetSize(); i ++)
432 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
433 return FALSE;
434 }
435 return TRUE; 1207 return TRUE;
436 } 1208 }
437 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCou nt) 1209 if (m_V5Type[objnum] == 2) {
438 { 1210 return TRUE;
439 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; 1211 }
440 m_Syntax.RestorePos(dwStartPos); 1212 FX_FILESIZE pos = m_CrossRef[objnum];
441 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset .GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); 1213 void* pResult =
1214 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
1215 sizeof(FX_FILESIZE), _CompareFileSize);
1216 if (pResult == NULL) {
1217 return TRUE;
1218 }
1219 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() ==
1220 m_SortedOffset.GetSize() - 1) {
1221 return FALSE;
1222 }
1223 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos;
1224 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1225 m_Syntax.RestorePos(pos);
1226 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0;
1227 m_Syntax.RestorePos(SavedPos);
1228 return TRUE;
1229 }
1230 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList,
1231 FX_DWORD objnum,
1232 PARSE_CONTEXT* pContext) {
1233 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1234 return NULL;
1235 }
1236 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1237 FX_FILESIZE pos = m_CrossRef[objnum];
1238 if (pos <= 0) {
1239 return NULL;
1240 }
1241 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);
1242 }
1243 if (m_V5Type[objnum] == 2) {
1244 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
1245 if (pObjStream == NULL) {
1246 return NULL;
1247 }
1248 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
1249 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
1250 CPDF_SyntaxParser syntax;
1251 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(
1252 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));
1253 syntax.InitParser(file.Get(), 0);
1254 CPDF_Object* pRet = NULL;
1255 while (n) {
1256 FX_DWORD thisnum = syntax.GetDirectNum();
1257 FX_DWORD thisoff = syntax.GetDirectNum();
1258 if (thisnum == objnum) {
1259 syntax.RestorePos(offset + thisoff);
1260 pRet = syntax.GetObject(pObjList, 0, 0, pContext);
1261 break;
1262 }
1263 n--;
1264 }
1265 return pRet;
1266 }
1267 return NULL;
1268 }
1269 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) {
1270 CPDF_StreamAcc* pStreamAcc = NULL;
1271 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) {
1272 return pStreamAcc;
1273 }
1274 const CPDF_Stream* pStream =
1275 m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL;
1276 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
1277 return NULL;
1278 }
1279 pStreamAcc = new CPDF_StreamAcc;
1280 pStreamAcc->LoadAllData(pStream);
1281 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc);
1282 return pStreamAcc;
1283 }
1284 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) {
1285 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1286 return 0;
1287 }
1288 if (m_V5Type[objnum] == 2) {
1289 objnum = (FX_DWORD)m_CrossRef[objnum];
1290 }
1291 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1292 FX_FILESIZE offset = m_CrossRef[objnum];
1293 if (offset == 0) {
1294 return 0;
1295 }
1296 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
1297 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
1298 _CompareFileSize);
442 if (pResult == NULL) { 1299 if (pResult == NULL) {
443 m_SortedOffset.Add(pos); 1300 return 0;
444 } 1301 }
445 FX_DWORD start_objnum = 0; 1302 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() ==
446 FX_DWORD count = dwObjCount; 1303 m_SortedOffset.GetSize() - 1) {
447 FX_FILESIZE SavedPos = m_Syntax.SavePos(); 1304 return 0;
448 int32_t recordsize = 20; 1305 }
449 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); 1306 return ((FX_FILESIZE*)pResult)[1] - offset;
450 pBuf[1024 * recordsize] = '\0'; 1307 }
451 int32_t nBlocks = count / 1024 + 1; 1308 return 0;
452 for (int32_t block = 0; block < nBlocks; block ++) { 1309 }
453 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; 1310 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum,
454 FX_DWORD dwReadSize = block_size * recordsize; 1311 uint8_t*& pBuffer,
455 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { 1312 FX_DWORD& size) {
456 FX_Free(pBuf); 1313 pBuffer = NULL;
457 return FALSE; 1314 size = 0;
458 } 1315 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
459 if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) { 1316 return;
460 FX_Free(pBuf); 1317 }
461 return FALSE; 1318 if (m_V5Type[objnum] == 2) {
462 } 1319 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
463 for (int32_t i = 0; i < block_size; i ++) { 1320 if (pObjStream == NULL) {
464 FX_DWORD objnum = start_objnum + block * 1024 + i; 1321 return;
465 char* pEntry = pBuf + i * recordsize; 1322 }
466 if (pEntry[17] == 'f') { 1323 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
467 m_CrossRef.SetAtGrow(objnum, 0); 1324 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
468 m_V5Type.SetAtGrow(objnum, 0); 1325 CPDF_SyntaxParser syntax;
469 } else { 1326 const uint8_t* pData = pObjStream->GetData();
470 int32_t offset = FXSYS_atoi(pEntry); 1327 FX_DWORD totalsize = pObjStream->GetSize();
471 if (offset == 0) { 1328 CFX_SmartPointer<IFX_FileStream> file(
472 for (int32_t c = 0; c < 10; c ++) { 1329 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE));
473 if (pEntry[c] < '0' || pEntry[c] > '9') { 1330 syntax.InitParser(file.Get(), 0);
474 FX_Free(pBuf); 1331 while (n) {
475 return FALSE; 1332 FX_DWORD thisnum = syntax.GetDirectNum();
476 } 1333 FX_DWORD thisoff = syntax.GetDirectNum();
477 } 1334 if (thisnum == objnum) {
478 } 1335 if (n == 1) {
479 m_CrossRef.SetAtGrow(objnum, offset); 1336 size = totalsize - (thisoff + offset);
480 int32_t version = FXSYS_atoi(pEntry + 11);
481 if (version >= 1) {
482 m_bVersionUpdated = TRUE;
483 }
484 m_ObjVersion.SetAtGrow(objnum, version);
485 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
486 void* pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedO ffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize );
487 if (pResult == NULL) {
488 m_SortedOffset.Add(m_CrossRef[objnum]);
489 }
490 }
491 m_V5Type.SetAtGrow(objnum, 1);
492 }
493 }
494 }
495 FX_Free(pBuf);
496 m_Syntax.RestorePos(SavedPos + count * recordsize);
497 return TRUE;
498 }
499 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_B OOL bSkip, FX_BOOL bFirst)
500 {
501 m_Syntax.RestorePos(pos);
502 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {
503 return FALSE;
504 }
505 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset .GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
506 if (pResult == NULL) {
507 m_SortedOffset.Add(pos);
508 }
509 if (streampos) {
510 void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_So rtedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
511 if (pResult == NULL) {
512 m_SortedOffset.Add(streampos);
513 }
514 }
515 while (1) {
516 FX_FILESIZE SavedPos = m_Syntax.SavePos();
517 FX_BOOL bIsNumber;
518 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
519 if (word.IsEmpty()) {
520 return FALSE;
521 }
522 if (!bIsNumber) {
523 m_Syntax.RestorePos(SavedPos);
524 break;
525 }
526 FX_DWORD start_objnum = FXSYS_atoi(word);
527 if (start_objnum >= (1 << 20)) {
528 return FALSE;
529 }
530 FX_DWORD count = m_Syntax.GetDirectNum();
531 m_Syntax.ToNextWord();
532 SavedPos = m_Syntax.SavePos();
533 FX_BOOL bFirstItem = FALSE;
534 int32_t recordsize = 20;
535 if (bFirst) {
536 bFirstItem = TRUE;
537 }
538 m_dwXrefStartObjNum = start_objnum;
539 if (!bSkip) {
540 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
541 pBuf[1024 * recordsize] = '\0';
542 int32_t nBlocks = count / 1024 + 1;
543 FX_BOOL bFirstBlock = TRUE;
544 for (int32_t block = 0; block < nBlocks; block ++) {
545 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
546 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize);
547 for (int32_t i = 0; i < block_size; i ++) {
548 FX_DWORD objnum = start_objnum + block * 1024 + i;
549 char* pEntry = pBuf + i * recordsize;
550 if (pEntry[17] == 'f') {
551 if (bFirstItem) {
552 objnum = 0;
553 bFirstItem = FALSE;
554 }
555 if (bFirstBlock) {
556 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntr y);
557 int32_t version = FXSYS_atoi(pEntry + 11);
558 if (offset == 0 && version == 65535 && start_objnum != 0) {
559 start_objnum--;
560 objnum = 0;
561 }
562 }
563 m_CrossRef.SetAtGrow(objnum, 0);
564 m_V5Type.SetAtGrow(objnum, 0);
565 } else {
566 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
567 if (offset == 0) {
568 for (int32_t c = 0; c < 10; c ++) {
569 if (pEntry[c] < '0' || pEntry[c] > '9') {
570 FX_Free(pBuf);
571 return FALSE;
572 }
573 }
574 }
575 m_CrossRef.SetAtGrow(objnum, offset);
576 int32_t version = FXSYS_atoi(pEntry + 11);
577 if (version >= 1) {
578 m_bVersionUpdated = TRUE;
579 }
580 m_ObjVersion.SetAtGrow(objnum, version);
581 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
582 void* pResult = FXSYS_bsearch(&m_CrossRef[objnum], m _SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _Compare FileSize);
583 if (pResult == NULL) {
584 m_SortedOffset.Add(m_CrossRef[objnum]);
585 }
586 }
587 m_V5Type.SetAtGrow(objnum, 1);
588 }
589 if (bFirstBlock) {
590 bFirstBlock = FALSE;
591 }
592 }
593 }
594 FX_Free(pBuf);
595 }
596 m_Syntax.RestorePos(SavedPos + count * recordsize);
597 }
598 if (streampos)
599 if (!LoadCrossRefV5(streampos, streampos, FALSE)) {
600 return FALSE;
601 }
602 return TRUE;
603 }
604 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos)
605 {
606 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {
607 return FALSE;
608 }
609 while (xrefpos)
610 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
611 return FALSE;
612 }
613 m_ObjectStreamMap.InitHashTable(101, FALSE);
614 m_bXRefStream = TRUE;
615 return TRUE;
616 }
617 FX_BOOL CPDF_Parser::RebuildCrossRef()
618 {
619 m_CrossRef.RemoveAll();
620 m_V5Type.RemoveAll();
621 m_SortedOffset.RemoveAll();
622 m_ObjVersion.RemoveAll();
623 if (m_pTrailer) {
624 m_pTrailer->Release();
625 m_pTrailer = NULL;
626 }
627 int32_t status = 0;
628 int32_t inside_index = 0;
629 FX_DWORD objnum = 0, gennum = 0;
630 int32_t depth = 0;
631 uint8_t* buffer = FX_Alloc(uint8_t, 4096);
632 FX_FILESIZE pos = m_Syntax.m_HeaderOffset;
633 FX_FILESIZE start_pos = 0, start_pos1 = 0;
634 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;
635 while (pos < m_Syntax.m_FileLen) {
636 FX_BOOL bOverFlow = FALSE;
637 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);
638 if (size > 4096) {
639 size = 4096;
640 }
641 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {
642 break;
643 }
644 for (FX_DWORD i = 0; i < size; i ++) {
645 uint8_t byte = buffer[i];
646 switch (status) {
647 case 0:
648 if (PDF_CharType[byte] == 'W') {
649 status = 1;
650 }
651 if (byte <= '9' && byte >= '0') {
652 --i;
653 status = 1;
654 }
655 if (byte == '%') {
656 inside_index = 0;
657 status = 9;
658 }
659 if (byte == '(') {
660 status = 10;
661 depth = 1;
662 }
663 if (byte == '<') {
664 inside_index = 1;
665 status = 11;
666 }
667 if (byte == '\\') {
668 status = 13;
669 }
670 if (byte == 't') {
671 status = 7;
672 inside_index = 1;
673 }
674 break;
675 case 1:
676 if (PDF_CharType[byte] == 'W') {
677 break;
678 } else if (byte <= '9' && byte >= '0') {
679 start_pos = pos + i;
680 status = 2;
681 objnum = byte - '0';
682 } else if (byte == 't') {
683 status = 7;
684 inside_index = 1;
685 } else if (byte == 'x') {
686 status = 8;
687 inside_index = 1;
688 } else {
689 --i;
690 status = 0;
691 }
692 break;
693 case 2:
694 if (byte <= '9' && byte >= '0') {
695 objnum = objnum * 10 + byte - '0';
696 break;
697 } else if (PDF_CharType[byte] == 'W') {
698 status = 3;
699 } else {
700 --i;
701 status = 14;
702 inside_index = 0;
703 }
704 break;
705 case 3:
706 if (byte <= '9' && byte >= '0') {
707 start_pos1 = pos + i;
708 status = 4;
709 gennum = byte - '0';
710 } else if (PDF_CharType[byte] == 'W') {
711 break;
712 } else if (byte == 't') {
713 status = 7;
714 inside_index = 1;
715 } else {
716 --i;
717 status = 0;
718 }
719 break;
720 case 4:
721 if (byte <= '9' && byte >= '0') {
722 gennum = gennum * 10 + byte - '0';
723 break;
724 } else if (PDF_CharType[byte] == 'W') {
725 status = 5;
726 } else {
727 --i;
728 status = 0;
729 }
730 break;
731 case 5:
732 if (byte == 'o') {
733 status = 6;
734 inside_index = 1;
735 } else if (PDF_CharType[byte] == 'W') {
736 break;
737 } else if (byte <= '9' && byte >= '0') {
738 objnum = gennum;
739 gennum = byte - '0';
740 start_pos = start_pos1;
741 start_pos1 = pos + i;
742 status = 4;
743 } else if (byte == 't') {
744 status = 7;
745 inside_index = 1;
746 } else {
747 --i;
748 status = 0;
749 }
750 break;
751 case 6:
752 switch (inside_index) {
753 case 1:
754 if (byte != 'b') {
755 --i;
756 status = 0;
757 } else {
758 inside_index ++;
759 }
760 break;
761 case 2:
762 if (byte != 'j') {
763 --i;
764 status = 0;
765 } else {
766 inside_index ++;
767 }
768 break;
769 case 3:
770 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') {
771 if (objnum > 0x1000000) {
772 status = 0;
773 break;
774 }
775 FX_FILESIZE obj_pos = start_pos - m_Syntax.m_Hea derOffset;
776 last_obj = start_pos;
777 void* pResult = FXSYS_bsearch(&obj_pos, m_Sorted Offset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSiz e);
778 if (pResult == NULL) {
779 m_SortedOffset.Add(obj_pos);
780 }
781 FX_FILESIZE obj_end = 0;
782 CPDF_Object *pObject = ParseIndirectObjectAtBySt rict(m_pDocument, obj_pos, objnum, NULL, &obj_end);
783 if (pObject) {
784 int iType = pObject->GetType();
785 if (iType == PDFOBJ_STREAM) {
786 CPDF_Stream* pStream = (CPDF_Stream*)pOb ject;
787 CPDF_Dictionary* pDict = pStream->GetDic t();
788 if (pDict) {
789 if (pDict->KeyExist(FX_BSTRC("Type") )) {
790 CFX_ByteString bsValue = pDict-> GetString(FX_BSTRC("Type"));
791 if (bsValue == FX_BSTRC("XRef") && pDict->KeyExist(FX_BSTRC("Size"))) {
792 CPDF_Object* pRoot = pDict-> GetElement(FX_BSTRC("Root"));
793 if (pRoot && pRoot->GetDict( ) && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) {
794 if (m_pTrailer) {
795 m_pTrailer->Release( );
796 }
797 m_pTrailer = (CPDF_Dicti onary*)pDict->Clone();
798 }
799 }
800 }
801 }
802 }
803 }
804 FX_FILESIZE offset = 0;
805 m_Syntax.RestorePos(obj_pos);
806 offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0);
807 if (offset == -1) {
808 offset = 0;
809 } else {
810 offset += 3;
811 }
812 FX_FILESIZE nLen = obj_end - obj_pos - offset;
813 if ((FX_DWORD)nLen > size - i) {
814 pos = obj_end + m_Syntax.m_HeaderOffset;
815 bOverFlow = TRUE;
816 } else {
817 i += (FX_DWORD)nLen;
818 }
819 if (m_CrossRef.GetSize() > (int32_t)objnum && m_ CrossRef[objnum]) {
820 if (pObject) {
821 FX_DWORD oldgen = m_ObjVersion.GetAt(obj num);
822 m_CrossRef[objnum] = obj_pos;
823 m_ObjVersion.SetAt(objnum, (int16_t)genn um);
824 if (oldgen != gennum) {
825 m_bVersionUpdated = TRUE;
826 }
827 }
828 } else {
829 m_CrossRef.SetAtGrow(objnum, obj_pos);
830 m_V5Type.SetAtGrow(objnum, 1);
831 m_ObjVersion.SetAtGrow(objnum, (int16_t)genn um);
832 }
833 if (pObject) {
834 pObject->Release();
835 }
836 }
837 --i;
838 status = 0;
839 break;
840 }
841 break;
842 case 7:
843 if (inside_index == 7) {
844 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == ' D') {
845 last_trailer = pos + i - 7;
846 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffse t);
847 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
848 if (pObj) {
849 if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj ->GetType() != PDFOBJ_STREAM) {
850 pObj->Release();
851 } else {
852 CPDF_Dictionary* pTrailer = NULL;
853 if (pObj->GetType() == PDFOBJ_STREAM) {
854 pTrailer = ((CPDF_Stream*)pObj)->GetDict ();
855 } else {
856 pTrailer = (CPDF_Dictionary*)pObj;
857 }
858 if (pTrailer) {
859 if (m_pTrailer) {
860 CPDF_Object* pRoot = pTrailer->GetEl ement(FX_BSTRC("Root"));
861 if (pRoot == NULL || (pRoot->GetType () == PDFOBJ_REFERENCE &&
862 (FX_DWORD)m_Cr ossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() &&
863 m_CrossRef.Get At(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) {
864 FX_POSITION pos = pTrailer->GetS tartPos();
865 while (pos) {
866 CFX_ByteString key;
867 CPDF_Object* pObj = pTrailer ->GetNextElement(pos, key);
868 m_pTrailer->SetAt(key, pObj- >Clone(), m_pDocument);
869 }
870 pObj->Release();
871 } else {
872 pObj->Release();
873 }
874 } else {
875 if (pObj->GetType() == PDFOBJ_STREAM ) {
876 m_pTrailer = (CPDF_Dictionary*)p Trailer->Clone();
877 pObj->Release();
878 } else {
879 m_pTrailer = pTrailer;
880 }
881 FX_FILESIZE dwSavePos = m_Syntax.Sav ePos();
882 CFX_ByteString strWord = m_Syntax.Ge tKeyword();
883 if (!strWord.Compare(FX_BSTRC("start xref"))) {
884 FX_BOOL bNumber = FALSE;
885 CFX_ByteString bsOffset = m_Synt ax.GetNextWord(bNumber);
886 if (bNumber) {
887 m_LastXRefOffset = FXSYS_ato i(bsOffset);
888 }
889 }
890 m_Syntax.RestorePos(dwSavePos);
891 }
892 } else {
893 pObj->Release();
894 }
895 }
896 }
897 }
898 --i;
899 status = 0;
900 } else if (byte == "trailer"[inside_index]) {
901 inside_index ++;
902 } else {
903 --i;
904 status = 0;
905 }
906 break;
907 case 8:
908 if (inside_index == 4) {
909 last_xref = pos + i - 4;
910 status = 1;
911 } else if (byte == "xref"[inside_index]) {
912 inside_index ++;
913 } else {
914 --i;
915 status = 0;
916 }
917 break;
918 case 9:
919 if (byte == '\r' || byte == '\n') {
920 status = 0;
921 }
922 break;
923 case 10:
924 if (byte == ')') {
925 if (depth > 0) {
926 depth--;
927 }
928 } else if (byte == '(') {
929 depth++;
930 }
931 if (!depth) {
932 status = 0;
933 }
934 break;
935 case 11:
936 if (byte == '<' && inside_index == 1) {
937 status = 12;
938 } else if (byte == '>') {
939 status = 0;
940 }
941 inside_index = 0;
942 break;
943 case 12:
944 --i;
945 status = 0;
946 break;
947 case 13:
948 if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W') {
949 --i;
950 status = 0;
951 }
952 break;
953 case 14:
954 if (PDF_CharType[byte] == 'W') {
955 status = 0;
956 } else if (byte == '%' || byte == '(' || byte == '<' || byte == '\\') {
957 status = 0;
958 --i;
959 } else if (inside_index == 6) {
960 status = 0;
961 --i;
962 } else if (byte == "endobj"[inside_index]) {
963 inside_index++;
964 }
965 break;
966 }
967 if (bOverFlow) {
968 size = 0;
969 break;
970 }
971 }
972 pos += size;
973 }
974 if (last_xref != -1 && last_xref > last_obj) {
975 last_trailer = last_xref;
976 } else if (last_trailer == -1 || last_xref < last_obj) {
977 last_trailer = m_Syntax.m_FileLen;
978 }
979 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;
980 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOff set.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
981 if (pResult == NULL) {
982 m_SortedOffset.Add(offset);
983 }
984 FX_Free(buffer);
985 return TRUE;
986 }
987 static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n)
988 {
989 FX_DWORD result = 0;
990 for (int32_t i = 0; i < n; i ++) {
991 result = result * 256 + p[i];
992 }
993 return result;
994 }
995 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef)
996 {
997 CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL);
998 if (!pStream) {
999 return FALSE;
1000 }
1001 if (m_pDocument) {
1002 CPDF_Dictionary * pDict = m_pDocument->GetRoot();
1003 if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) {
1004 m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream);
1005 } else { 1337 } else {
1006 if (pStream->GetType() == PDFOBJ_STREAM) { 1338 syntax.GetDirectNum(); // Skip nextnum.
1007 pStream->Release(); 1339 FX_DWORD nextoff = syntax.GetDirectNum();
1008 } 1340 size = nextoff - thisoff;
1009 return FALSE; 1341 }
1010 } 1342 pBuffer = FX_Alloc(uint8_t, size);
1011 } 1343 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size);
1012 if (pStream->GetType() != PDFOBJ_STREAM) { 1344 return;
1013 return FALSE; 1345 }
1014 } 1346 n--;
1015 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); 1347 }
1016 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); 1348 return;
1017 if (size < 0) { 1349 }
1018 pStream->Release(); 1350 if (m_V5Type[objnum] == 1) {
1019 return FALSE;
1020 }
1021 if (bMainXRef) {
1022 m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone();
1023 m_CrossRef.SetSize(size);
1024 if (m_V5Type.SetSize(size)) {
1025 FXSYS_memset(m_V5Type.GetData(), 0, size);
1026 }
1027 } else {
1028 m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone());
1029 }
1030 std::vector<std::pair<int32_t, int32_t> > arrIndex;
1031 CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index"));
1032 if (pArray) {
1033 FX_DWORD nPairSize = pArray->GetCount() / 2;
1034 for (FX_DWORD i = 0; i < nPairSize; i++) {
1035 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2);
1036 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1);
1037 if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER
1038 && pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) {
1039 int nStartNum = pStartNumObj->GetInteger();
1040 int nCount = pCountObj->GetInteger();
1041 if (nStartNum >= 0 && nCount > 0) {
1042 arrIndex.push_back(std::make_pair(nStartNum, nCount));
1043 }
1044 }
1045 }
1046 }
1047 if (arrIndex.size() == 0) {
1048 arrIndex.push_back(std::make_pair(0, size));
1049 }
1050 pArray = pStream->GetDict()->GetArray(FX_BSTRC("W"));
1051 if (pArray == NULL) {
1052 pStream->Release();
1053 return FALSE;
1054 }
1055 CFX_DWordArray WidthArray;
1056 FX_SAFE_DWORD dwAccWidth = 0;
1057 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
1058 WidthArray.Add(pArray->GetInteger(i));
1059 dwAccWidth += WidthArray[i];
1060 }
1061 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) {
1062 pStream->Release();
1063 return FALSE;
1064 }
1065 FX_DWORD totalWidth = dwAccWidth.ValueOrDie();
1066 CPDF_StreamAcc acc;
1067 acc.LoadAllData(pStream);
1068 const uint8_t* pData = acc.GetData();
1069 FX_DWORD dwTotalSize = acc.GetSize();
1070 FX_DWORD segindex = 0;
1071 for (FX_DWORD i = 0; i < arrIndex.size(); i ++) {
1072 int32_t startnum = arrIndex[i].first;
1073 if (startnum < 0) {
1074 continue;
1075 }
1076 m_dwXrefStartObjNum = pdfium::base::checked_cast<FX_DWORD, int32_t> (sta rtnum);
1077 FX_DWORD count = pdfium::base::checked_cast<FX_DWORD, int32_t> (arrIndex [i].second);
1078 FX_SAFE_DWORD dwCaculatedSize = segindex;
1079 dwCaculatedSize += count;
1080 dwCaculatedSize *= totalWidth;
1081 if (!dwCaculatedSize.IsValid() || dwCaculatedSize.ValueOrDie() > dwTotal Size) {
1082 continue;
1083 }
1084 const uint8_t* segstart = pData + segindex * totalWidth;
1085 FX_SAFE_DWORD dwMaxObjNum = startnum;
1086 dwMaxObjNum += count;
1087 FX_DWORD dwV5Size = pdfium::base::checked_cast<FX_DWORD, int32_t> (m_V5T ype.GetSize());
1088 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) {
1089 continue;
1090 }
1091 for (FX_DWORD j = 0; j < count; j ++) {
1092 int32_t type = 1;
1093 const uint8_t* entrystart = segstart + j * totalWidth;
1094 if (WidthArray[0]) {
1095 type = _GetVarInt(entrystart, WidthArray[0]);
1096 }
1097 if (m_V5Type[startnum + j] == 255) {
1098 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], Widt hArray[1]);
1099 m_CrossRef[startnum + j] = offset;
1100 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1101 if (pResult == NULL) {
1102 m_SortedOffset.Add(offset);
1103 }
1104 continue;
1105 }
1106 if (m_V5Type[startnum + j]) {
1107 continue;
1108 }
1109 m_V5Type[startnum + j] = type;
1110 if (type == 0) {
1111 m_CrossRef[startnum + j] = 0;
1112 } else {
1113 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], Widt hArray[1]);
1114 m_CrossRef[startnum + j] = offset;
1115 if (type == 1) {
1116 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetDat a(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1117 if (pResult == NULL) {
1118 m_SortedOffset.Add(offset);
1119 }
1120 } else {
1121 if (offset < 0 || offset >= m_V5Type.GetSize()) {
1122 pStream->Release();
1123 return FALSE;
1124 }
1125 m_V5Type[offset] = 255;
1126 }
1127 }
1128 }
1129 segindex += count;
1130 }
1131 pStream->Release();
1132 return TRUE;
1133 }
1134 CPDF_Array* CPDF_Parser::GetIDArray()
1135 {
1136 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NUL L;
1137 if (pID == NULL) {
1138 return NULL;
1139 }
1140 if (pID->GetType() == PDFOBJ_REFERENCE) {
1141 pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());
1142 m_pTrailer->SetAt(FX_BSTRC("ID"), pID);
1143 }
1144 if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {
1145 return NULL;
1146 }
1147 return (CPDF_Array*)pID;
1148 }
1149 FX_DWORD CPDF_Parser::GetRootObjNum()
1150 {
1151 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL;
1152 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
1153 return 0;
1154 }
1155 return ((CPDF_Reference*) pRef)->GetRefObjNum();
1156 }
1157 FX_DWORD CPDF_Parser::GetInfoObjNum()
1158 {
1159 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL;
1160 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
1161 return 0;
1162 }
1163 return ((CPDF_Reference*) pRef)->GetRefObjNum();
1164 }
1165 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm)
1166 {
1167 bForm = FALSE;
1168 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1169 return TRUE;
1170 }
1171 if (m_V5Type[objnum] == 0) {
1172 return TRUE;
1173 }
1174 if (m_V5Type[objnum] == 2) {
1175 return TRUE;
1176 }
1177 FX_FILESIZE pos = m_CrossRef[objnum]; 1351 FX_FILESIZE pos = m_CrossRef[objnum];
1178 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset .GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); 1352 if (pos == 0) {
1179 if (pResult == NULL) { 1353 return;
1180 return TRUE; 1354 }
1181 }
1182 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_Sort edOffset.GetSize() - 1) {
1183 return FALSE;
1184 }
1185 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos;
1186 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1187 m_Syntax.RestorePos(pos);
1188 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0 ;
1189 m_Syntax.RestorePos(SavedPos);
1190 return TRUE;
1191 }
1192 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX _DWORD objnum, PARSE_CONTEXT* pContext)
1193 {
1194 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1195 return NULL;
1196 }
1197 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1198 FX_FILESIZE pos = m_CrossRef[objnum];
1199 if (pos <= 0) {
1200 return NULL;
1201 }
1202 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);
1203 }
1204 if (m_V5Type[objnum] == 2) {
1205 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum ]);
1206 if (pObjStream == NULL) {
1207 return NULL;
1208 }
1209 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
1210 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
1211 CPDF_SyntaxParser syntax;
1212 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pO bjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));
1213 syntax.InitParser(file.Get(), 0);
1214 CPDF_Object* pRet = NULL;
1215 while (n) {
1216 FX_DWORD thisnum = syntax.GetDirectNum();
1217 FX_DWORD thisoff = syntax.GetDirectNum();
1218 if (thisnum == objnum) {
1219 syntax.RestorePos(offset + thisoff);
1220 pRet = syntax.GetObject(pObjList, 0, 0, pContext);
1221 break;
1222 }
1223 n --;
1224 }
1225 return pRet;
1226 }
1227 return NULL;
1228 }
1229 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum)
1230 {
1231 CPDF_StreamAcc* pStreamAcc = NULL;
1232 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) {
1233 return pStreamAcc;
1234 }
1235 const CPDF_Stream* pStream = m_pDocument ? (CPDF_Stream*)m_pDocument->GetInd irectObject(objnum) : NULL;
1236 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
1237 return NULL;
1238 }
1239 pStreamAcc = new CPDF_StreamAcc;
1240 pStreamAcc->LoadAllData(pStream);
1241 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc);
1242 return pStreamAcc;
1243 }
1244 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum)
1245 {
1246 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1247 return 0;
1248 }
1249 if (m_V5Type[objnum] == 2) {
1250 objnum = (FX_DWORD)m_CrossRef[objnum];
1251 }
1252 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1253 FX_FILESIZE offset = m_CrossRef[objnum];
1254 if (offset == 0) {
1255 return 0;
1256 }
1257 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_Sorte dOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1258 if (pResult == NULL) {
1259 return 0;
1260 }
1261 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_ SortedOffset.GetSize() - 1) {
1262 return 0;
1263 }
1264 return ((FX_FILESIZE*)pResult)[1] - offset;
1265 }
1266 return 0;
1267 }
1268 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, uint8_t*& pBuffer, FX_DWORD & size)
1269 {
1270 pBuffer = NULL;
1271 size = 0;
1272 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1273 return;
1274 }
1275 if (m_V5Type[objnum] == 2) {
1276 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum ]);
1277 if (pObjStream == NULL) {
1278 return;
1279 }
1280 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
1281 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
1282 CPDF_SyntaxParser syntax;
1283 const uint8_t* pData = pObjStream->GetData();
1284 FX_DWORD totalsize = pObjStream->GetSize();
1285 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pD ata, (size_t)totalsize, FALSE));
1286 syntax.InitParser(file.Get(), 0);
1287 while (n) {
1288 FX_DWORD thisnum = syntax.GetDirectNum();
1289 FX_DWORD thisoff = syntax.GetDirectNum();
1290 if (thisnum == objnum) {
1291 if (n == 1) {
1292 size = totalsize - (thisoff + offset);
1293 } else {
1294 syntax.GetDirectNum(); // Skip nextnum.
1295 FX_DWORD nextoff = syntax.GetDirectNum();
1296 size = nextoff - thisoff;
1297 }
1298 pBuffer = FX_Alloc(uint8_t, size);
1299 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size);
1300 return;
1301 }
1302 n --;
1303 }
1304 return;
1305 }
1306 if (m_V5Type[objnum] == 1) {
1307 FX_FILESIZE pos = m_CrossRef[objnum];
1308 if (pos == 0) {
1309 return;
1310 }
1311 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1312 m_Syntax.RestorePos(pos);
1313 FX_BOOL bIsNumber;
1314 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1315 if (!bIsNumber) {
1316 m_Syntax.RestorePos(SavedPos);
1317 return;
1318 }
1319 FX_DWORD parser_objnum = FXSYS_atoi(word);
1320 if (parser_objnum && parser_objnum != objnum) {
1321 m_Syntax.RestorePos(SavedPos);
1322 return;
1323 }
1324 word = m_Syntax.GetNextWord(bIsNumber);
1325 if (!bIsNumber) {
1326 m_Syntax.RestorePos(SavedPos);
1327 return;
1328 }
1329 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1330 m_Syntax.RestorePos(SavedPos);
1331 return;
1332 }
1333 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOf fset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1334 if (pResult == NULL) {
1335 m_Syntax.RestorePos(SavedPos);
1336 return;
1337 }
1338 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1];
1339 FX_BOOL bNextOffValid = FALSE;
1340 if (nextoff != pos) {
1341 m_Syntax.RestorePos(nextoff);
1342 word = m_Syntax.GetNextWord(bIsNumber);
1343 if (word == FX_BSTRC("xref")) {
1344 bNextOffValid = TRUE;
1345 } else if (bIsNumber) {
1346 word = m_Syntax.GetNextWord(bIsNumber);
1347 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) {
1348 bNextOffValid = TRUE;
1349 }
1350 }
1351 }
1352 if (!bNextOffValid) {
1353 m_Syntax.RestorePos(pos);
1354 while (1) {
1355 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) {
1356 break;
1357 }
1358 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) {
1359 break;
1360 }
1361 }
1362 nextoff = m_Syntax.SavePos();
1363 }
1364 size = (FX_DWORD)(nextoff - pos);
1365 pBuffer = FX_Alloc(uint8_t, size);
1366 m_Syntax.RestorePos(pos);
1367 m_Syntax.ReadBlock(pBuffer, size);
1368 m_Syntax.RestorePos(SavedPos);
1369 }
1370 }
1371 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
1372 PARSE_CONTEXT* pContext)
1373 {
1374 FX_FILESIZE SavedPos = m_Syntax.SavePos(); 1355 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1375 m_Syntax.RestorePos(pos); 1356 m_Syntax.RestorePos(pos);
1376 FX_BOOL bIsNumber; 1357 FX_BOOL bIsNumber;
1377 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); 1358 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1378 if (!bIsNumber) { 1359 if (!bIsNumber) {
1379 m_Syntax.RestorePos(SavedPos); 1360 m_Syntax.RestorePos(SavedPos);
1380 return NULL; 1361 return;
1381 } 1362 }
1382 FX_FILESIZE objOffset = m_Syntax.SavePos();
1383 objOffset -= word.GetLength();
1384 FX_DWORD parser_objnum = FXSYS_atoi(word); 1363 FX_DWORD parser_objnum = FXSYS_atoi(word);
1385 if (objnum && parser_objnum != objnum) { 1364 if (parser_objnum && parser_objnum != objnum) {
1386 m_Syntax.RestorePos(SavedPos); 1365 m_Syntax.RestorePos(SavedPos);
1387 return NULL; 1366 return;
1388 } 1367 }
1389 word = m_Syntax.GetNextWord(bIsNumber); 1368 word = m_Syntax.GetNextWord(bIsNumber);
1390 if (!bIsNumber) { 1369 if (!bIsNumber) {
1391 m_Syntax.RestorePos(SavedPos); 1370 m_Syntax.RestorePos(SavedPos);
1392 return NULL; 1371 return;
1393 } 1372 }
1394 FX_DWORD parser_gennum = FXSYS_atoi(word);
1395 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { 1373 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1396 m_Syntax.RestorePos(SavedPos); 1374 m_Syntax.RestorePos(SavedPos);
1397 return NULL; 1375 return;
1398 } 1376 }
1399 CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, parser_gennum, pCon text); 1377 void* pResult =
1378 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
1379 sizeof(FX_FILESIZE), _CompareFileSize);
1380 if (pResult == NULL) {
1381 m_Syntax.RestorePos(SavedPos);
1382 return;
1383 }
1384 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1];
1385 FX_BOOL bNextOffValid = FALSE;
1386 if (nextoff != pos) {
1387 m_Syntax.RestorePos(nextoff);
1388 word = m_Syntax.GetNextWord(bIsNumber);
1389 if (word == FX_BSTRC("xref")) {
1390 bNextOffValid = TRUE;
1391 } else if (bIsNumber) {
1392 word = m_Syntax.GetNextWord(bIsNumber);
1393 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) {
1394 bNextOffValid = TRUE;
1395 }
1396 }
1397 }
1398 if (!bNextOffValid) {
1399 m_Syntax.RestorePos(pos);
1400 while (1) {
1401 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) {
1402 break;
1403 }
1404 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) {
1405 break;
1406 }
1407 }
1408 nextoff = m_Syntax.SavePos();
1409 }
1410 size = (FX_DWORD)(nextoff - pos);
1411 pBuffer = FX_Alloc(uint8_t, size);
1412 m_Syntax.RestorePos(pos);
1413 m_Syntax.ReadBlock(pBuffer, size);
1414 m_Syntax.RestorePos(SavedPos);
1415 }
1416 }
1417 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList,
1418 FX_FILESIZE pos,
1419 FX_DWORD objnum,
1420 PARSE_CONTEXT* pContext) {
1421 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1422 m_Syntax.RestorePos(pos);
1423 FX_BOOL bIsNumber;
1424 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1425 if (!bIsNumber) {
1426 m_Syntax.RestorePos(SavedPos);
1427 return NULL;
1428 }
1429 FX_FILESIZE objOffset = m_Syntax.SavePos();
1430 objOffset -= word.GetLength();
1431 FX_DWORD parser_objnum = FXSYS_atoi(word);
1432 if (objnum && parser_objnum != objnum) {
1433 m_Syntax.RestorePos(SavedPos);
1434 return NULL;
1435 }
1436 word = m_Syntax.GetNextWord(bIsNumber);
1437 if (!bIsNumber) {
1438 m_Syntax.RestorePos(SavedPos);
1439 return NULL;
1440 }
1441 FX_DWORD parser_gennum = FXSYS_atoi(word);
1442 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1443 m_Syntax.RestorePos(SavedPos);
1444 return NULL;
1445 }
1446 CPDF_Object* pObj =
1447 m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext);
1448 m_Syntax.SavePos();
1449 CFX_ByteString bsWord = m_Syntax.GetKeyword();
1450 if (bsWord == FX_BSTRC("endobj")) {
1400 m_Syntax.SavePos(); 1451 m_Syntax.SavePos();
1401 CFX_ByteString bsWord = m_Syntax.GetKeyword(); 1452 }
1402 if (bsWord == FX_BSTRC("endobj")) { 1453 m_Syntax.RestorePos(SavedPos);
1403 m_Syntax.SavePos(); 1454 if (pObj) {
1404 } 1455 if (!objnum) {
1456 pObj->m_ObjNum = parser_objnum;
1457 }
1458 pObj->m_GenNum = parser_gennum;
1459 }
1460 return pObj;
1461 }
1462 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(
1463 CPDF_IndirectObjects* pObjList,
1464 FX_FILESIZE pos,
1465 FX_DWORD objnum,
1466 struct PARSE_CONTEXT* pContext,
1467 FX_FILESIZE* pResultPos) {
1468 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1469 m_Syntax.RestorePos(pos);
1470 FX_BOOL bIsNumber;
1471 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1472 if (!bIsNumber) {
1405 m_Syntax.RestorePos(SavedPos); 1473 m_Syntax.RestorePos(SavedPos);
1474 return NULL;
1475 }
1476 FX_DWORD parser_objnum = FXSYS_atoi(word);
1477 if (objnum && parser_objnum != objnum) {
1478 m_Syntax.RestorePos(SavedPos);
1479 return NULL;
1480 }
1481 word = m_Syntax.GetNextWord(bIsNumber);
1482 if (!bIsNumber) {
1483 m_Syntax.RestorePos(SavedPos);
1484 return NULL;
1485 }
1486 FX_DWORD gennum = FXSYS_atoi(word);
1487 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1488 m_Syntax.RestorePos(SavedPos);
1489 return NULL;
1490 }
1491 CPDF_Object* pObj =
1492 m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext);
1493 if (pResultPos) {
1494 *pResultPos = m_Syntax.m_Pos;
1495 }
1496 m_Syntax.RestorePos(SavedPos);
1497 return pObj;
1498 }
1499 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() {
1500 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) {
1501 return NULL;
1502 }
1503 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
1504 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) {
1406 if (pObj) { 1505 if (pObj) {
1407 if (!objnum) { 1506 pObj->Release();
1408 pObj->m_ObjNum = parser_objnum; 1507 }
1409 } 1508 return NULL;
1410 pObj->m_GenNum = parser_gennum; 1509 }
1411 } 1510 return (CPDF_Dictionary*)pObj;
1412 return pObj; 1511 }
1413 } 1512 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) {
1414 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pO bjList, FX_FILESIZE pos, FX_DWORD objnum, 1513 if (m_pSecurityHandler == NULL) {
1415 struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos) 1514 return (FX_DWORD)-1;
1416 { 1515 }
1417 FX_FILESIZE SavedPos = m_Syntax.SavePos(); 1516 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions();
1418 m_Syntax.RestorePos(pos); 1517 if (m_pEncryptDict &&
1419 FX_BOOL bIsNumber; 1518 m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) {
1420 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); 1519 dwPermission &= 0xFFFFFFFC;
1421 if (!bIsNumber) { 1520 dwPermission |= 0xFFFFF0C0;
1422 m_Syntax.RestorePos(SavedPos); 1521 if (bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) {
1423 return NULL; 1522 dwPermission &= 0xFFFFF0FF;
1424 } 1523 }
1425 FX_DWORD parser_objnum = FXSYS_atoi(word); 1524 }
1426 if (objnum && parser_objnum != objnum) { 1525 return dwPermission;
1427 m_Syntax.RestorePos(SavedPos); 1526 }
1428 return NULL; 1527 FX_BOOL CPDF_Parser::IsOwner() {
1429 } 1528 return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner();
1430 word = m_Syntax.GetNextWord(bIsNumber); 1529 }
1431 if (!bIsNumber) { 1530 void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler,
1432 m_Syntax.RestorePos(SavedPos); 1531 FX_BOOL bForced) {
1433 return NULL; 1532 ASSERT(m_pSecurityHandler == NULL);
1434 } 1533 if (!m_bForceUseSecurityHandler) {
1435 FX_DWORD gennum = FXSYS_atoi(word); 1534 delete m_pSecurityHandler;
1436 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { 1535 m_pSecurityHandler = NULL;
1437 m_Syntax.RestorePos(SavedPos); 1536 }
1438 return NULL; 1537 m_bForceUseSecurityHandler = bForced;
1439 } 1538 m_pSecurityHandler = pSecurityHandler;
1440 CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pCo ntext); 1539 if (m_bForceUseSecurityHandler) {
1441 if (pResultPos) { 1540 return;
1442 *pResultPos = m_Syntax.m_Pos; 1541 }
1443 } 1542 m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler();
1543 m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler);
1544 }
1545 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess,
1546 FX_DWORD offset) {
1547 m_Syntax.InitParser(pFileAccess, offset);
1548 m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9);
1549 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1550 FX_BOOL bIsNumber;
1551 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1552 if (!bIsNumber) {
1553 return FALSE;
1554 }
1555 FX_DWORD objnum = FXSYS_atoi(word);
1556 word = m_Syntax.GetNextWord(bIsNumber);
1557 if (!bIsNumber) {
1558 return FALSE;
1559 }
1560 FX_DWORD gennum = FXSYS_atoi(word);
1561 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1444 m_Syntax.RestorePos(SavedPos); 1562 m_Syntax.RestorePos(SavedPos);
1445 return pObj; 1563 return FALSE;
1446 } 1564 }
1447 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() 1565 m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0);
1448 { 1566 if (!m_pLinearized) {
1449 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { 1567 return FALSE;
1450 return NULL; 1568 }
1451 } 1569 if (m_pLinearized->GetDict() &&
1452 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); 1570 m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {
1453 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { 1571 m_Syntax.GetNextWord(bIsNumber);
1454 if (pObj) { 1572 CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
1455 pObj->Release(); 1573 if (!pLen) {
1456 } 1574 m_pLinearized->Release();
1457 return NULL; 1575 m_pLinearized = NULL;
1458 } 1576 return FALSE;
1459 return (CPDF_Dictionary*)pObj; 1577 }
1460 } 1578 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) {
1461 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) 1579 return FALSE;
1462 { 1580 }
1463 if (m_pSecurityHandler == NULL) { 1581 CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
1464 return (FX_DWORD) - 1; 1582 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
1465 } 1583 m_dwFirstPageNo = pNo->GetInteger();
1466 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); 1584 }
1467 if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BS TRC("Standard")) { 1585 CPDF_Object* pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T"));
1468 dwPermission &= 0xFFFFFFFC; 1586 if (pTable && pTable->GetType() == PDFOBJ_NUMBER) {
1469 dwPermission |= 0xFFFFF0C0; 1587 m_LastXRefOffset = pTable->GetInteger();
1470 if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { 1588 }
1471 dwPermission &= 0xFFFFF0FF; 1589 return TRUE;
1472 } 1590 }
1473 } 1591 m_pLinearized->Release();
1474 return dwPermission; 1592 m_pLinearized = NULL;
1475 } 1593 return FALSE;
1476 FX_BOOL CPDF_Parser::IsOwner() 1594 }
1477 { 1595 FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess,
1478 return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner(); 1596 FX_BOOL bReParse,
1479 } 1597 FX_BOOL bOwnFileRead) {
1480 void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_ BOOL bForced) 1598 CloseParser(bReParse);
1481 { 1599 m_bXRefStream = FALSE;
1482 ASSERT(m_pSecurityHandler == NULL); 1600 m_LastXRefOffset = 0;
1483 if (!m_bForceUseSecurityHandler) { 1601 m_bOwnFileRead = bOwnFileRead;
1484 delete m_pSecurityHandler; 1602 int32_t offset = GetHeaderOffset(pFileAccess);
1485 m_pSecurityHandler = NULL; 1603 if (offset == -1) {
1486 } 1604 return PDFPARSE_ERROR_FORMAT;
1487 m_bForceUseSecurityHandler = bForced; 1605 }
1488 m_pSecurityHandler = pSecurityHandler; 1606 if (!IsLinearizedFile(pFileAccess, offset)) {
1489 if (m_bForceUseSecurityHandler) { 1607 m_Syntax.m_pFileAccess = NULL;
1490 return; 1608 return StartParse(pFileAccess, bReParse, bOwnFileRead);
1491 } 1609 }
1492 m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); 1610 if (!bReParse) {
1493 m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler); 1611 m_pDocument = new CPDF_Document(this);
1494 } 1612 }
1495 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset ) 1613 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos();
1496 { 1614 FX_BOOL bXRefRebuilt = FALSE;
1497 m_Syntax.InitParser(pFileAccess, offset); 1615 FX_BOOL bLoadV4 = FALSE;
1498 m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9); 1616 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) &&
1499 FX_FILESIZE SavedPos = m_Syntax.SavePos(); 1617 !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) {
1500 FX_BOOL bIsNumber; 1618 if (!RebuildCrossRef()) {
1501 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); 1619 return PDFPARSE_ERROR_FORMAT;
1502 if (!bIsNumber) { 1620 }
1503 return FALSE; 1621 bXRefRebuilt = TRUE;
1504 }
1505 FX_DWORD objnum = FXSYS_atoi(word);
1506 word = m_Syntax.GetNextWord(bIsNumber);
1507 if (!bIsNumber) {
1508 return FALSE;
1509 }
1510 FX_DWORD gennum = FXSYS_atoi(word);
1511 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1512 m_Syntax.RestorePos(SavedPos);
1513 return FALSE;
1514 }
1515 m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0);
1516 if (!m_pLinearized) {
1517 return FALSE;
1518 }
1519 if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTR C("Linearized"))) {
1520 m_Syntax.GetNextWord(bIsNumber);
1521 CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
1522 if (!pLen) {
1523 m_pLinearized->Release();
1524 m_pLinearized = NULL;
1525 return FALSE;
1526 }
1527 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) {
1528 return FALSE;
1529 }
1530 CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
1531 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
1532 m_dwFirstPageNo = pNo->GetInteger();
1533 }
1534 CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T") );
1535 if (pTable && pTable->GetType() == PDFOBJ_NUMBER) {
1536 m_LastXRefOffset = pTable->GetInteger();
1537 }
1538 return TRUE;
1539 }
1540 m_pLinearized->Release();
1541 m_pLinearized = NULL;
1542 return FALSE;
1543 }
1544 FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse , FX_BOOL bOwnFileRead)
1545 {
1546 CloseParser(bReParse);
1547 m_bXRefStream = FALSE;
1548 m_LastXRefOffset = 0; 1622 m_LastXRefOffset = 0;
1549 m_bOwnFileRead = bOwnFileRead; 1623 }
1550 int32_t offset = GetHeaderOffset(pFileAccess); 1624 if (bLoadV4) {
1551 if (offset == -1) { 1625 m_pTrailer = LoadTrailerV4();
1552 return PDFPARSE_ERROR_FORMAT; 1626 if (m_pTrailer == NULL) {
1553 } 1627 return FALSE;
1554 if (!IsLinearizedFile(pFileAccess, offset)) { 1628 }
1555 m_Syntax.m_pFileAccess = NULL; 1629 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
1556 return StartParse(pFileAccess, bReParse, bOwnFileRead); 1630 if (xrefsize > 0) {
1557 } 1631 m_CrossRef.SetSize(xrefsize);
1558 if (!bReParse) { 1632 m_V5Type.SetSize(xrefsize);
1559 m_pDocument = new CPDF_Document(this); 1633 }
1560 } 1634 }
1561 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); 1635 FX_DWORD dwRet = SetEncryptHandler();
1562 FX_BOOL bXRefRebuilt = FALSE; 1636 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1563 FX_BOOL bLoadV4 = FALSE; 1637 return dwRet;
1564 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !Load CrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { 1638 }
1565 if (!RebuildCrossRef()) { 1639 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
1566 return PDFPARSE_ERROR_FORMAT; 1640 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
1567 } 1641 if (bXRefRebuilt) {
1568 bXRefRebuilt = TRUE; 1642 return PDFPARSE_ERROR_FORMAT;
1569 m_LastXRefOffset = 0; 1643 }
1570 } 1644 ReleaseEncryptHandler();
1571 if (bLoadV4) { 1645 if (!RebuildCrossRef()) {
1572 m_pTrailer = LoadTrailerV4(); 1646 return PDFPARSE_ERROR_FORMAT;
1573 if (m_pTrailer == NULL) { 1647 }
1574 return FALSE; 1648 dwRet = SetEncryptHandler();
1575 }
1576 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
1577 if (xrefsize > 0) {
1578 m_CrossRef.SetSize(xrefsize);
1579 m_V5Type.SetSize(xrefsize);
1580 }
1581 }
1582 FX_DWORD dwRet = SetEncryptHandler();
1583 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 1649 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1584 return dwRet; 1650 return dwRet;
1585 } 1651 }
1586 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); 1652 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
1587 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { 1653 if (m_pDocument->GetRoot() == NULL) {
1588 if (bXRefRebuilt) { 1654 return PDFPARSE_ERROR_FORMAT;
1589 return PDFPARSE_ERROR_FORMAT; 1655 }
1590 } 1656 }
1591 ReleaseEncryptHandler(); 1657 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
1592 if (!RebuildCrossRef()) { 1658 sizeof(FX_FILESIZE), _CompareFileSize);
1593 return PDFPARSE_ERROR_FORMAT; 1659 FX_DWORD RootObjNum = GetRootObjNum();
1594 } 1660 if (RootObjNum == 0) {
1595 dwRet = SetEncryptHandler(); 1661 ReleaseEncryptHandler();
1596 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 1662 RebuildCrossRef();
1597 return dwRet; 1663 RootObjNum = GetRootObjNum();
1598 }
1599 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
1600 if (m_pDocument->GetRoot() == NULL) {
1601 return PDFPARSE_ERROR_FORMAT;
1602 }
1603 }
1604 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI LESIZE), _CompareFileSize);
1605 FX_DWORD RootObjNum = GetRootObjNum();
1606 if (RootObjNum == 0) { 1664 if (RootObjNum == 0) {
1607 ReleaseEncryptHandler(); 1665 return PDFPARSE_ERROR_FORMAT;
1608 RebuildCrossRef(); 1666 }
1609 RootObjNum = GetRootObjNum(); 1667 dwRet = SetEncryptHandler();
1610 if (RootObjNum == 0) { 1668 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1611 return PDFPARSE_ERROR_FORMAT; 1669 return dwRet;
1612 } 1670 }
1613 dwRet = SetEncryptHandler(); 1671 }
1614 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 1672 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {
1615 return dwRet; 1673 CPDF_Object* pMetadata =
1616 } 1674 m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));
1617 } 1675 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
1618 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { 1676 m_Syntax.m_MetadataObjnum = ((CPDF_Reference*)pMetadata)->GetRefObjNum();
1619 CPDF_Object* pMetadata = m_pDocument->GetRoot()->GetElement(FX_BSTRC("Me tadata")); 1677 }
1620 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { 1678 }
1621 m_Syntax.m_MetadataObjnum = ((CPDF_Reference*) pMetadata)->GetRefObj Num(); 1679 return PDFPARSE_ERROR_SUCCESS;
1622 } 1680 }
1623 } 1681 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) {
1624 return PDFPARSE_ERROR_SUCCESS; 1682 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
1625 } 1683 return FALSE;
1626 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) 1684 }
1627 { 1685 while (xrefpos)
1628 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { 1686 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
1629 return FALSE; 1687 return FALSE;
1630 } 1688 }
1631 while (xrefpos) 1689 m_ObjectStreamMap.InitHashTable(101, FALSE);
1632 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { 1690 m_bXRefStream = TRUE;
1633 return FALSE; 1691 return TRUE;
1634 } 1692 }
1635 m_ObjectStreamMap.InitHashTable(101, FALSE); 1693 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() {
1636 m_bXRefStream = TRUE; 1694 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum;
1637 return TRUE; 1695 m_Syntax.m_MetadataObjnum = 0;
1638 } 1696 if (m_pTrailer) {
1639 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() 1697 m_pTrailer->Release();
1640 { 1698 m_pTrailer = NULL;
1641 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; 1699 }
1642 m_Syntax.m_MetadataObjnum = 0; 1700 m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset);
1643 if (m_pTrailer) { 1701 uint8_t ch = 0;
1644 m_pTrailer->Release(); 1702 FX_DWORD dwCount = 0;
1645 m_pTrailer = NULL; 1703 m_Syntax.GetNextChar(ch);
1646 } 1704 int32_t type = PDF_CharType[ch];
1647 m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset); 1705 while (type == 'W') {
1648 uint8_t ch = 0; 1706 ++dwCount;
1649 FX_DWORD dwCount = 0; 1707 if (m_Syntax.m_FileLen >=
1708 (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) {
1709 break;
1710 }
1650 m_Syntax.GetNextChar(ch); 1711 m_Syntax.GetNextChar(ch);
1651 int32_t type = PDF_CharType[ch]; 1712 type = PDF_CharType[ch];
1652 while (type == 'W') { 1713 }
1653 ++dwCount; 1714 m_LastXRefOffset += dwCount;
1654 if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_ HeaderOffset)) { 1715 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
1655 break; 1716 while (pos) {
1656 } 1717 void* objnum;
1657 m_Syntax.GetNextChar(ch); 1718 CPDF_StreamAcc* pStream;
1658 type = PDF_CharType[ch]; 1719 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
1659 } 1720 delete pStream;
1660 m_LastXRefOffset += dwCount; 1721 }
1661 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); 1722 m_ObjectStreamMap.RemoveAll();
1662 while (pos) { 1723 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) &&
1663 void* objnum; 1724 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
1664 CPDF_StreamAcc* pStream; 1725 m_LastXRefOffset = 0;
1665 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
1666 delete pStream;
1667 }
1668 m_ObjectStreamMap.RemoveAll();
1669 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && ! LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
1670 m_LastXRefOffset = 0;
1671 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
1672 return PDFPARSE_ERROR_FORMAT;
1673 }
1674 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI LESIZE), _CompareFileSize);
1675 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; 1726 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
1676 return PDFPARSE_ERROR_SUCCESS; 1727 return PDFPARSE_ERROR_FORMAT;
1728 }
1729 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
1730 sizeof(FX_FILESIZE), _CompareFileSize);
1731 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
1732 return PDFPARSE_ERROR_SUCCESS;
1677 } 1733 }
1678 1734
1679 // static 1735 // static
1680 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; 1736 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0;
1681 1737
1682 CPDF_SyntaxParser::CPDF_SyntaxParser() 1738 CPDF_SyntaxParser::CPDF_SyntaxParser() {
1683 { 1739 m_pFileAccess = NULL;
1684 m_pFileAccess = NULL; 1740 m_pCryptoHandler = NULL;
1685 m_pCryptoHandler = NULL; 1741 m_pFileBuf = NULL;
1742 m_BufSize = CPDF_ModuleMgr::kFileBufSize;
1743 m_pFileBuf = NULL;
1744 m_MetadataObjnum = 0;
1745 m_dwWordPos = 0;
1746 m_bFileStream = FALSE;
1747 }
1748 CPDF_SyntaxParser::~CPDF_SyntaxParser() {
1749 if (m_pFileBuf) {
1750 FX_Free(m_pFileBuf);
1751 }
1752 }
1753 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) {
1754 FX_FILESIZE save_pos = m_Pos;
1755 m_Pos = pos;
1756 FX_BOOL ret = GetNextChar(ch);
1757 m_Pos = save_pos;
1758 return ret;
1759 }
1760 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) {
1761 FX_FILESIZE pos = m_Pos + m_HeaderOffset;
1762 if (pos >= m_FileLen) {
1763 return FALSE;
1764 }
1765 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
1766 FX_FILESIZE read_pos = pos;
1767 FX_DWORD read_size = m_BufSize;
1768 if ((FX_FILESIZE)read_size > m_FileLen) {
1769 read_size = (FX_DWORD)m_FileLen;
1770 }
1771 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
1772 if (m_FileLen < (FX_FILESIZE)read_size) {
1773 read_pos = 0;
1774 read_size = (FX_DWORD)m_FileLen;
1775 } else {
1776 read_pos = m_FileLen - read_size;
1777 }
1778 }
1779 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
1780 return FALSE;
1781 }
1782 m_BufOffset = read_pos;
1783 }
1784 ch = m_pFileBuf[pos - m_BufOffset];
1785 m_Pos++;
1786 return TRUE;
1787 }
1788 FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) {
1789 pos += m_HeaderOffset;
1790 if (pos >= m_FileLen) {
1791 return FALSE;
1792 }
1793 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
1794 FX_FILESIZE read_pos;
1795 if (pos < (FX_FILESIZE)m_BufSize) {
1796 read_pos = 0;
1797 } else {
1798 read_pos = pos - m_BufSize + 1;
1799 }
1800 FX_DWORD read_size = m_BufSize;
1801 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
1802 if (m_FileLen < (FX_FILESIZE)read_size) {
1803 read_pos = 0;
1804 read_size = (FX_DWORD)m_FileLen;
1805 } else {
1806 read_pos = m_FileLen - read_size;
1807 }
1808 }
1809 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
1810 return FALSE;
1811 }
1812 m_BufOffset = read_pos;
1813 }
1814 ch = m_pFileBuf[pos - m_BufOffset];
1815 return TRUE;
1816 }
1817 FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) {
1818 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) {
1819 return FALSE;
1820 }
1821 m_Pos += size;
1822 return TRUE;
1823 }
1824 #define MAX_WORD_BUFFER 256
1825 void CPDF_SyntaxParser::GetNextWord() {
1826 m_WordSize = 0;
1827 m_bIsNumber = TRUE;
1828 uint8_t ch;
1829 if (!GetNextChar(ch)) {
1830 return;
1831 }
1832 uint8_t type = PDF_CharType[ch];
1833 while (1) {
1834 while (type == 'W') {
1835 if (!GetNextChar(ch)) {
1836 return;
1837 }
1838 type = PDF_CharType[ch];
1839 }
1840 if (ch != '%') {
1841 break;
1842 }
1843 while (1) {
1844 if (!GetNextChar(ch)) {
1845 return;
1846 }
1847 if (ch == '\r' || ch == '\n') {
1848 break;
1849 }
1850 }
1851 type = PDF_CharType[ch];
1852 }
1853 if (type == 'D') {
1854 m_bIsNumber = FALSE;
1855 m_WordBuffer[m_WordSize++] = ch;
1856 if (ch == '/') {
1857 while (1) {
1858 if (!GetNextChar(ch)) {
1859 return;
1860 }
1861 type = PDF_CharType[ch];
1862 if (type != 'R' && type != 'N') {
1863 m_Pos--;
1864 return;
1865 }
1866 if (m_WordSize < MAX_WORD_BUFFER) {
1867 m_WordBuffer[m_WordSize++] = ch;
1868 }
1869 }
1870 } else if (ch == '<') {
1871 if (!GetNextChar(ch)) {
1872 return;
1873 }
1874 if (ch == '<') {
1875 m_WordBuffer[m_WordSize++] = ch;
1876 } else {
1877 m_Pos--;
1878 }
1879 } else if (ch == '>') {
1880 if (!GetNextChar(ch)) {
1881 return;
1882 }
1883 if (ch == '>') {
1884 m_WordBuffer[m_WordSize++] = ch;
1885 } else {
1886 m_Pos--;
1887 }
1888 }
1889 return;
1890 }
1891 while (1) {
1892 if (m_WordSize < MAX_WORD_BUFFER) {
1893 m_WordBuffer[m_WordSize++] = ch;
1894 }
1895 if (type != 'N') {
1896 m_bIsNumber = FALSE;
1897 }
1898 if (!GetNextChar(ch)) {
1899 return;
1900 }
1901 type = PDF_CharType[ch];
1902 if (type == 'D' || type == 'W') {
1903 m_Pos--;
1904 break;
1905 }
1906 }
1907 }
1908 CFX_ByteString CPDF_SyntaxParser::ReadString() {
1909 uint8_t ch;
1910 if (!GetNextChar(ch)) {
1911 return CFX_ByteString();
1912 }
1913 CFX_ByteTextBuf buf;
1914 int32_t parlevel = 0;
1915 int32_t status = 0, iEscCode = 0;
1916 while (1) {
1917 switch (status) {
1918 case 0:
1919 if (ch == ')') {
1920 if (parlevel == 0) {
1921 return buf.GetByteString();
1922 }
1923 parlevel--;
1924 buf.AppendChar(')');
1925 } else if (ch == '(') {
1926 parlevel++;
1927 buf.AppendChar('(');
1928 } else if (ch == '\\') {
1929 status = 1;
1930 } else {
1931 buf.AppendChar(ch);
1932 }
1933 break;
1934 case 1:
1935 if (ch >= '0' && ch <= '7') {
1936 iEscCode = ch - '0';
1937 status = 2;
1938 break;
1939 }
1940 if (ch == 'n') {
1941 buf.AppendChar('\n');
1942 } else if (ch == 'r') {
1943 buf.AppendChar('\r');
1944 } else if (ch == 't') {
1945 buf.AppendChar('\t');
1946 } else if (ch == 'b') {
1947 buf.AppendChar('\b');
1948 } else if (ch == 'f') {
1949 buf.AppendChar('\f');
1950 } else if (ch == '\r') {
1951 status = 4;
1952 break;
1953 } else if (ch == '\n') {
1954 } else {
1955 buf.AppendChar(ch);
1956 }
1957 status = 0;
1958 break;
1959 case 2:
1960 if (ch >= '0' && ch <= '7') {
1961 iEscCode = iEscCode * 8 + ch - '0';
1962 status = 3;
1963 } else {
1964 buf.AppendChar(iEscCode);
1965 status = 0;
1966 continue;
1967 }
1968 break;
1969 case 3:
1970 if (ch >= '0' && ch <= '7') {
1971 iEscCode = iEscCode * 8 + ch - '0';
1972 buf.AppendChar(iEscCode);
1973 status = 0;
1974 } else {
1975 buf.AppendChar(iEscCode);
1976 status = 0;
1977 continue;
1978 }
1979 break;
1980 case 4:
1981 status = 0;
1982 if (ch != '\n') {
1983 continue;
1984 }
1985 break;
1986 }
1987 if (!GetNextChar(ch)) {
1988 break;
1989 }
1990 }
1991 GetNextChar(ch);
1992 return buf.GetByteString();
1993 }
1994 CFX_ByteString CPDF_SyntaxParser::ReadHexString() {
1995 uint8_t ch;
1996 if (!GetNextChar(ch)) {
1997 return CFX_ByteString();
1998 }
1999 CFX_BinaryBuf buf;
2000 FX_BOOL bFirst = TRUE;
2001 uint8_t code = 0;
2002 while (1) {
2003 if (ch == '>') {
2004 break;
2005 }
2006 if (ch >= '0' && ch <= '9') {
2007 if (bFirst) {
2008 code = (ch - '0') * 16;
2009 } else {
2010 code += ch - '0';
2011 buf.AppendByte((uint8_t)code);
2012 }
2013 bFirst = !bFirst;
2014 } else if (ch >= 'A' && ch <= 'F') {
2015 if (bFirst) {
2016 code = (ch - 'A' + 10) * 16;
2017 } else {
2018 code += ch - 'A' + 10;
2019 buf.AppendByte((uint8_t)code);
2020 }
2021 bFirst = !bFirst;
2022 } else if (ch >= 'a' && ch <= 'f') {
2023 if (bFirst) {
2024 code = (ch - 'a' + 10) * 16;
2025 } else {
2026 code += ch - 'a' + 10;
2027 buf.AppendByte((uint8_t)code);
2028 }
2029 bFirst = !bFirst;
2030 }
2031 if (!GetNextChar(ch)) {
2032 break;
2033 }
2034 }
2035 if (!bFirst) {
2036 buf.AppendByte((uint8_t)code);
2037 }
2038 return buf.GetByteString();
2039 }
2040 void CPDF_SyntaxParser::ToNextLine() {
2041 uint8_t ch;
2042 while (GetNextChar(ch)) {
2043 if (ch == '\n') {
2044 break;
2045 }
2046 if (ch == '\r') {
2047 GetNextChar(ch);
2048 if (ch != '\n') {
2049 --m_Pos;
2050 }
2051 break;
2052 }
2053 }
2054 }
2055 void CPDF_SyntaxParser::ToNextWord() {
2056 uint8_t ch;
2057 if (!GetNextChar(ch)) {
2058 return;
2059 }
2060 uint8_t type = PDF_CharType[ch];
2061 while (1) {
2062 while (type == 'W') {
2063 m_dwWordPos = m_Pos;
2064 if (!GetNextChar(ch)) {
2065 return;
2066 }
2067 type = PDF_CharType[ch];
2068 }
2069 if (ch != '%') {
2070 break;
2071 }
2072 while (1) {
2073 if (!GetNextChar(ch)) {
2074 return;
2075 }
2076 if (ch == '\r' || ch == '\n') {
2077 break;
2078 }
2079 }
2080 type = PDF_CharType[ch];
2081 }
2082 m_Pos--;
2083 }
2084 CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) {
2085 GetNextWord();
2086 bIsNumber = m_bIsNumber;
2087 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize);
2088 }
2089 CFX_ByteString CPDF_SyntaxParser::GetKeyword() {
2090 GetNextWord();
2091 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize);
2092 }
2093 CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList,
2094 FX_DWORD objnum,
2095 FX_DWORD gennum,
2096 PARSE_CONTEXT* pContext,
2097 FX_BOOL bDecrypt) {
2098 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
2099 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) {
2100 return NULL;
2101 }
2102 FX_FILESIZE SavedPos = m_Pos;
2103 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
2104 FX_BOOL bIsNumber;
2105 CFX_ByteString word = GetNextWord(bIsNumber);
2106 if (word.GetLength() == 0) {
2107 if (bTypeOnly) {
2108 return (CPDF_Object*)PDFOBJ_INVALID;
2109 }
2110 return NULL;
2111 }
2112 if (bIsNumber) {
2113 FX_FILESIZE SavedPos = m_Pos;
2114 CFX_ByteString nextword = GetNextWord(bIsNumber);
2115 if (bIsNumber) {
2116 CFX_ByteString nextword2 = GetNextWord(bIsNumber);
2117 if (nextword2 == FX_BSTRC("R")) {
2118 FX_DWORD objnum = FXSYS_atoi(word);
2119 if (bTypeOnly) {
2120 return (CPDF_Object*)PDFOBJ_REFERENCE;
2121 }
2122 return new CPDF_Reference(pObjList, objnum);
2123 }
2124 }
2125 m_Pos = SavedPos;
2126 if (bTypeOnly) {
2127 return (CPDF_Object*)PDFOBJ_NUMBER;
2128 }
2129 return CPDF_Number::Create(word);
2130 }
2131 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2132 if (bTypeOnly) {
2133 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2134 }
2135 return CPDF_Boolean::Create(word == FX_BSTRC("true"));
2136 }
2137 if (word == FX_BSTRC("null")) {
2138 if (bTypeOnly) {
2139 return (CPDF_Object*)PDFOBJ_NULL;
2140 }
2141 return CPDF_Null::Create();
2142 }
2143 if (word == FX_BSTRC("(")) {
2144 if (bTypeOnly) {
2145 return (CPDF_Object*)PDFOBJ_STRING;
2146 }
2147 CFX_ByteString str = ReadString();
2148 if (m_pCryptoHandler && bDecrypt) {
2149 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2150 }
2151 return CPDF_String::Create(str, FALSE);
2152 }
2153 if (word == FX_BSTRC("<")) {
2154 if (bTypeOnly) {
2155 return (CPDF_Object*)PDFOBJ_STRING;
2156 }
2157 CFX_ByteString str = ReadHexString();
2158 if (m_pCryptoHandler && bDecrypt) {
2159 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2160 }
2161 return CPDF_String::Create(str, TRUE);
2162 }
2163 if (word == FX_BSTRC("[")) {
2164 if (bTypeOnly) {
2165 return (CPDF_Object*)PDFOBJ_ARRAY;
2166 }
2167 CPDF_Array* pArray = CPDF_Array::Create();
2168 while (1) {
2169 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2170 if (pObj == NULL) {
2171 return pArray;
2172 }
2173 pArray->Add(pObj);
2174 }
2175 }
2176 if (word[0] == '/') {
2177 if (bTypeOnly) {
2178 return (CPDF_Object*)PDFOBJ_NAME;
2179 }
2180 return CPDF_Name::Create(
2181 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
2182 }
2183 if (word == FX_BSTRC("<<")) {
2184 if (bTypeOnly) {
2185 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2186 }
2187 if (pContext) {
2188 pContext->m_DictStart = SavedPos;
2189 }
2190 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2191 int32_t nKeys = 0;
2192 FX_FILESIZE dwSignValuePos = 0;
2193 while (1) {
2194 FX_BOOL bIsNumber;
2195 CFX_ByteString key = GetNextWord(bIsNumber);
2196 if (key.IsEmpty()) {
2197 if (pDict)
2198 pDict->Release();
2199 return NULL;
2200 }
2201 FX_FILESIZE SavedPos = m_Pos - key.GetLength();
2202 if (key == FX_BSTRC(">>")) {
2203 break;
2204 }
2205 if (key == FX_BSTRC("endobj")) {
2206 m_Pos = SavedPos;
2207 break;
2208 }
2209 if (key[0] != '/') {
2210 continue;
2211 }
2212 nKeys++;
2213 key = PDF_NameDecode(key);
2214 if (key == FX_BSTRC("/Contents")) {
2215 dwSignValuePos = m_Pos;
2216 }
2217 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2218 if (pObj == NULL) {
2219 continue;
2220 }
2221 if (key.GetLength() >= 1) {
2222 if (nKeys < 32) {
2223 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1),
2224 pObj);
2225 } else {
2226 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1),
2227 pObj);
2228 }
2229 }
2230 }
2231 if (IsSignatureDict(pDict)) {
2232 FX_FILESIZE dwSavePos = m_Pos;
2233 m_Pos = dwSignValuePos;
2234 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE);
2235 pDict->SetAt(FX_BSTRC("Contents"), pObj);
2236 m_Pos = dwSavePos;
2237 }
2238 if (pContext) {
2239 pContext->m_DictEnd = m_Pos;
2240 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2241 return pDict;
2242 }
2243 }
2244 FX_FILESIZE SavedPos = m_Pos;
2245 FX_BOOL bIsNumber;
2246 CFX_ByteString nextword = GetNextWord(bIsNumber);
2247 if (nextword == FX_BSTRC("stream")) {
2248 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2249 if (pStream) {
2250 return pStream;
2251 }
2252 if (pDict)
2253 pDict->Release();
2254 return NULL;
2255 } else {
2256 m_Pos = SavedPos;
2257 return pDict;
2258 }
2259 }
2260 if (word == FX_BSTRC(">>")) {
2261 m_Pos = SavedPos;
2262 return NULL;
2263 }
2264 if (bTypeOnly) {
2265 return (CPDF_Object*)PDFOBJ_INVALID;
2266 }
2267 return NULL;
2268 }
2269 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(
2270 CPDF_IndirectObjects* pObjList,
2271 FX_DWORD objnum,
2272 FX_DWORD gennum,
2273 struct PARSE_CONTEXT* pContext) {
2274 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
2275 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) {
2276 return NULL;
2277 }
2278 FX_FILESIZE SavedPos = m_Pos;
2279 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
2280 FX_BOOL bIsNumber;
2281 CFX_ByteString word = GetNextWord(bIsNumber);
2282 if (word.GetLength() == 0) {
2283 if (bTypeOnly) {
2284 return (CPDF_Object*)PDFOBJ_INVALID;
2285 }
2286 return NULL;
2287 }
2288 if (bIsNumber) {
2289 FX_FILESIZE SavedPos = m_Pos;
2290 CFX_ByteString nextword = GetNextWord(bIsNumber);
2291 if (bIsNumber) {
2292 CFX_ByteString nextword2 = GetNextWord(bIsNumber);
2293 if (nextword2 == FX_BSTRC("R")) {
2294 if (bTypeOnly) {
2295 return (CPDF_Object*)PDFOBJ_REFERENCE;
2296 }
2297 FX_DWORD objnum = FXSYS_atoi(word);
2298 return new CPDF_Reference(pObjList, objnum);
2299 }
2300 }
2301 m_Pos = SavedPos;
2302 if (bTypeOnly) {
2303 return (CPDF_Object*)PDFOBJ_NUMBER;
2304 }
2305 return CPDF_Number::Create(word);
2306 }
2307 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2308 if (bTypeOnly) {
2309 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2310 }
2311 return CPDF_Boolean::Create(word == FX_BSTRC("true"));
2312 }
2313 if (word == FX_BSTRC("null")) {
2314 if (bTypeOnly) {
2315 return (CPDF_Object*)PDFOBJ_NULL;
2316 }
2317 return CPDF_Null::Create();
2318 }
2319 if (word == FX_BSTRC("(")) {
2320 if (bTypeOnly) {
2321 return (CPDF_Object*)PDFOBJ_STRING;
2322 }
2323 CFX_ByteString str = ReadString();
2324 if (m_pCryptoHandler) {
2325 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2326 }
2327 return CPDF_String::Create(str, FALSE);
2328 }
2329 if (word == FX_BSTRC("<")) {
2330 if (bTypeOnly) {
2331 return (CPDF_Object*)PDFOBJ_STRING;
2332 }
2333 CFX_ByteString str = ReadHexString();
2334 if (m_pCryptoHandler) {
2335 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2336 }
2337 return CPDF_String::Create(str, TRUE);
2338 }
2339 if (word == FX_BSTRC("[")) {
2340 if (bTypeOnly) {
2341 return (CPDF_Object*)PDFOBJ_ARRAY;
2342 }
2343 CPDF_Array* pArray = CPDF_Array::Create();
2344 while (1) {
2345 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2346 if (pObj == NULL) {
2347 if (m_WordBuffer[0] == ']') {
2348 return pArray;
2349 }
2350 if (pArray) {
2351 pArray->Release();
2352 }
2353 return NULL;
2354 }
2355 pArray->Add(pObj);
2356 }
2357 }
2358 if (word[0] == '/') {
2359 if (bTypeOnly) {
2360 return (CPDF_Object*)PDFOBJ_NAME;
2361 }
2362 return CPDF_Name::Create(
2363 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
2364 }
2365 if (word == FX_BSTRC("<<")) {
2366 if (bTypeOnly) {
2367 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2368 }
2369 if (pContext) {
2370 pContext->m_DictStart = SavedPos;
2371 }
2372 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2373 while (1) {
2374 FX_BOOL bIsNumber;
2375 FX_FILESIZE SavedPos = m_Pos;
2376 CFX_ByteString key = GetNextWord(bIsNumber);
2377 if (key.IsEmpty()) {
2378 if (pDict) {
2379 pDict->Release();
2380 }
2381 return NULL;
2382 }
2383 if (key == FX_BSTRC(">>")) {
2384 break;
2385 }
2386 if (key == FX_BSTRC("endobj")) {
2387 m_Pos = SavedPos;
2388 break;
2389 }
2390 if (key[0] != '/') {
2391 continue;
2392 }
2393 key = PDF_NameDecode(key);
2394 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2395 if (pObj == NULL) {
2396 if (pDict) {
2397 pDict->Release();
2398 }
2399 uint8_t ch;
2400 while (1) {
2401 if (!GetNextChar(ch)) {
2402 break;
2403 }
2404 if (ch == 0x0A || ch == 0x0D) {
2405 break;
2406 }
2407 }
2408 return NULL;
2409 }
2410 if (key.GetLength() > 1) {
2411 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1),
2412 pObj);
2413 }
2414 }
2415 if (pContext) {
2416 pContext->m_DictEnd = m_Pos;
2417 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2418 return pDict;
2419 }
2420 }
2421 FX_FILESIZE SavedPos = m_Pos;
2422 FX_BOOL bIsNumber;
2423 CFX_ByteString nextword = GetNextWord(bIsNumber);
2424 if (nextword == FX_BSTRC("stream")) {
2425 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2426 if (pStream) {
2427 return pStream;
2428 }
2429 if (pDict) {
2430 pDict->Release();
2431 }
2432 return NULL;
2433 } else {
2434 m_Pos = SavedPos;
2435 return pDict;
2436 }
2437 }
2438 if (word == FX_BSTRC(">>")) {
2439 m_Pos = SavedPos;
2440 return NULL;
2441 }
2442 if (bTypeOnly) {
2443 return (CPDF_Object*)PDFOBJ_INVALID;
2444 }
2445 return NULL;
2446 }
2447 CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict,
2448 PARSE_CONTEXT* pContext,
2449 FX_DWORD objnum,
2450 FX_DWORD gennum) {
2451 CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));
2452 FX_FILESIZE len = 0;
2453 if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) ||
2454 ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&
2455 ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) {
2456 len = pLenObj->GetInteger();
2457 }
2458
2459 ToNextLine();
2460 FX_FILESIZE StreamStartPos = m_Pos;
2461 if (pContext) {
2462 pContext->m_DataStart = m_Pos;
2463 }
2464
2465 CPDF_CryptoHandler* pCryptoHandler =
2466 objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;
2467 if (pCryptoHandler == NULL) {
2468 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos;
2469 pos += len;
2470 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) {
2471 m_Pos = pos.ValueOrDie();
2472 }
2473 GetNextWord();
2474 if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) {
2475 m_Pos = StreamStartPos;
2476 FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0);
2477 if (offset >= 0) {
2478 FX_FILESIZE curPos = m_Pos;
2479 m_Pos = StreamStartPos;
2480 FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0);
2481 if (endobjOffset < offset && endobjOffset >= 0) {
2482 offset = endobjOffset;
2483 } else {
2484 m_Pos = curPos;
2485 }
2486 uint8_t byte1, byte2;
2487 GetCharAt(StreamStartPos + offset - 1, byte1);
2488 GetCharAt(StreamStartPos + offset - 2, byte2);
2489 if (byte1 == 0x0a && byte2 == 0x0d) {
2490 len -= 2;
2491 } else if (byte1 == 0x0a || byte1 == 0x0d) {
2492 len--;
2493 }
2494 len = (FX_DWORD)offset;
2495 pDict->SetAtInteger(FX_BSTRC("Length"), len);
2496 } else {
2497 m_Pos = StreamStartPos;
2498 if (FindTag(FX_BSTRC("endobj"), 0) < 0) {
2499 return NULL;
2500 }
2501 }
2502 }
2503 m_Pos = StreamStartPos;
2504 }
2505 CPDF_Stream* pStream;
2506 uint8_t* pData = FX_Alloc(uint8_t, len);
2507 ReadBlock(pData, len);
2508 if (pCryptoHandler) {
2509 CFX_BinaryBuf dest_buf;
2510 dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));
2511 void* context = pCryptoHandler->DecryptStart(objnum, gennum);
2512 pCryptoHandler->DecryptStream(context, pData, len, dest_buf);
2513 pCryptoHandler->DecryptFinish(context, dest_buf);
2514 FX_Free(pData);
2515 pData = dest_buf.GetBuffer();
2516 len = dest_buf.GetSize();
2517 dest_buf.DetachBuffer();
2518 }
2519 pStream = new CPDF_Stream(pData, len, pDict);
2520 if (pContext) {
2521 pContext->m_DataEnd = pContext->m_DataStart + len;
2522 }
2523 StreamStartPos = m_Pos;
2524 GetNextWord();
2525 if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) {
2526 m_Pos = StreamStartPos;
2527 }
2528 return pStream;
2529 }
2530 void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess,
2531 FX_DWORD HeaderOffset) {
2532 if (m_pFileBuf) {
2533 FX_Free(m_pFileBuf);
1686 m_pFileBuf = NULL; 2534 m_pFileBuf = NULL;
1687 m_BufSize = CPDF_ModuleMgr::kFileBufSize; 2535 }
1688 m_pFileBuf = NULL; 2536 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize);
1689 m_MetadataObjnum = 0; 2537 m_HeaderOffset = HeaderOffset;
1690 m_dwWordPos = 0; 2538 m_FileLen = pFileAccess->GetSize();
1691 m_bFileStream = FALSE; 2539 m_Pos = 0;
1692 } 2540 m_pFileAccess = pFileAccess;
1693 CPDF_SyntaxParser::~CPDF_SyntaxParser() 2541 m_BufOffset = 0;
1694 { 2542 pFileAccess->ReadBlock(
1695 if (m_pFileBuf) { 2543 m_pFileBuf, 0,
1696 FX_Free(m_pFileBuf); 2544 (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize));
1697 } 2545 }
1698 } 2546 int32_t CPDF_SyntaxParser::GetDirectNum() {
1699 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) 2547 GetNextWord();
1700 { 2548 if (!m_bIsNumber) {
1701 FX_FILESIZE save_pos = m_Pos; 2549 return 0;
1702 m_Pos = pos; 2550 }
1703 FX_BOOL ret = GetNextChar(ch); 2551 m_WordBuffer[m_WordSize] = 0;
1704 m_Pos = save_pos; 2552 return FXSYS_atoi((const FX_CHAR*)m_WordBuffer);
1705 return ret; 2553 }
1706 } 2554 FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos,
1707 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) 2555 FX_FILESIZE limit,
1708 { 2556 const uint8_t* tag,
1709 FX_FILESIZE pos = m_Pos + m_HeaderOffset; 2557 FX_DWORD taglen) {
1710 if (pos >= m_FileLen) { 2558 uint8_t type = PDF_CharType[tag[0]];
2559 FX_BOOL bCheckLeft = type != 'D' && type != 'W';
2560 type = PDF_CharType[tag[taglen - 1]];
2561 FX_BOOL bCheckRight = type != 'D' && type != 'W';
2562 uint8_t ch;
2563 if (bCheckRight && startpos + (int32_t)taglen <= limit &&
2564 GetCharAt(startpos + (int32_t)taglen, ch)) {
2565 uint8_t type = PDF_CharType[ch];
2566 if (type == 'N' || type == 'R') {
2567 return FALSE;
2568 }
2569 }
2570 if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
2571 uint8_t type = PDF_CharType[ch];
2572 if (type == 'N' || type == 'R') {
2573 return FALSE;
2574 }
2575 }
2576 return TRUE;
2577 }
2578 FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag,
2579 FX_BOOL bWholeWord,
2580 FX_BOOL bForward,
2581 FX_FILESIZE limit) {
2582 int32_t taglen = tag.GetLength();
2583 if (taglen == 0) {
2584 return FALSE;
2585 }
2586 FX_FILESIZE pos = m_Pos;
2587 int32_t offset = 0;
2588 if (!bForward) {
2589 offset = taglen - 1;
2590 }
2591 const uint8_t* tag_data = tag.GetPtr();
2592 uint8_t byte;
2593 while (1) {
2594 if (bForward) {
2595 if (limit) {
2596 if (pos >= m_Pos + limit) {
2597 return FALSE;
2598 }
2599 }
2600 if (!GetCharAt(pos, byte)) {
1711 return FALSE; 2601 return FALSE;
1712 } 2602 }
1713 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { 2603 } else {
1714 FX_FILESIZE read_pos = pos; 2604 if (limit) {
1715 FX_DWORD read_size = m_BufSize; 2605 if (pos <= m_Pos - limit) {
1716 if ((FX_FILESIZE)read_size > m_FileLen) { 2606 return FALSE;
1717 read_size = (FX_DWORD)m_FileLen; 2607 }
1718 } 2608 }
1719 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { 2609 if (!GetCharAtBackward(pos, byte)) {
1720 if (m_FileLen < (FX_FILESIZE)read_size) { 2610 return FALSE;
1721 read_pos = 0; 2611 }
1722 read_size = (FX_DWORD)m_FileLen; 2612 }
2613 if (byte == tag_data[offset]) {
2614 if (bForward) {
2615 offset++;
2616 if (offset < taglen) {
2617 pos++;
2618 continue;
2619 }
2620 } else {
2621 offset--;
2622 if (offset >= 0) {
2623 pos--;
2624 continue;
2625 }
2626 }
2627 FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;
2628 if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen)) {
2629 m_Pos = startpos;
2630 return TRUE;
2631 }
2632 }
2633 if (bForward) {
2634 offset = byte == tag_data[0] ? 1 : 0;
2635 pos++;
2636 } else {
2637 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;
2638 pos--;
2639 }
2640 if (pos < 0) {
2641 return FALSE;
2642 }
2643 }
2644 return FALSE;
2645 }
2646 struct _SearchTagRecord {
2647 const uint8_t* m_pTag;
2648 FX_DWORD m_Len;
2649 FX_DWORD m_Offset;
2650 };
2651 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags,
2652 FX_BOOL bWholeWord,
2653 FX_FILESIZE limit) {
2654 int32_t ntags = 1, i;
2655 for (i = 0; i < tags.GetLength(); i++)
2656 if (tags[i] == 0) {
2657 ntags++;
2658 }
2659 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);
2660 FX_DWORD start = 0, itag = 0, max_len = 0;
2661 for (i = 0; i <= tags.GetLength(); i++) {
2662 if (tags[i] == 0) {
2663 FX_DWORD len = i - start;
2664 if (len > max_len) {
2665 max_len = len;
2666 }
2667 pPatterns[itag].m_pTag = tags.GetPtr() + start;
2668 pPatterns[itag].m_Len = len;
2669 pPatterns[itag].m_Offset = 0;
2670 start = i + 1;
2671 itag++;
2672 }
2673 }
2674 FX_FILESIZE pos = m_Pos;
2675 uint8_t byte;
2676 GetCharAt(pos++, byte);
2677 int32_t found = -1;
2678 while (1) {
2679 for (i = 0; i < ntags; i++) {
2680 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {
2681 pPatterns[i].m_Offset++;
2682 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {
2683 if (!bWholeWord ||
2684 IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag,
2685 pPatterns[i].m_Len)) {
2686 found = i;
2687 goto end;
2688 } else {
2689 if (pPatterns[i].m_pTag[0] == byte) {
2690 pPatterns[i].m_Offset = 1;
1723 } else { 2691 } else {
1724 read_pos = m_FileLen - read_size; 2692 pPatterns[i].m_Offset = 0;
1725 } 2693 }
1726 } 2694 }
1727 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { 2695 }
1728 return FALSE; 2696 } else {
1729 } 2697 if (pPatterns[i].m_pTag[0] == byte) {
1730 m_BufOffset = read_pos; 2698 pPatterns[i].m_Offset = 1;
1731 }
1732 ch = m_pFileBuf[pos - m_BufOffset];
1733 m_Pos ++;
1734 return TRUE;
1735 }
1736 FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch)
1737 {
1738 pos += m_HeaderOffset;
1739 if (pos >= m_FileLen) {
1740 return FALSE;
1741 }
1742 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
1743 FX_FILESIZE read_pos;
1744 if (pos < (FX_FILESIZE)m_BufSize) {
1745 read_pos = 0;
1746 } else { 2699 } else {
1747 read_pos = pos - m_BufSize + 1; 2700 pPatterns[i].m_Offset = 0;
1748 } 2701 }
1749 FX_DWORD read_size = m_BufSize; 2702 }
1750 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { 2703 }
1751 if (m_FileLen < (FX_FILESIZE)read_size) { 2704 if (limit && pos >= m_Pos + limit) {
1752 read_pos = 0; 2705 goto end;
1753 read_size = (FX_DWORD)m_FileLen; 2706 }
1754 } else { 2707 if (!GetCharAt(pos, byte)) {
1755 read_pos = m_FileLen - read_size; 2708 goto end;
1756 } 2709 }
1757 } 2710 pos++;
1758 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { 2711 }
1759 return FALSE; 2712 end:
1760 } 2713 FX_Free(pPatterns);
1761 m_BufOffset = read_pos; 2714 return found;
1762 } 2715 }
1763 ch = m_pFileBuf[pos - m_BufOffset]; 2716 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag,
1764 return TRUE; 2717 FX_FILESIZE limit) {
1765 } 2718 int32_t taglen = tag.GetLength();
1766 FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) 2719 int32_t match = 0;
1767 { 2720 limit += m_Pos;
1768 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) { 2721 FX_FILESIZE startpos = m_Pos;
1769 return FALSE; 2722 while (1) {
1770 }
1771 m_Pos += size;
1772 return TRUE;
1773 }
1774 #define MAX_WORD_BUFFER 256
1775 void CPDF_SyntaxParser::GetNextWord()
1776 {
1777 m_WordSize = 0;
1778 m_bIsNumber = TRUE;
1779 uint8_t ch; 2723 uint8_t ch;
1780 if (!GetNextChar(ch)) { 2724 if (!GetNextChar(ch)) {
1781 return; 2725 return -1;
1782 } 2726 }
1783 uint8_t type = PDF_CharType[ch]; 2727 if (ch == tag[match]) {
1784 while (1) { 2728 match++;
1785 while (type == 'W') { 2729 if (match == taglen) {
1786 if (!GetNextChar(ch)) { 2730 return m_Pos - startpos - taglen;
1787 return; 2731 }
1788 } 2732 } else {
1789 type = PDF_CharType[ch]; 2733 match = ch == tag[0] ? 1 : 0;
1790 } 2734 }
1791 if (ch != '%') { 2735 if (limit && m_Pos == limit) {
1792 break; 2736 return -1;
1793 } 2737 }
1794 while (1) { 2738 }
1795 if (!GetNextChar(ch)) { 2739 return -1;
1796 return; 2740 }
1797 } 2741 void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size) {
1798 if (ch == '\r' || ch == '\n') { 2742 FX_DWORD offset = 0;
1799 break; 2743 uint8_t ch;
1800 } 2744 while (1) {
1801 }
1802 type = PDF_CharType[ch];
1803 }
1804 if (type == 'D') {
1805 m_bIsNumber = FALSE;
1806 m_WordBuffer[m_WordSize++] = ch;
1807 if (ch == '/') {
1808 while (1) {
1809 if (!GetNextChar(ch)) {
1810 return;
1811 }
1812 type = PDF_CharType[ch];
1813 if (type != 'R' && type != 'N') {
1814 m_Pos --;
1815 return;
1816 }
1817 if (m_WordSize < MAX_WORD_BUFFER) {
1818 m_WordBuffer[m_WordSize++] = ch;
1819 }
1820 }
1821 } else if (ch == '<') {
1822 if (!GetNextChar(ch)) {
1823 return;
1824 }
1825 if (ch == '<') {
1826 m_WordBuffer[m_WordSize++] = ch;
1827 } else {
1828 m_Pos --;
1829 }
1830 } else if (ch == '>') {
1831 if (!GetNextChar(ch)) {
1832 return;
1833 }
1834 if (ch == '>') {
1835 m_WordBuffer[m_WordSize++] = ch;
1836 } else {
1837 m_Pos --;
1838 }
1839 }
1840 return;
1841 }
1842 while (1) {
1843 if (m_WordSize < MAX_WORD_BUFFER) {
1844 m_WordBuffer[m_WordSize++] = ch;
1845 }
1846 if (type != 'N') {
1847 m_bIsNumber = FALSE;
1848 }
1849 if (!GetNextChar(ch)) {
1850 return;
1851 }
1852 type = PDF_CharType[ch];
1853 if (type == 'D' || type == 'W') {
1854 m_Pos --;
1855 break;
1856 }
1857 }
1858 }
1859 CFX_ByteString CPDF_SyntaxParser::ReadString()
1860 {
1861 uint8_t ch;
1862 if (!GetNextChar(ch)) { 2745 if (!GetNextChar(ch)) {
1863 return CFX_ByteString(); 2746 return;
1864 } 2747 }
1865 CFX_ByteTextBuf buf; 2748 buffer[offset++] = ch;
1866 int32_t parlevel = 0; 2749 if (offset == size) {
1867 int32_t status = 0, iEscCode = 0; 2750 break;
1868 while (1) { 2751 }
1869 switch (status) { 2752 }
1870 case 0: 2753 }
1871 if (ch == ')') { 2754
1872 if (parlevel == 0) { 2755 class CPDF_DataAvail final : public IPDF_DataAvail {
1873 return buf.GetByteString(); 2756 public:
1874 } 2757 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);
1875 parlevel --; 2758 ~CPDF_DataAvail();
1876 buf.AppendChar(')'); 2759
1877 } else if (ch == '(') { 2760 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override;
1878 parlevel ++; 2761
1879 buf.AppendChar('('); 2762 virtual void SetDocument(CPDF_Document* pDoc) override;
1880 } else if (ch == '\\') { 2763
1881 status = 1; 2764 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override;
1882 } else { 2765
1883 buf.AppendChar(ch); 2766 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override;
1884 } 2767
1885 break; 2768 virtual int32_t IsLinearizedPDF() override;
1886 case 1: 2769
1887 if (ch >= '0' && ch <= '7') { 2770 virtual FX_BOOL IsLinearized() override { return m_bLinearized; }
1888 iEscCode = ch - '0'; 2771
1889 status = 2; 2772 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
1890 break; 2773 FX_DWORD* pSize) override;
1891 } 2774
1892 if (ch == 'n') { 2775 protected:
1893 buf.AppendChar('\n'); 2776 static const int kMaxDataAvailRecursionDepth = 64;
1894 } else if (ch == 'r') { 2777 static int s_CurrentDataAvailRecursionDepth;
1895 buf.AppendChar('\r'); 2778
1896 } else if (ch == 't') { 2779 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset);
1897 buf.AppendChar('\t'); 2780 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array,
1898 } else if (ch == 'b') { 2781 FX_BOOL bParsePage,
1899 buf.AppendChar('\b'); 2782 IFX_DownloadHints* pHints,
1900 } else if (ch == 'f') { 2783 CFX_PtrArray& ret_array);
1901 buf.AppendChar('\f'); 2784 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints);
1902 } else if (ch == '\r') { 2785 FX_BOOL CheckHeader(IFX_DownloadHints* pHints);
1903 status = 4; 2786 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints);
1904 break; 2787 FX_BOOL CheckEnd(IFX_DownloadHints* pHints);
1905 } else if (ch == '\n') { 2788 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints);
1906 } else { 2789 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints);
1907 buf.AppendChar(ch); 2790 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints);
1908 } 2791 FX_BOOL CheckRoot(IFX_DownloadHints* pHints);
1909 status = 0; 2792 FX_BOOL CheckInfo(IFX_DownloadHints* pHints);
1910 break; 2793 FX_BOOL CheckPages(IFX_DownloadHints* pHints);
1911 case 2: 2794 FX_BOOL CheckPage(IFX_DownloadHints* pHints);
1912 if (ch >= '0' && ch <= '7') { 2795 FX_BOOL CheckResources(IFX_DownloadHints* pHints);
1913 iEscCode = iEscCode * 8 + ch - '0'; 2796 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints);
1914 status = 3; 2797 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints);
1915 } else { 2798 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints);
1916 buf.AppendChar(iEscCode); 2799 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints);
1917 status = 0; 2800 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints);
1918 continue; 2801 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints);
1919 } 2802
1920 break; 2803 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints,
1921 case 3: 2804 FX_FILESIZE& xref_offset);
1922 if (ch >= '0' && ch <= '7') { 2805 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen);
1923 iEscCode = iEscCode * 8 + ch - '0'; 2806 void SetStartOffset(FX_FILESIZE dwOffset);
1924 buf.AppendChar(iEscCode); 2807 FX_BOOL GetNextToken(CFX_ByteString& token);
1925 status = 0; 2808 FX_BOOL GetNextChar(uint8_t& ch);
1926 } else { 2809 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum);
1927 buf.AppendChar(iEscCode); 2810 CPDF_Object* GetObject(FX_DWORD objnum,
1928 status = 0; 2811 IFX_DownloadHints* pHints,
1929 continue; 2812 FX_BOOL* pExistInFile);
1930 } 2813 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages);
1931 break; 2814 FX_BOOL PreparePageItem();
1932 case 4: 2815 FX_BOOL LoadPages(IFX_DownloadHints* pHints);
1933 status = 0; 2816 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints);
1934 if (ch != '\n') { 2817 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints);
1935 continue; 2818 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints);
1936 } 2819 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints);
1937 break; 2820 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints);
1938 } 2821
1939 if (!GetNextChar(ch)) { 2822 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints);
1940 break; 2823 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict);
1941 } 2824 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints);
1942 } 2825 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints);
1943 GetNextChar(ch); 2826 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints);
1944 return buf.GetByteString(); 2827 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes,
1945 } 2828 int32_t iPage,
1946 CFX_ByteString CPDF_SyntaxParser::ReadHexString() 2829 int32_t& iCount,
1947 { 2830 IFX_DownloadHints* pHints);
1948 uint8_t ch; 2831 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo,
1949 if (!GetNextChar(ch)) { 2832 CPDF_PageNode* pPageNode,
1950 return CFX_ByteString(); 2833 IFX_DownloadHints* pHints);
1951 } 2834 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo,
1952 CFX_BinaryBuf buf; 2835 CPDF_PageNode* pPageNode,
1953 FX_BOOL bFirst = TRUE; 2836 IFX_DownloadHints* pHints);
1954 uint8_t code = 0; 2837 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints);
1955 while (1) { 2838 FX_BOOL IsFirstCheck(int iPage);
1956 if (ch == '>') { 2839 void ResetFirstCheck(int iPage);
1957 break; 2840
1958 } 2841 CPDF_Parser m_parser;
1959 if (ch >= '0' && ch <= '9') { 2842
1960 if (bFirst) { 2843 CPDF_SyntaxParser m_syntaxParser;
1961 code = (ch - '0') * 16; 2844
1962 } else { 2845 CPDF_Object* m_pRoot;
1963 code += ch - '0'; 2846
1964 buf.AppendByte((uint8_t)code); 2847 FX_DWORD m_dwRootObjNum;
1965 } 2848
1966 bFirst = !bFirst; 2849 FX_DWORD m_dwInfoObjNum;
1967 } else if (ch >= 'A' && ch <= 'F') { 2850
1968 if (bFirst) { 2851 CPDF_Object* m_pLinearized;
1969 code = (ch - 'A' + 10) * 16; 2852
1970 } else { 2853 CPDF_Object* m_pTrailer;
1971 code += ch - 'A' + 10; 2854
1972 buf.AppendByte((uint8_t)code); 2855 FX_BOOL m_bDocAvail;
1973 } 2856
1974 bFirst = !bFirst; 2857 FX_FILESIZE m_dwHeaderOffset;
1975 } else if (ch >= 'a' && ch <= 'f') { 2858
1976 if (bFirst) { 2859 FX_FILESIZE m_dwLastXRefOffset;
1977 code = (ch - 'a' + 10) * 16; 2860
1978 } else { 2861 FX_FILESIZE m_dwXRefOffset;
1979 code += ch - 'a' + 10; 2862
1980 buf.AppendByte((uint8_t)code); 2863 FX_FILESIZE m_dwTrailerOffset;
1981 } 2864
1982 bFirst = !bFirst; 2865 FX_FILESIZE m_dwCurrentOffset;
1983 } 2866
1984 if (!GetNextChar(ch)) { 2867 PDF_DATAAVAIL_STATUS m_docStatus;
1985 break; 2868
1986 } 2869 FX_FILESIZE m_dwFileLen;
1987 } 2870
1988 if (!bFirst) { 2871 CPDF_Document* m_pDocument;
1989 buf.AppendByte((uint8_t)code); 2872
1990 } 2873 CPDF_SortObjNumArray m_objnum_array;
1991 return buf.GetByteString(); 2874
1992 } 2875 CFX_PtrArray m_objs_array;
1993 void CPDF_SyntaxParser::ToNextLine() 2876
1994 { 2877 FX_FILESIZE m_Pos;
1995 uint8_t ch; 2878
1996 while (GetNextChar(ch)) { 2879 FX_FILESIZE m_bufferOffset;
1997 if (ch == '\n') { 2880
1998 break; 2881 FX_DWORD m_bufferSize;
1999 } 2882
2000 if (ch == '\r') { 2883 CFX_ByteString m_WordBuf;
2001 GetNextChar(ch); 2884
2002 if (ch != '\n') { 2885 uint8_t m_WordBuffer[257];
2003 --m_Pos; 2886
2004 } 2887 FX_DWORD m_WordSize;
2005 break; 2888
2006 } 2889 uint8_t m_bufferData[512];
2007 } 2890
2008 } 2891 CFX_FileSizeArray m_CrossOffset;
2009 void CPDF_SyntaxParser::ToNextWord() 2892
2010 { 2893 CFX_DWordArray m_XRefStreamList;
2011 uint8_t ch; 2894
2012 if (!GetNextChar(ch)) { 2895 CFX_DWordArray m_PageObjList;
2013 return; 2896
2014 } 2897 FX_DWORD m_PagesObjNum;
2015 uint8_t type = PDF_CharType[ch]; 2898
2016 while (1) { 2899 FX_BOOL m_bLinearized;
2017 while (type == 'W') { 2900
2018 m_dwWordPos = m_Pos; 2901 FX_DWORD m_dwFirstPageNo;
2019 if (!GetNextChar(ch)) { 2902
2020 return; 2903 FX_BOOL m_bLinearedDataOK;
2021 } 2904
2022 type = PDF_CharType[ch]; 2905 FX_BOOL m_bMainXRefLoadTried;
2023 } 2906
2024 if (ch != '%') { 2907 FX_BOOL m_bMainXRefLoadedOK;
2025 break; 2908
2026 } 2909 FX_BOOL m_bPagesTreeLoad;
2027 while (1) { 2910
2028 if (!GetNextChar(ch)) { 2911 FX_BOOL m_bPagesLoad;
2029 return; 2912
2030 } 2913 CPDF_Parser* m_pCurrentParser;
2031 if (ch == '\r' || ch == '\n') { 2914
2032 break; 2915 FX_FILESIZE m_dwCurrentXRefSteam;
2033 } 2916
2034 } 2917 FX_BOOL m_bAnnotsLoad;
2035 type = PDF_CharType[ch]; 2918
2036 } 2919 FX_BOOL m_bHaveAcroForm;
2037 m_Pos --; 2920
2038 } 2921 FX_DWORD m_dwAcroFormObjNum;
2039 CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) 2922
2040 { 2923 FX_BOOL m_bAcroFormLoad;
2041 GetNextWord(); 2924
2042 bIsNumber = m_bIsNumber; 2925 CPDF_Object* m_pAcroForm;
2043 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); 2926
2044 } 2927 CFX_PtrArray m_arrayAcroforms;
2045 CFX_ByteString CPDF_SyntaxParser::GetKeyword() 2928
2046 { 2929 CPDF_Dictionary* m_pPageDict;
2047 GetNextWord(); 2930
2048 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); 2931 CPDF_Object* m_pPageResource;
2049 } 2932
2050 CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO RD objnum, FX_DWORD gennum, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt) 2933 FX_BOOL m_bNeedDownLoadResource;
2051 { 2934
2052 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); 2935 FX_BOOL m_bPageLoadedOK;
2053 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { 2936
2054 return NULL; 2937 FX_BOOL m_bLinearizedFormParamLoad;
2055 } 2938
2056 FX_FILESIZE SavedPos = m_Pos; 2939 CFX_PtrArray m_PagesArray;
2057 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); 2940
2058 FX_BOOL bIsNumber; 2941 FX_DWORD m_dwEncryptObjNum;
2059 CFX_ByteString word = GetNextWord(bIsNumber); 2942
2060 if (word.GetLength() == 0) { 2943 FX_FILESIZE m_dwPrevXRefOffset;
2061 if (bTypeOnly) { 2944
2062 return (CPDF_Object*)PDFOBJ_INVALID; 2945 FX_BOOL m_bTotalLoadPageTree;
2063 } 2946
2064 return NULL; 2947 FX_BOOL m_bCurPageDictLoadOK;
2065 } 2948
2066 if (bIsNumber) { 2949 CPDF_PageNode m_pageNodes;
2067 FX_FILESIZE SavedPos = m_Pos; 2950
2068 CFX_ByteString nextword = GetNextWord(bIsNumber); 2951 CFX_CMapDWordToDWord* m_pageMapCheckState;
2069 if (bIsNumber) { 2952
2070 CFX_ByteString nextword2 = GetNextWord(bIsNumber); 2953 CFX_CMapDWordToDWord* m_pagesLoadState;
2071 if (nextword2 == FX_BSTRC("R")) {
2072 FX_DWORD objnum = FXSYS_atoi(word);
2073 if (bTypeOnly) {
2074 return (CPDF_Object*)PDFOBJ_REFERENCE;
2075 }
2076 return new CPDF_Reference(pObjList, objnum);
2077 }
2078 }
2079 m_Pos = SavedPos;
2080 if (bTypeOnly) {
2081 return (CPDF_Object*)PDFOBJ_NUMBER;
2082 }
2083 return CPDF_Number::Create(word);
2084 }
2085 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2086 if (bTypeOnly) {
2087 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2088 }
2089 return CPDF_Boolean::Create(word == FX_BSTRC("true"));
2090 }
2091 if (word == FX_BSTRC("null")) {
2092 if (bTypeOnly) {
2093 return (CPDF_Object*)PDFOBJ_NULL;
2094 }
2095 return CPDF_Null::Create();
2096 }
2097 if (word == FX_BSTRC("(")) {
2098 if (bTypeOnly) {
2099 return (CPDF_Object*)PDFOBJ_STRING;
2100 }
2101 CFX_ByteString str = ReadString();
2102 if (m_pCryptoHandler && bDecrypt) {
2103 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2104 }
2105 return CPDF_String::Create(str, FALSE);
2106 }
2107 if (word == FX_BSTRC("<")) {
2108 if (bTypeOnly) {
2109 return (CPDF_Object*)PDFOBJ_STRING;
2110 }
2111 CFX_ByteString str = ReadHexString();
2112 if (m_pCryptoHandler && bDecrypt) {
2113 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2114 }
2115 return CPDF_String::Create(str, TRUE);
2116 }
2117 if (word == FX_BSTRC("[")) {
2118 if (bTypeOnly) {
2119 return (CPDF_Object*)PDFOBJ_ARRAY;
2120 }
2121 CPDF_Array* pArray = CPDF_Array::Create();
2122 while (1) {
2123 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2124 if (pObj == NULL) {
2125 return pArray;
2126 }
2127 pArray->Add(pObj);
2128 }
2129 }
2130 if (word[0] == '/') {
2131 if (bTypeOnly) {
2132 return (CPDF_Object*)PDFOBJ_NAME;
2133 }
2134 return CPDF_Name::Create(
2135 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
2136 }
2137 if (word == FX_BSTRC("<<")) {
2138 if (bTypeOnly) {
2139 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2140 }
2141 if (pContext) {
2142 pContext->m_DictStart = SavedPos;
2143 }
2144 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2145 int32_t nKeys = 0;
2146 FX_FILESIZE dwSignValuePos = 0;
2147 while (1) {
2148 FX_BOOL bIsNumber;
2149 CFX_ByteString key = GetNextWord(bIsNumber);
2150 if (key.IsEmpty()) {
2151 if (pDict)
2152 pDict->Release();
2153 return NULL;
2154 }
2155 FX_FILESIZE SavedPos = m_Pos - key.GetLength();
2156 if (key == FX_BSTRC(">>")) {
2157 break;
2158 }
2159 if (key == FX_BSTRC("endobj")) {
2160 m_Pos = SavedPos;
2161 break;
2162 }
2163 if (key[0] != '/') {
2164 continue;
2165 }
2166 nKeys ++;
2167 key = PDF_NameDecode(key);
2168 if (key == FX_BSTRC("/Contents")) {
2169 dwSignValuePos = m_Pos;
2170 }
2171 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2172 if (pObj == NULL) {
2173 continue;
2174 }
2175 if (key.GetLength() >= 1) {
2176 if (nKeys < 32) {
2177 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength( ) - 1), pObj);
2178 } else {
2179 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLeng th() - 1), pObj);
2180 }
2181 }
2182 }
2183 if (IsSignatureDict(pDict)) {
2184 FX_FILESIZE dwSavePos = m_Pos;
2185 m_Pos = dwSignValuePos;
2186 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE) ;
2187 pDict->SetAt(FX_BSTRC("Contents"), pObj);
2188 m_Pos = dwSavePos;
2189 }
2190 if (pContext) {
2191 pContext->m_DictEnd = m_Pos;
2192 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2193 return pDict;
2194 }
2195 }
2196 FX_FILESIZE SavedPos = m_Pos;
2197 FX_BOOL bIsNumber;
2198 CFX_ByteString nextword = GetNextWord(bIsNumber);
2199 if (nextword == FX_BSTRC("stream")) {
2200 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2201 if (pStream) {
2202 return pStream;
2203 }
2204 if (pDict)
2205 pDict->Release();
2206 return NULL;
2207 } else {
2208 m_Pos = SavedPos;
2209 return pDict;
2210 }
2211 }
2212 if (word == FX_BSTRC(">>")) {
2213 m_Pos = SavedPos;
2214 return NULL;
2215 }
2216 if (bTypeOnly) {
2217 return (CPDF_Object*)PDFOBJ_INVALID;
2218 }
2219 return NULL;
2220 }
2221 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList , FX_DWORD objnum, FX_DWORD gennum, struct PARSE_CONTEXT* pContext)
2222 {
2223 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
2224 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) {
2225 return NULL;
2226 }
2227 FX_FILESIZE SavedPos = m_Pos;
2228 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
2229 FX_BOOL bIsNumber;
2230 CFX_ByteString word = GetNextWord(bIsNumber);
2231 if (word.GetLength() == 0) {
2232 if (bTypeOnly) {
2233 return (CPDF_Object*)PDFOBJ_INVALID;
2234 }
2235 return NULL;
2236 }
2237 if (bIsNumber) {
2238 FX_FILESIZE SavedPos = m_Pos;
2239 CFX_ByteString nextword = GetNextWord(bIsNumber);
2240 if (bIsNumber) {
2241 CFX_ByteString nextword2 = GetNextWord(bIsNumber);
2242 if (nextword2 == FX_BSTRC("R")) {
2243 if (bTypeOnly) {
2244 return (CPDF_Object*)PDFOBJ_REFERENCE;
2245 }
2246 FX_DWORD objnum = FXSYS_atoi(word);
2247 return new CPDF_Reference(pObjList, objnum);
2248 }
2249 }
2250 m_Pos = SavedPos;
2251 if (bTypeOnly) {
2252 return (CPDF_Object*)PDFOBJ_NUMBER;
2253 }
2254 return CPDF_Number::Create(word);
2255 }
2256 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2257 if (bTypeOnly) {
2258 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2259 }
2260 return CPDF_Boolean::Create(word == FX_BSTRC("true"));
2261 }
2262 if (word == FX_BSTRC("null")) {
2263 if (bTypeOnly) {
2264 return (CPDF_Object*)PDFOBJ_NULL;
2265 }
2266 return CPDF_Null::Create();
2267 }
2268 if (word == FX_BSTRC("(")) {
2269 if (bTypeOnly) {
2270 return (CPDF_Object*)PDFOBJ_STRING;
2271 }
2272 CFX_ByteString str = ReadString();
2273 if (m_pCryptoHandler) {
2274 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2275 }
2276 return CPDF_String::Create(str, FALSE);
2277 }
2278 if (word == FX_BSTRC("<")) {
2279 if (bTypeOnly) {
2280 return (CPDF_Object*)PDFOBJ_STRING;
2281 }
2282 CFX_ByteString str = ReadHexString();
2283 if (m_pCryptoHandler) {
2284 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2285 }
2286 return CPDF_String::Create(str, TRUE);
2287 }
2288 if (word == FX_BSTRC("[")) {
2289 if (bTypeOnly) {
2290 return (CPDF_Object*)PDFOBJ_ARRAY;
2291 }
2292 CPDF_Array* pArray = CPDF_Array::Create();
2293 while (1) {
2294 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2295 if (pObj == NULL) {
2296 if (m_WordBuffer[0] == ']') {
2297 return pArray;
2298 }
2299 if (pArray) {
2300 pArray->Release();
2301 }
2302 return NULL;
2303 }
2304 pArray->Add(pObj);
2305 }
2306 }
2307 if (word[0] == '/') {
2308 if (bTypeOnly) {
2309 return (CPDF_Object*)PDFOBJ_NAME;
2310 }
2311 return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1 , m_WordSize - 1)));
2312 }
2313 if (word == FX_BSTRC("<<")) {
2314 if (bTypeOnly) {
2315 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2316 }
2317 if (pContext) {
2318 pContext->m_DictStart = SavedPos;
2319 }
2320 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2321 while (1) {
2322 FX_BOOL bIsNumber;
2323 FX_FILESIZE SavedPos = m_Pos;
2324 CFX_ByteString key = GetNextWord(bIsNumber);
2325 if (key.IsEmpty()) {
2326 if (pDict) {
2327 pDict->Release();
2328 }
2329 return NULL;
2330 }
2331 if (key == FX_BSTRC(">>")) {
2332 break;
2333 }
2334 if (key == FX_BSTRC("endobj")) {
2335 m_Pos = SavedPos;
2336 break;
2337 }
2338 if (key[0] != '/') {
2339 continue;
2340 }
2341 key = PDF_NameDecode(key);
2342 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum);
2343 if (pObj == NULL) {
2344 if (pDict) {
2345 pDict->Release();
2346 }
2347 uint8_t ch;
2348 while (1) {
2349 if (!GetNextChar(ch)) {
2350 break;
2351 }
2352 if (ch == 0x0A || ch == 0x0D) {
2353 break;
2354 }
2355 }
2356 return NULL;
2357 }
2358 if (key.GetLength() > 1) {
2359 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), pObj);
2360 }
2361 }
2362 if (pContext) {
2363 pContext->m_DictEnd = m_Pos;
2364 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2365 return pDict;
2366 }
2367 }
2368 FX_FILESIZE SavedPos = m_Pos;
2369 FX_BOOL bIsNumber;
2370 CFX_ByteString nextword = GetNextWord(bIsNumber);
2371 if (nextword == FX_BSTRC("stream")) {
2372 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2373 if (pStream) {
2374 return pStream;
2375 }
2376 if (pDict) {
2377 pDict->Release();
2378 }
2379 return NULL;
2380 } else {
2381 m_Pos = SavedPos;
2382 return pDict;
2383 }
2384 }
2385 if (word == FX_BSTRC(">>")) {
2386 m_Pos = SavedPos;
2387 return NULL;
2388 }
2389 if (bTypeOnly) {
2390 return (CPDF_Object*)PDFOBJ_INVALID;
2391 }
2392 return NULL;
2393 }
2394 CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT * pContext,
2395 FX_DWORD objnum, FX_DWORD gennum)
2396 {
2397 CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));
2398 FX_FILESIZE len = 0;
2399 if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) ||
2400 ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&
2401 ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) {
2402 len = pLenObj->GetInteger();
2403 }
2404
2405 ToNextLine();
2406 FX_FILESIZE StreamStartPos = m_Pos;
2407 if (pContext) {
2408 pContext->m_DataStart = m_Pos;
2409 }
2410
2411 CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;
2412 if (pCryptoHandler == NULL) {
2413 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos;
2414 pos += len;
2415 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) {
2416 m_Pos = pos.ValueOrDie();
2417 }
2418 GetNextWord();
2419 if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) {
2420 m_Pos = StreamStartPos;
2421 FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0);
2422 if (offset >= 0) {
2423 FX_FILESIZE curPos = m_Pos;
2424 m_Pos = StreamStartPos;
2425 FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0);
2426 if (endobjOffset < offset && endobjOffset >= 0) {
2427 offset = endobjOffset;
2428 } else {
2429 m_Pos = curPos;
2430 }
2431 uint8_t byte1, byte2;
2432 GetCharAt(StreamStartPos + offset - 1, byte1);
2433 GetCharAt(StreamStartPos + offset - 2, byte2);
2434 if (byte1 == 0x0a && byte2 == 0x0d) {
2435 len -= 2;
2436 } else if (byte1 == 0x0a || byte1 == 0x0d) {
2437 len --;
2438 }
2439 len = (FX_DWORD)offset;
2440 pDict->SetAtInteger(FX_BSTRC("Length"), len);
2441 } else {
2442 m_Pos = StreamStartPos;
2443 if (FindTag(FX_BSTRC("endobj"), 0) < 0) {
2444 return NULL;
2445 }
2446 }
2447 }
2448 m_Pos = StreamStartPos;
2449 }
2450 CPDF_Stream* pStream;
2451 uint8_t* pData = FX_Alloc(uint8_t, len);
2452 ReadBlock(pData, len);
2453 if (pCryptoHandler) {
2454 CFX_BinaryBuf dest_buf;
2455 dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));
2456 void* context = pCryptoHandler->DecryptStart(objnum, gennum);
2457 pCryptoHandler->DecryptStream(context, pData, len, dest_buf);
2458 pCryptoHandler->DecryptFinish(context, dest_buf);
2459 FX_Free(pData);
2460 pData = dest_buf.GetBuffer();
2461 len = dest_buf.GetSize();
2462 dest_buf.DetachBuffer();
2463 }
2464 pStream = new CPDF_Stream(pData, len, pDict);
2465 if (pContext) {
2466 pContext->m_DataEnd = pContext->m_DataStart + len;
2467 }
2468 StreamStartPos = m_Pos;
2469 GetNextWord();
2470 if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) {
2471 m_Pos = StreamStartPos;
2472 }
2473 return pStream;
2474 }
2475 void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOff set)
2476 {
2477 if (m_pFileBuf) {
2478 FX_Free(m_pFileBuf);
2479 m_pFileBuf = NULL;
2480 }
2481 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize);
2482 m_HeaderOffset = HeaderOffset;
2483 m_FileLen = pFileAccess->GetSize();
2484 m_Pos = 0;
2485 m_pFileAccess = pFileAccess;
2486 m_BufOffset = 0;
2487 pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_Fi leLen ? m_FileLen : m_BufSize));
2488 }
2489 int32_t CPDF_SyntaxParser::GetDirectNum()
2490 {
2491 GetNextWord();
2492 if (!m_bIsNumber) {
2493 return 0;
2494 }
2495 m_WordBuffer[m_WordSize] = 0;
2496 return FXSYS_atoi((const FX_CHAR*)m_WordBuffer);
2497 }
2498 FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, const uint8_t* tag, FX_DWORD taglen)
2499 {
2500 uint8_t type = PDF_CharType[tag[0]];
2501 FX_BOOL bCheckLeft = type != 'D' && type != 'W';
2502 type = PDF_CharType[tag[taglen - 1]];
2503 FX_BOOL bCheckRight = type != 'D' && type != 'W';
2504 uint8_t ch;
2505 if (bCheckRight && startpos + (int32_t)taglen <= limit && GetCharAt(startpos + (int32_t)taglen, ch)) {
2506 uint8_t type = PDF_CharType[ch];
2507 if (type == 'N' || type == 'R') {
2508 return FALSE;
2509 }
2510 }
2511 if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
2512 uint8_t type = PDF_CharType[ch];
2513 if (type == 'N' || type == 'R') {
2514 return FALSE;
2515 }
2516 }
2517 return TRUE;
2518 }
2519 FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag, FX_BOOL bWhole Word, FX_BOOL bForward, FX_FILESIZE limit)
2520 {
2521 int32_t taglen = tag.GetLength();
2522 if (taglen == 0) {
2523 return FALSE;
2524 }
2525 FX_FILESIZE pos = m_Pos;
2526 int32_t offset = 0;
2527 if (!bForward) {
2528 offset = taglen - 1;
2529 }
2530 const uint8_t* tag_data = tag.GetPtr();
2531 uint8_t byte;
2532 while (1) {
2533 if (bForward) {
2534 if (limit) {
2535 if (pos >= m_Pos + limit) {
2536 return FALSE;
2537 }
2538 }
2539 if (!GetCharAt(pos, byte)) {
2540 return FALSE;
2541 }
2542 } else {
2543 if (limit) {
2544 if (pos <= m_Pos - limit) {
2545 return FALSE;
2546 }
2547 }
2548 if (!GetCharAtBackward(pos, byte)) {
2549 return FALSE;
2550 }
2551 }
2552 if (byte == tag_data[offset]) {
2553 if (bForward) {
2554 offset ++;
2555 if (offset < taglen) {
2556 pos ++;
2557 continue;
2558 }
2559 } else {
2560 offset --;
2561 if (offset >= 0) {
2562 pos --;
2563 continue;
2564 }
2565 }
2566 FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;
2567 if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen )) {
2568 m_Pos = startpos;
2569 return TRUE;
2570 }
2571 }
2572 if (bForward) {
2573 offset = byte == tag_data[0] ? 1 : 0;
2574 pos ++;
2575 } else {
2576 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;
2577 pos --;
2578 }
2579 if (pos < 0) {
2580 return FALSE;
2581 }
2582 }
2583 return FALSE;
2584 }
2585 struct _SearchTagRecord {
2586 const uint8_t* m_pTag;
2587 FX_DWORD m_Len;
2588 FX_DWORD m_Offset;
2589 }; 2954 };
2590 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, FX_BOOL bWholeWord, FX_FILESIZE limit) 2955
2591 { 2956 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail,
2592 int32_t ntags = 1, i; 2957 IFX_FileRead* pFileRead)
2593 for (i = 0; i < tags.GetLength(); i ++) 2958 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {}
2594 if (tags[i] == 0) {
2595 ntags ++;
2596 }
2597 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);
2598 FX_DWORD start = 0, itag = 0, max_len = 0;
2599 for (i = 0; i <= tags.GetLength(); i ++) {
2600 if (tags[i] == 0) {
2601 FX_DWORD len = i - start;
2602 if (len > max_len) {
2603 max_len = len;
2604 }
2605 pPatterns[itag].m_pTag = tags.GetPtr() + start;
2606 pPatterns[itag].m_Len = len;
2607 pPatterns[itag].m_Offset = 0;
2608 start = i + 1;
2609 itag ++;
2610 }
2611 }
2612 FX_FILESIZE pos = m_Pos;
2613 uint8_t byte;
2614 GetCharAt(pos++, byte);
2615 int32_t found = -1;
2616 while (1) {
2617 for (i = 0; i < ntags; i ++) {
2618 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {
2619 pPatterns[i].m_Offset ++;
2620 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {
2621 if (!bWholeWord || IsWholeWord(pos - pPatterns[i].m_Len, lim it, pPatterns[i].m_pTag, pPatterns[i].m_Len)) {
2622 found = i;
2623 goto end;
2624 } else {
2625 if (pPatterns[i].m_pTag[0] == byte) {
2626 pPatterns[i].m_Offset = 1;
2627 } else {
2628 pPatterns[i].m_Offset = 0;
2629 }
2630 }
2631 }
2632 } else {
2633 if (pPatterns[i].m_pTag[0] == byte) {
2634 pPatterns[i].m_Offset = 1;
2635 } else {
2636 pPatterns[i].m_Offset = 0;
2637 }
2638 }
2639 }
2640 if (limit && pos >= m_Pos + limit) {
2641 goto end;
2642 }
2643 if (!GetCharAt(pos, byte)) {
2644 goto end;
2645 }
2646 pos ++;
2647 }
2648 end:
2649 FX_Free(pPatterns);
2650 return found;
2651 }
2652 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, FX_FILESIZE l imit)
2653 {
2654 int32_t taglen = tag.GetLength();
2655 int32_t match = 0;
2656 limit += m_Pos;
2657 FX_FILESIZE startpos = m_Pos;
2658 while (1) {
2659 uint8_t ch;
2660 if (!GetNextChar(ch)) {
2661 return -1;
2662 }
2663 if (ch == tag[match]) {
2664 match ++;
2665 if (match == taglen) {
2666 return m_Pos - startpos - taglen;
2667 }
2668 } else {
2669 match = ch == tag[0] ? 1 : 0;
2670 }
2671 if (limit && m_Pos == limit) {
2672 return -1;
2673 }
2674 }
2675 return -1;
2676 }
2677 void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size)
2678 {
2679 FX_DWORD offset = 0;
2680 uint8_t ch;
2681 while (1) {
2682 if (!GetNextChar(ch)) {
2683 return;
2684 }
2685 buffer[offset++] = ch;
2686 if (offset == size) {
2687 break;
2688 }
2689 }
2690 }
2691
2692 class CPDF_DataAvail final : public IPDF_DataAvail
2693 {
2694 public:
2695 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);
2696 ~CPDF_DataAvail();
2697
2698 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) o verride;
2699
2700 virtual void SetDocument(CPDF_Document* pDoc) overri de;
2701
2702 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints * pHints) override;
2703
2704 virtual int32_t IsFormAvail(IFX_DownloadHints *pHints) override;
2705
2706 virtual int32_t IsLinearizedPDF() override;
2707
2708 virtual FX_BOOL IsLinearized() override
2709 {
2710 return m_bLinearized;
2711 }
2712
2713 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE *p Pos, FX_DWORD *pSize) override;
2714
2715 protected:
2716 static const int kMaxDataAvailRecursionDepth = 64;
2717 static int s_CurrentDataAvailRecursionDepth;
2718
2719 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESI ZE& offset);
2720 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array);
2721 FX_BOOL CheckDocStatus(IFX_DownloadHints *pHints );
2722 FX_BOOL CheckHeader(IFX_DownloadHints* pHints);
2723 FX_BOOL CheckFirstPage(IFX_DownloadHints *pHints );
2724 FX_BOOL CheckEnd(IFX_DownloadHints *pHints);
2725 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints) ;
2726 FX_BOOL CheckCrossRefItem(IFX_DownloadHints *pHi nts);
2727 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints);
2728 FX_BOOL CheckRoot(IFX_DownloadHints* pHints);
2729 FX_BOOL CheckInfo(IFX_DownloadHints* pHints);
2730 FX_BOOL CheckPages(IFX_DownloadHints* pHints);
2731 FX_BOOL CheckPage(IFX_DownloadHints* pHints);
2732 FX_BOOL CheckResources(IFX_DownloadHints* pHints );
2733 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints);
2734 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints) ;
2735 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints * pHints);
2736 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pH ints);
2737 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHint s);
2738 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints *pHints);
2739
2740 int32_t CheckCrossRefStream(IFX_DownloadHints *pH ints, FX_FILESIZE &xref_offset);
2741 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWOR D dwLen);
2742 void SetStartOffset(FX_FILESIZE dwOffset);
2743 FX_BOOL GetNextToken(CFX_ByteString &token);
2744 FX_BOOL GetNextChar(uint8_t &ch);
2745 CPDF_Object * ParseIndirectObjectAt(FX_FILESIZE pos, F X_DWORD objnum);
2746 CPDF_Object * GetObject(FX_DWORD objnum, IFX_DownloadH ints* pHints, FX_BOOL *pExistInFile);
2747 FX_BOOL GetPageKids(CPDF_Parser *pParser, CPDF_O bject *pPages);
2748 FX_BOOL PreparePageItem();
2749 FX_BOOL LoadPages(IFX_DownloadHints* pHints);
2750 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints);
2751 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints);
2752 FX_BOOL CheckLinearizedData(IFX_DownloadHints* p Hints);
2753 FX_BOOL CheckFileResources(IFX_DownloadHints* pH ints);
2754 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadH ints* pHints);
2755
2756 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_ DownloadHints* pHints);
2757 FX_BOOL HaveResourceAncestor(CPDF_Dictionary *pD ict);
2758 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHin ts* pHints);
2759 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints);
2760 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadH ints* pHints);
2761 FX_BOOL CheckPageNode(CPDF_PageNode &pageNodes, int32_t iPage, int32_t &iCount, IFX_DownloadHints* pHints);
2762 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, C PDF_PageNode *pPageNode, IFX_DownloadHints* pHints);
2763 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, CP DF_PageNode *pPageNode, IFX_DownloadHints* pHints);
2764 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints );
2765 FX_BOOL IsFirstCheck(int iPage);
2766 void ResetFirstCheck(int iPage);
2767
2768 CPDF_Parser m_parser;
2769
2770 CPDF_SyntaxParser m_syntaxParser;
2771
2772 CPDF_Object *m_pRoot;
2773
2774 FX_DWORD m_dwRootObjNum;
2775
2776 FX_DWORD m_dwInfoObjNum;
2777
2778 CPDF_Object *m_pLinearized;
2779
2780 CPDF_Object *m_pTrailer;
2781
2782 FX_BOOL m_bDocAvail;
2783
2784 FX_FILESIZE m_dwHeaderOffset;
2785
2786 FX_FILESIZE m_dwLastXRefOffset;
2787
2788 FX_FILESIZE m_dwXRefOffset;
2789
2790 FX_FILESIZE m_dwTrailerOffset;
2791
2792 FX_FILESIZE m_dwCurrentOffset;
2793
2794 PDF_DATAAVAIL_STATUS m_docStatus;
2795
2796 FX_FILESIZE m_dwFileLen;
2797
2798 CPDF_Document* m_pDocument;
2799
2800 CPDF_SortObjNumArray m_objnum_array;
2801
2802 CFX_PtrArray m_objs_array;
2803
2804 FX_FILESIZE m_Pos;
2805
2806 FX_FILESIZE m_bufferOffset;
2807
2808 FX_DWORD m_bufferSize;
2809
2810 CFX_ByteString m_WordBuf;
2811
2812 uint8_t m_WordBuffer[257];
2813
2814 FX_DWORD m_WordSize;
2815
2816 uint8_t m_bufferData[512];
2817
2818 CFX_FileSizeArray m_CrossOffset;
2819
2820 CFX_DWordArray m_XRefStreamList;
2821
2822 CFX_DWordArray m_PageObjList;
2823
2824 FX_DWORD m_PagesObjNum;
2825
2826 FX_BOOL m_bLinearized;
2827
2828 FX_DWORD m_dwFirstPageNo;
2829
2830 FX_BOOL m_bLinearedDataOK;
2831
2832 FX_BOOL m_bMainXRefLoadTried;
2833
2834 FX_BOOL m_bMainXRefLoadedOK;
2835
2836 FX_BOOL m_bPagesTreeLoad;
2837
2838 FX_BOOL m_bPagesLoad;
2839
2840 CPDF_Parser * m_pCurrentParser;
2841
2842 FX_FILESIZE m_dwCurrentXRefSteam;
2843
2844 FX_BOOL m_bAnnotsLoad;
2845
2846 FX_BOOL m_bHaveAcroForm;
2847
2848 FX_DWORD m_dwAcroFormObjNum;
2849
2850 FX_BOOL m_bAcroFormLoad;
2851
2852 CPDF_Object * m_pAcroForm;
2853
2854 CFX_PtrArray m_arrayAcroforms;
2855
2856 CPDF_Dictionary * m_pPageDict;
2857
2858 CPDF_Object * m_pPageResource;
2859
2860 FX_BOOL m_bNeedDownLoadResource;
2861
2862 FX_BOOL m_bPageLoadedOK;
2863
2864 FX_BOOL m_bLinearizedFormParamLoad;
2865
2866 CFX_PtrArray m_PagesArray;
2867
2868 FX_DWORD m_dwEncryptObjNum;
2869
2870 FX_FILESIZE m_dwPrevXRefOffset;
2871
2872 FX_BOOL m_bTotalLoadPageTree;
2873
2874 FX_BOOL m_bCurPageDictLoadOK;
2875
2876 CPDF_PageNode m_pageNodes;
2877
2878 CFX_CMapDWordToDWord * m_pageMapCheckState;
2879
2880 CFX_CMapDWordToDWord * m_pagesLoadState;
2881 };
2882
2883 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRea d) :
2884 m_pFileAvail(pFileAvail),
2885 m_pFileRead(pFileRead) {
2886 }
2887 2959
2888 // static 2960 // static
2889 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead) 2961 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail,
2890 { 2962 IFX_FileRead* pFileRead) {
2891 return new CPDF_DataAvail(pFileAvail, pFileRead); 2963 return new CPDF_DataAvail(pFileAvail, pFileRead);
2892 } 2964 }
2893 2965
2894 // static 2966 // static
2895 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; 2967 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
2896 2968
2897 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRea d) 2969 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail,
2898 : IPDF_DataAvail(pFileAvail, pFileRead) 2970 IFX_FileRead* pFileRead)
2899 { 2971 : IPDF_DataAvail(pFileAvail, pFileRead) {
2900 m_Pos = 0; 2972 m_Pos = 0;
2901 m_dwFileLen = 0; 2973 m_dwFileLen = 0;
2902 if (m_pFileRead) { 2974 if (m_pFileRead) {
2903 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); 2975 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
2904 } 2976 }
2905 m_dwCurrentOffset = 0; 2977 m_dwCurrentOffset = 0;
2906 m_WordSize = 0; 2978 m_WordSize = 0;
2907 m_dwXRefOffset = 0; 2979 m_dwXRefOffset = 0;
2908 m_bufferOffset = 0; 2980 m_bufferOffset = 0;
2909 m_dwFirstPageNo = 0; 2981 m_dwFirstPageNo = 0;
2910 m_bufferSize = 0; 2982 m_bufferSize = 0;
2911 m_PagesObjNum = 0; 2983 m_PagesObjNum = 0;
2912 m_dwCurrentXRefSteam = 0; 2984 m_dwCurrentXRefSteam = 0;
2913 m_dwAcroFormObjNum = 0; 2985 m_dwAcroFormObjNum = 0;
2914 m_dwInfoObjNum = 0; 2986 m_dwInfoObjNum = 0;
2915 m_pDocument = 0; 2987 m_pDocument = 0;
2916 m_dwEncryptObjNum = 0; 2988 m_dwEncryptObjNum = 0;
2917 m_dwPrevXRefOffset = 0; 2989 m_dwPrevXRefOffset = 0;
2918 m_dwLastXRefOffset = 0; 2990 m_dwLastXRefOffset = 0;
2919 m_bDocAvail = FALSE; 2991 m_bDocAvail = FALSE;
2920 m_bMainXRefLoadTried = FALSE; 2992 m_bMainXRefLoadTried = FALSE;
2921 m_bDocAvail = FALSE; 2993 m_bDocAvail = FALSE;
2922 m_bLinearized = FALSE; 2994 m_bLinearized = FALSE;
2923 m_bPagesLoad = FALSE; 2995 m_bPagesLoad = FALSE;
2924 m_bPagesTreeLoad = FALSE; 2996 m_bPagesTreeLoad = FALSE;
2925 m_bMainXRefLoadedOK = FALSE; 2997 m_bMainXRefLoadedOK = FALSE;
2926 m_bAnnotsLoad = FALSE; 2998 m_bAnnotsLoad = FALSE;
2927 m_bHaveAcroForm = FALSE; 2999 m_bHaveAcroForm = FALSE;
2928 m_bAcroFormLoad = FALSE; 3000 m_bAcroFormLoad = FALSE;
2929 m_bPageLoadedOK = FALSE; 3001 m_bPageLoadedOK = FALSE;
2930 m_bNeedDownLoadResource = FALSE; 3002 m_bNeedDownLoadResource = FALSE;
2931 m_bLinearizedFormParamLoad = FALSE; 3003 m_bLinearizedFormParamLoad = FALSE;
2932 m_pLinearized = NULL; 3004 m_pLinearized = NULL;
2933 m_pRoot = NULL; 3005 m_pRoot = NULL;
2934 m_pTrailer = NULL; 3006 m_pTrailer = NULL;
2935 m_pCurrentParser = NULL; 3007 m_pCurrentParser = NULL;
2936 m_pAcroForm = NULL; 3008 m_pAcroForm = NULL;
2937 m_pPageDict = NULL; 3009 m_pPageDict = NULL;
2938 m_pPageResource = NULL; 3010 m_pPageResource = NULL;
2939 m_pageMapCheckState = NULL; 3011 m_pageMapCheckState = NULL;
2940 m_docStatus = PDF_DATAAVAIL_HEADER; 3012 m_docStatus = PDF_DATAAVAIL_HEADER;
2941 m_parser.m_bOwnFileRead = FALSE; 3013 m_parser.m_bOwnFileRead = FALSE;
2942 m_bTotalLoadPageTree = FALSE; 3014 m_bTotalLoadPageTree = FALSE;
2943 m_bCurPageDictLoadOK = FALSE; 3015 m_bCurPageDictLoadOK = FALSE;
2944 m_bLinearedDataOK = FALSE; 3016 m_bLinearedDataOK = FALSE;
2945 m_pagesLoadState = NULL; 3017 m_pagesLoadState = NULL;
2946 } 3018 }
2947 CPDF_DataAvail::~CPDF_DataAvail() 3019 CPDF_DataAvail::~CPDF_DataAvail() {
2948 { 3020 if (m_pLinearized) {
2949 if (m_pLinearized)» { 3021 m_pLinearized->Release();
2950 m_pLinearized->Release(); 3022 }
2951 } 3023 if (m_pRoot) {
2952 if (m_pRoot) { 3024 m_pRoot->Release();
2953 m_pRoot->Release(); 3025 }
2954 } 3026 if (m_pTrailer) {
2955 if (m_pTrailer) { 3027 m_pTrailer->Release();
2956 m_pTrailer->Release(); 3028 }
2957 } 3029 delete m_pageMapCheckState;
2958 delete m_pageMapCheckState; 3030 delete m_pagesLoadState;
2959 delete m_pagesLoadState; 3031 int32_t i = 0;
2960 int32_t i = 0; 3032 int32_t iSize = m_arrayAcroforms.GetSize();
3033 for (i = 0; i < iSize; ++i) {
3034 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release();
3035 }
3036 }
3037 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) {
3038 m_pDocument = pDoc;
3039 }
3040 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) {
3041 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser());
3042 if (pParser == NULL) {
3043 return 0;
3044 }
3045 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {
3046 return 0;
3047 }
3048 if (pParser->m_V5Type[objnum] == 2) {
3049 objnum = (FX_DWORD)pParser->m_CrossRef[objnum];
3050 }
3051 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {
3052 offset = pParser->m_CrossRef[objnum];
3053 if (offset == 0) {
3054 return 0;
3055 }
3056 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(),
3057 pParser->m_SortedOffset.GetSize(),
3058 sizeof(FX_FILESIZE), _CompareFileSize);
3059 if (pResult == NULL) {
3060 return 0;
3061 }
3062 if ((FX_FILESIZE*)pResult -
3063 (FX_FILESIZE*)pParser->m_SortedOffset.GetData() ==
3064 pParser->m_SortedOffset.GetSize() - 1) {
3065 return 0;
3066 }
3067 return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset);
3068 }
3069 return 0;
3070 }
3071 FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array,
3072 FX_BOOL bParsePage,
3073 IFX_DownloadHints* pHints,
3074 CFX_PtrArray& ret_array) {
3075 if (!obj_array.GetSize()) {
3076 return TRUE;
3077 }
3078 FX_DWORD count = 0;
3079 CFX_PtrArray new_obj_array;
3080 int32_t i = 0;
3081 for (i = 0; i < obj_array.GetSize(); i++) {
3082 CPDF_Object* pObj = (CPDF_Object*)obj_array[i];
3083 if (!pObj) {
3084 continue;
3085 }
3086 int32_t type = pObj->GetType();
3087 switch (type) {
3088 case PDFOBJ_ARRAY: {
3089 CPDF_Array* pArray = pObj->GetArray();
3090 for (FX_DWORD k = 0; k < pArray->GetCount(); k++) {
3091 new_obj_array.Add(pArray->GetElement(k));
3092 }
3093 } break;
3094 case PDFOBJ_STREAM:
3095 pObj = pObj->GetDict();
3096 case PDFOBJ_DICTIONARY: {
3097 CPDF_Dictionary* pDict = pObj->GetDict();
3098 if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) {
3099 continue;
3100 }
3101 FX_POSITION pos = pDict->GetStartPos();
3102 while (pos) {
3103 CPDF_Object* value;
3104 CFX_ByteString key;
3105 value = pDict->GetNextElement(pos, key);
3106 if (key != "Parent") {
3107 new_obj_array.Add(value);
3108 }
3109 }
3110 } break;
3111 case PDFOBJ_REFERENCE: {
3112 CPDF_Reference* pRef = (CPDF_Reference*)pObj;
3113 FX_DWORD dwNum = pRef->GetRefObjNum();
3114 FX_FILESIZE offset;
3115 FX_DWORD original_size = GetObjectSize(dwNum, offset);
3116 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size;
3117 if (size.ValueOrDefault(0) == 0 || offset < 0 ||
3118 offset >= m_dwFileLen) {
3119 break;
3120 }
3121
3122 size += offset;
3123 size += 512;
3124 if (!size.IsValid()) {
3125 break;
3126 }
3127 if (size.ValueOrDie() > m_dwFileLen) {
3128 size = m_dwFileLen - offset;
3129 } else {
3130 size = original_size + 512;
3131 }
3132 if (!size.IsValid()) {
3133 break;
3134 }
3135 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3136 pHints->AddSegment(offset, size.ValueOrDie());
3137 ret_array.Add(pObj);
3138 count++;
3139 } else if (!m_objnum_array.Find(dwNum)) {
3140 m_objnum_array.AddObjNum(dwNum);
3141 CPDF_Object* pReferred =
3142 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL);
3143 if (pReferred) {
3144 new_obj_array.Add(pReferred);
3145 }
3146 }
3147 } break;
3148 }
3149 }
3150 if (count > 0) {
3151 int32_t iSize = new_obj_array.GetSize();
3152 for (i = 0; i < iSize; ++i) {
3153 CPDF_Object* pObj = (CPDF_Object*)new_obj_array[i];
3154 int32_t type = pObj->GetType();
3155 if (type == PDFOBJ_REFERENCE) {
3156 CPDF_Reference* pRef = (CPDF_Reference*)pObj;
3157 FX_DWORD dwNum = pRef->GetRefObjNum();
3158 if (!m_objnum_array.Find(dwNum)) {
3159 ret_array.Add(pObj);
3160 }
3161 } else {
3162 ret_array.Add(pObj);
3163 }
3164 }
3165 return FALSE;
3166 }
3167 obj_array.RemoveAll();
3168 obj_array.Append(new_obj_array);
3169 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
3170 }
3171 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) {
3172 if (!m_dwFileLen && m_pFileRead) {
3173 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
3174 if (!m_dwFileLen) {
3175 return TRUE;
3176 }
3177 }
3178 while (!m_bDocAvail) {
3179 if (!CheckDocStatus(pHints)) {
3180 return FALSE;
3181 }
3182 }
3183 return TRUE;
3184 }
3185 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) {
3186 if (!m_objs_array.GetSize()) {
3187 m_objs_array.RemoveAll();
3188 m_objnum_array.RemoveAll();
3189 CFX_PtrArray obj_array;
3190 obj_array.Append(m_arrayAcroforms);
3191 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
3192 if (bRet) {
3193 m_objs_array.RemoveAll();
3194 }
3195 return bRet;
3196 }
3197 CFX_PtrArray new_objs_array;
3198 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
3199 if (bRet) {
2961 int32_t iSize = m_arrayAcroforms.GetSize(); 3200 int32_t iSize = m_arrayAcroforms.GetSize();
2962 for (i = 0; i < iSize; ++i) { 3201 for (int32_t i = 0; i < iSize; ++i) {
2963 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release(); 3202 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release();
2964 } 3203 }
2965 } 3204 m_arrayAcroforms.RemoveAll();
2966 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) 3205 } else {
2967 { 3206 m_objs_array.RemoveAll();
2968 m_pDocument = pDoc; 3207 m_objs_array.Append(new_objs_array);
2969 } 3208 }
2970 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) 3209 return bRet;
2971 { 3210 }
2972 CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser()); 3211 FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) {
2973 if (pParser == NULL) { 3212 FX_BOOL bExist = FALSE;
2974 return 0; 3213 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
2975 } 3214 if (!bExist) {
2976 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {
2977 return 0;
2978 }
2979 if (pParser->m_V5Type[objnum] == 2) {
2980 objnum = (FX_DWORD)pParser->m_CrossRef[objnum];
2981 }
2982 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {
2983 offset = pParser->m_CrossRef[objnum];
2984 if (offset == 0) {
2985 return 0;
2986 }
2987 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData() , pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
2988 if (pResult == NULL) {
2989 return 0;
2990 }
2991 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetDat a() == pParser->m_SortedOffset.GetSize() - 1) {
2992 return 0;
2993 }
2994 return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset);
2995 }
2996 return 0;
2997 }
2998 FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePa ge, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array)
2999 {
3000 if (!obj_array.GetSize()) {
3001 return TRUE;
3002 }
3003 FX_DWORD count = 0;
3004 CFX_PtrArray new_obj_array;
3005 int32_t i = 0;
3006 for (i = 0; i < obj_array.GetSize(); i++) {
3007 CPDF_Object *pObj = (CPDF_Object *)obj_array[i];
3008 if (!pObj) {
3009 continue;
3010 }
3011 int32_t type = pObj->GetType();
3012 switch (type) {
3013 case PDFOBJ_ARRAY: {
3014 CPDF_Array *pArray = pObj->GetArray();
3015 for (FX_DWORD k = 0; k < pArray->GetCount(); k++) {
3016 new_obj_array.Add(pArray->GetElement(k));
3017 }
3018 }
3019 break;
3020 case PDFOBJ_STREAM:
3021 pObj = pObj->GetDict();
3022 case PDFOBJ_DICTIONARY: {
3023 CPDF_Dictionary *pDict = pObj->GetDict();
3024 if (pDict && pDict->GetString("Type") == "Page" && !bParsePa ge) {
3025 continue;
3026 }
3027 FX_POSITION pos = pDict->GetStartPos();
3028 while (pos) {
3029 CPDF_Object *value;
3030 CFX_ByteString key;
3031 value = pDict->GetNextElement(pos, key);
3032 if (key != "Parent") {
3033 new_obj_array.Add(value);
3034 }
3035 }
3036 }
3037 break;
3038 case PDFOBJ_REFERENCE: {
3039 CPDF_Reference *pRef = (CPDF_Reference*)pObj;
3040 FX_DWORD dwNum = pRef->GetRefObjNum();
3041 FX_FILESIZE offset;
3042 FX_DWORD original_size = GetObjectSize(dwNum, offset);
3043 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size;
3044 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m _dwFileLen) {
3045 break;
3046 }
3047
3048 size += offset;
3049 size += 512;
3050 if (!size.IsValid()) {
3051 break;
3052 }
3053 if (size.ValueOrDie() > m_dwFileLen) {
3054 size = m_dwFileLen - offset;
3055 } else {
3056 size = original_size + 512;
3057 }
3058 if (!size.IsValid()) {
3059 break;
3060 }
3061 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3062 pHints->AddSegment(offset, size.ValueOrDie());
3063 ret_array.Add(pObj);
3064 count++;
3065 } else if (!m_objnum_array.Find(dwNum)) {
3066 m_objnum_array.AddObjNum(dwNum);
3067 CPDF_Object *pReferred = m_pDocument->GetIndirectObject( pRef->GetRefObjNum(), NULL);
3068 if (pReferred) {
3069 new_obj_array.Add(pReferred);
3070 }
3071 }
3072 }
3073 break;
3074 }
3075 }
3076 if (count > 0) {
3077 int32_t iSize = new_obj_array.GetSize();
3078 for (i = 0; i < iSize; ++i) {
3079 CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i];
3080 int32_t type = pObj->GetType();
3081 if (type == PDFOBJ_REFERENCE) {
3082 CPDF_Reference *pRef = (CPDF_Reference *)pObj;
3083 FX_DWORD dwNum = pRef->GetRefObjNum();
3084 if (!m_objnum_array.Find(dwNum)) {
3085 ret_array.Add(pObj);
3086 }
3087 } else {
3088 ret_array.Add(pObj);
3089 }
3090 }
3091 return FALSE;
3092 }
3093 obj_array.RemoveAll();
3094 obj_array.Append(new_obj_array);
3095 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
3096 }
3097 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints)
3098 {
3099 if (!m_dwFileLen && m_pFileRead) {
3100 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
3101 if (!m_dwFileLen) {
3102 return TRUE;
3103 }
3104 }
3105 while (!m_bDocAvail) {
3106 if (!CheckDocStatus(pHints)) {
3107 return FALSE;
3108 }
3109 }
3110 return TRUE;
3111 }
3112 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints)
3113 {
3114 if (!m_objs_array.GetSize()) {
3115 m_objs_array.RemoveAll();
3116 m_objnum_array.RemoveAll();
3117 CFX_PtrArray obj_array;
3118 obj_array.Append(m_arrayAcroforms);
3119 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
3120 if (bRet) {
3121 m_objs_array.RemoveAll();
3122 }
3123 return bRet;
3124 }
3125 CFX_PtrArray new_objs_array;
3126 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
3127 if (bRet) {
3128 int32_t iSize = m_arrayAcroforms.GetSize();
3129 for (int32_t i = 0; i < iSize; ++i) {
3130 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();
3131 }
3132 m_arrayAcroforms.RemoveAll();
3133 } else {
3134 m_objs_array.RemoveAll();
3135 m_objs_array.Append(new_objs_array);
3136 }
3137 return bRet;
3138 }
3139 FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints)
3140 {
3141 FX_BOOL bExist = FALSE;
3142 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
3143 if (!bExist) {
3144 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3145 return TRUE;
3146 }
3147 if (!m_pAcroForm) {
3148 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3149 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3150 return TRUE;
3151 }
3152 return FALSE;
3153 }
3154 m_arrayAcroforms.Add(m_pAcroForm);
3155 m_docStatus = PDF_DATAAVAIL_PAGETREE; 3215 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3156 return TRUE; 3216 return TRUE;
3157 } 3217 }
3158 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints) 3218 if (!m_pAcroForm) {
3159 { 3219 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3160 switch (m_docStatus) { 3220 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3161 case PDF_DATAAVAIL_HEADER: 3221 return TRUE;
3162 return CheckHeader(pHints); 3222 }
3163 case PDF_DATAAVAIL_FIRSTPAGE: 3223 return FALSE;
3164 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: 3224 }
3165 return CheckFirstPage(pHints); 3225 m_arrayAcroforms.Add(m_pAcroForm);
3166 case PDF_DATAAVAIL_END: 3226 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3167 return CheckEnd(pHints); 3227 return TRUE;
3168 case PDF_DATAAVAIL_CROSSREF: 3228 }
3169 return CheckCrossRef(pHints); 3229 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) {
3170 case PDF_DATAAVAIL_CROSSREF_ITEM: 3230 switch (m_docStatus) {
3171 return CheckCrossRefItem(pHints); 3231 case PDF_DATAAVAIL_HEADER:
3172 case PDF_DATAAVAIL_CROSSREF_STREAM: 3232 return CheckHeader(pHints);
3173 return CheckAllCrossRefStream(pHints); 3233 case PDF_DATAAVAIL_FIRSTPAGE:
3174 case PDF_DATAAVAIL_TRAILER: 3234 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
3175 return CheckTrailer(pHints); 3235 return CheckFirstPage(pHints);
3176 case PDF_DATAAVAIL_TRAILER_APPEND: 3236 case PDF_DATAAVAIL_END:
3177 return CheckTrailerAppend(pHints); 3237 return CheckEnd(pHints);
3178 case PDF_DATAAVAIL_LOADALLCRSOSSREF: 3238 case PDF_DATAAVAIL_CROSSREF:
3179 return LoadAllXref(pHints); 3239 return CheckCrossRef(pHints);
3180 case PDF_DATAAVAIL_LOADALLFILE: 3240 case PDF_DATAAVAIL_CROSSREF_ITEM:
3181 return LoadAllFile(pHints); 3241 return CheckCrossRefItem(pHints);
3182 case PDF_DATAAVAIL_ROOT: 3242 case PDF_DATAAVAIL_CROSSREF_STREAM:
3183 return CheckRoot(pHints); 3243 return CheckAllCrossRefStream(pHints);
3184 case PDF_DATAAVAIL_INFO: 3244 case PDF_DATAAVAIL_TRAILER:
3185 return CheckInfo(pHints); 3245 return CheckTrailer(pHints);
3186 case PDF_DATAAVAIL_ACROFORM: 3246 case PDF_DATAAVAIL_TRAILER_APPEND:
3187 return CheckAcroForm(pHints); 3247 return CheckTrailerAppend(pHints);
3188 case PDF_DATAAVAIL_PAGETREE: 3248 case PDF_DATAAVAIL_LOADALLCRSOSSREF:
3189 if (m_bTotalLoadPageTree) { 3249 return LoadAllXref(pHints);
3190 return CheckPages(pHints); 3250 case PDF_DATAAVAIL_LOADALLFILE:
3191 } 3251 return LoadAllFile(pHints);
3192 return LoadDocPages(pHints); 3252 case PDF_DATAAVAIL_ROOT:
3193 case PDF_DATAAVAIL_PAGE: 3253 return CheckRoot(pHints);
3194 if (m_bTotalLoadPageTree) { 3254 case PDF_DATAAVAIL_INFO:
3195 return CheckPage(pHints); 3255 return CheckInfo(pHints);
3196 } 3256 case PDF_DATAAVAIL_ACROFORM:
3197 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD; 3257 return CheckAcroForm(pHints);
3198 return TRUE; 3258 case PDF_DATAAVAIL_PAGETREE:
3199 case PDF_DATAAVAIL_ERROR: 3259 if (m_bTotalLoadPageTree) {
3200 return LoadAllFile(pHints); 3260 return CheckPages(pHints);
3201 case PDF_DATAAVAIL_PAGE_LATERLOAD: 3261 }
3202 m_docStatus = PDF_DATAAVAIL_PAGE; 3262 return LoadDocPages(pHints);
3203 default: 3263 case PDF_DATAAVAIL_PAGE:
3204 m_bDocAvail = TRUE; 3264 if (m_bTotalLoadPageTree) {
3205 return TRUE; 3265 return CheckPage(pHints);
3206 } 3266 }
3207 } 3267 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;
3208 FX_BOOL»CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) 3268 return TRUE;
3209 { 3269 case PDF_DATAAVAIL_ERROR:
3210 switch (m_docStatus) { 3270 return LoadAllFile(pHints);
3211 case PDF_DATAAVAIL_PAGETREE: 3271 case PDF_DATAAVAIL_PAGE_LATERLOAD:
3212 return CheckPages(pHints); 3272 m_docStatus = PDF_DATAAVAIL_PAGE;
3213 case PDF_DATAAVAIL_PAGE: 3273 default:
3214 return CheckPage(pHints); 3274 m_bDocAvail = TRUE;
3215 case PDF_DATAAVAIL_ERROR: 3275 return TRUE;
3216 return LoadAllFile(pHints); 3276 }
3217 default: 3277 }
3218 m_bPagesTreeLoad = TRUE; 3278 FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) {
3219 m_bPagesLoad = TRUE; 3279 switch (m_docStatus) {
3220 return TRUE; 3280 case PDF_DATAAVAIL_PAGETREE:
3221 } 3281 return CheckPages(pHints);
3222 } 3282 case PDF_DATAAVAIL_PAGE:
3223 FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) 3283 return CheckPage(pHints);
3224 { 3284 case PDF_DATAAVAIL_ERROR:
3225 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { 3285 return LoadAllFile(pHints);
3226 m_docStatus = PDF_DATAAVAIL_DONE; 3286 default:
3227 return TRUE; 3287 m_bPagesTreeLoad = TRUE;
3228 } 3288 m_bPagesLoad = TRUE;
3229 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen); 3289 return TRUE;
3230 return FALSE; 3290 }
3231 } 3291 }
3232 FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) 3292 FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) {
3233 { 3293 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) {
3234 m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); 3294 m_docStatus = PDF_DATAAVAIL_DONE;
3235 m_parser.m_bOwnFileRead = FALSE;
3236 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && !m_parser.LoadAllCros sRefV5(m_dwLastXRefOffset)) {
3237 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3238 return FALSE;
3239 }
3240 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSi ze(), sizeof(FX_FILESIZE), _CompareFileSize);
3241 m_dwRootObjNum = m_parser.GetRootObjNum();
3242 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3243 m_pCurrentParser = &m_parser;
3244 m_docStatus = PDF_DATAAVAIL_ROOT;
3245 return TRUE; 3295 return TRUE;
3246 } 3296 }
3247 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHint s, FX_BOOL *pExistInFile) 3297 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen);
3248 { 3298 return FALSE;
3249 CPDF_Object *pRet = NULL; 3299 }
3250 FX_DWORD original_size = 0; 3300 FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) {
3251 FX_FILESIZE offset = 0; 3301 m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset);
3252 CPDF_Parser *pParser = NULL; 3302 m_parser.m_bOwnFileRead = FALSE;
3253 3303 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) &&
3254 if (pExistInFile) { 3304 !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {
3255 *pExistInFile = TRUE; 3305 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3256 } 3306 return FALSE;
3257 3307 }
3258 if (m_pDocument == NULL) { 3308 FXSYS_qsort(m_parser.m_SortedOffset.GetData(),
3259 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); 3309 m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
3260 offset = m_parser.GetObjectOffset(objnum); 3310 _CompareFileSize);
3261 pParser = &m_parser; 3311 m_dwRootObjNum = m_parser.GetRootObjNum();
3312 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3313 m_pCurrentParser = &m_parser;
3314 m_docStatus = PDF_DATAAVAIL_ROOT;
3315 return TRUE;
3316 }
3317 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum,
3318 IFX_DownloadHints* pHints,
3319 FX_BOOL* pExistInFile) {
3320 CPDF_Object* pRet = NULL;
3321 FX_DWORD original_size = 0;
3322 FX_FILESIZE offset = 0;
3323 CPDF_Parser* pParser = NULL;
3324
3325 if (pExistInFile) {
3326 *pExistInFile = TRUE;
3327 }
3328
3329 if (m_pDocument == NULL) {
3330 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum);
3331 offset = m_parser.GetObjectOffset(objnum);
3332 pParser = &m_parser;
3333 } else {
3334 original_size = GetObjectSize(objnum, offset);
3335 pParser = (CPDF_Parser*)(m_pDocument->GetParser());
3336 }
3337
3338 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size;
3339 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
3340 if (pExistInFile)
3341 *pExistInFile = FALSE;
3342
3343 return NULL;
3344 }
3345
3346 size += offset;
3347 size += 512;
3348 if (!size.IsValid()) {
3349 return NULL;
3350 }
3351
3352 if (size.ValueOrDie() > m_dwFileLen) {
3353 size = m_dwFileLen - offset;
3354 } else {
3355 size = original_size + 512;
3356 }
3357
3358 if (!size.IsValid()) {
3359 return NULL;
3360 }
3361
3362 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3363 pHints->AddSegment(offset, size.ValueOrDie());
3364 return NULL;
3365 }
3366
3367 if (pParser) {
3368 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
3369 }
3370
3371 if (!pRet && pExistInFile) {
3372 *pExistInFile = FALSE;
3373 }
3374
3375 return pRet;
3376 }
3377
3378 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) {
3379 FX_BOOL bExist = FALSE;
3380 CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
3381 if (!bExist) {
3382 if (m_bHaveAcroForm) {
3383 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3262 } else { 3384 } else {
3263 original_size = GetObjectSize(objnum, offset); 3385 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3264 pParser = (CPDF_Parser *)(m_pDocument->GetParser()); 3386 }
3265 } 3387 return TRUE;
3266 3388 }
3267 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; 3389 if (!pInfo) {
3268 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { 3390 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3269 if (pExistInFile) 3391 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3270 *pExistInFile = FALSE; 3392 return TRUE;
3271 3393 }
3272 return NULL; 3394 if (m_Pos == m_dwFileLen) {
3273 } 3395 m_docStatus = PDF_DATAAVAIL_ERROR;
3274 3396 }
3275 size += offset; 3397 return FALSE;
3276 size += 512; 3398 }
3277 if (!size.IsValid()) { 3399 if (pInfo) {
3278 return NULL; 3400 pInfo->Release();
3279 } 3401 }
3280 3402 if (m_bHaveAcroForm) {
3281 if (size.ValueOrDie() > m_dwFileLen) { 3403 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3282 size = m_dwFileLen - offset; 3404 } else {
3405 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3406 }
3407 return TRUE;
3408 }
3409 FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) {
3410 FX_BOOL bExist = FALSE;
3411 m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
3412 if (!bExist) {
3413 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3414 return TRUE;
3415 }
3416 if (!m_pRoot) {
3417 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3418 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3419 return TRUE;
3420 }
3421 return FALSE;
3422 }
3423 CPDF_Dictionary* pDict = m_pRoot->GetDict();
3424 if (!pDict) {
3425 m_docStatus = PDF_DATAAVAIL_ERROR;
3426 return FALSE;
3427 }
3428 CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages"));
3429 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
3430 m_docStatus = PDF_DATAAVAIL_ERROR;
3431 return FALSE;
3432 }
3433 m_PagesObjNum = pRef->GetRefObjNum();
3434 CPDF_Reference* pAcroFormRef =
3435 (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("AcroForm"));
3436 if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) {
3437 m_bHaveAcroForm = TRUE;
3438 m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
3439 }
3440 if (m_dwInfoObjNum) {
3441 m_docStatus = PDF_DATAAVAIL_INFO;
3442 } else {
3443 if (m_bHaveAcroForm) {
3444 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3283 } else { 3445 } else {
3284 size = original_size + 512; 3446 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3285 } 3447 }
3286 3448 }
3287 if (!size.IsValid()) { 3449 return TRUE;
3288 return NULL; 3450 }
3289 } 3451 FX_BOOL CPDF_DataAvail::PreparePageItem() {
3290 3452 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
3291 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { 3453 CPDF_Reference* pRef =
3292 pHints->AddSegment(offset, size.ValueOrDie()); 3454 pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("Pages")) : NULL;
3293 return NULL; 3455 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
3294 } 3456 m_docStatus = PDF_DATAAVAIL_ERROR;
3295 3457 return FALSE;
3296 if (pParser) { 3458 }
3297 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); 3459 m_PagesObjNum = pRef->GetRefObjNum();
3298 } 3460 m_pCurrentParser = (CPDF_Parser*)m_pDocument->GetParser();
3299 3461 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3300 if (!pRet && pExistInFile) { 3462 return TRUE;
3301 *pExistInFile = FALSE; 3463 }
3302 } 3464 FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage) {
3303 3465 if (NULL == m_pageMapCheckState) {
3304 return pRet; 3466 m_pageMapCheckState = new CFX_CMapDWordToDWord();
3305 } 3467 }
3306 3468 FX_DWORD dwValue = 0;
3307 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) 3469 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) {
3308 {
3309 FX_BOOL bExist = FALSE;
3310 CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
3311 if (!bExist) {
3312 if (m_bHaveAcroForm) {
3313 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3314 } else {
3315 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3316 }
3317 return TRUE;
3318 }
3319 if (!pInfo) {
3320 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3321 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3322 return TRUE;
3323 }
3324 if (m_Pos == m_dwFileLen) {
3325 m_docStatus = PDF_DATAAVAIL_ERROR;
3326 }
3327 return FALSE;
3328 }
3329 if (pInfo) {
3330 pInfo->Release();
3331 }
3332 if (m_bHaveAcroForm) {
3333 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3334 } else {
3335 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3336 }
3337 return TRUE;
3338 }
3339 FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints)
3340 {
3341 FX_BOOL bExist = FALSE;
3342 m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
3343 if (!bExist) {
3344 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3345 return TRUE;
3346 }
3347 if (!m_pRoot) {
3348 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3349 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3350 return TRUE;
3351 }
3352 return FALSE;
3353 }
3354 CPDF_Dictionary* pDict = m_pRoot->GetDict();
3355 if (!pDict) {
3356 m_docStatus = PDF_DATAAVAIL_ERROR;
3357 return FALSE;
3358 }
3359 CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages")) ;
3360 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
3361 m_docStatus = PDF_DATAAVAIL_ERROR;
3362 return FALSE;
3363 }
3364 m_PagesObjNum = pRef->GetRefObjNum();
3365 CPDF_Reference* pAcroFormRef = (CPDF_Reference*)m_pRoot->GetDict()->GetEleme nt(FX_BSTRC("AcroForm"));
3366 if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) {
3367 m_bHaveAcroForm = TRUE;
3368 m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
3369 }
3370 if (m_dwInfoObjNum) {
3371 m_docStatus = PDF_DATAAVAIL_INFO;
3372 } else {
3373 if (m_bHaveAcroForm) {
3374 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3375 } else {
3376 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3377 }
3378 }
3379 return TRUE;
3380 }
3381 FX_BOOL CPDF_DataAvail::PreparePageItem()
3382 {
3383 CPDF_Dictionary *pRoot = m_pDocument->GetRoot();
3384 CPDF_Reference* pRef = pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC(" Pages")) : NULL;
3385 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
3386 m_docStatus = PDF_DATAAVAIL_ERROR;
3387 return FALSE;
3388 }
3389 m_PagesObjNum = pRef->GetRefObjNum();
3390 m_pCurrentParser = (CPDF_Parser *)m_pDocument->GetParser();
3391 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3392 return TRUE;
3393 }
3394 FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage)
3395 {
3396 if (NULL == m_pageMapCheckState) {
3397 m_pageMapCheckState = new CFX_CMapDWordToDWord();
3398 }
3399 FX_DWORD dwValue = 0;
3400 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) {
3401 m_pageMapCheckState->SetAt(iPage, 1);
3402 return TRUE;
3403 }
3404 if (dwValue != 0) {
3405 return FALSE;
3406 }
3407 m_pageMapCheckState->SetAt(iPage, 1); 3470 m_pageMapCheckState->SetAt(iPage, 1);
3408 return TRUE; 3471 return TRUE;
3409 } 3472 }
3410 void CPDF_DataAvail::ResetFirstCheck(int iPage) 3473 if (dwValue != 0) {
3411 { 3474 return FALSE;
3412 if (NULL == m_pageMapCheckState) { 3475 }
3413 m_pageMapCheckState = new CFX_CMapDWordToDWord(); 3476 m_pageMapCheckState->SetAt(iPage, 1);
3414 } 3477 return TRUE;
3415 FX_DWORD dwValue = 1; 3478 }
3416 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { 3479 void CPDF_DataAvail::ResetFirstCheck(int iPage) {
3417 return; 3480 if (NULL == m_pageMapCheckState) {
3418 } 3481 m_pageMapCheckState = new CFX_CMapDWordToDWord();
3419 m_pageMapCheckState->SetAt(iPage, 0); 3482 }
3420 } 3483 FX_DWORD dwValue = 1;
3421 FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) 3484 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) {
3422 { 3485 return;
3423 FX_DWORD iPageObjs = m_PageObjList.GetSize(); 3486 }
3424 CFX_DWordArray UnavailObjList; 3487 m_pageMapCheckState->SetAt(iPage, 0);
3425 for (FX_DWORD i = 0; i < iPageObjs; ++i) { 3488 }
3426 FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i); 3489 FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) {
3427 FX_BOOL bExist = FALSE; 3490 FX_DWORD iPageObjs = m_PageObjList.GetSize();
3428 CPDF_Object *pObj = GetObject(dwPageObjNum, pHints, &bExist); 3491 CFX_DWordArray UnavailObjList;
3429 if (!pObj) { 3492 for (FX_DWORD i = 0; i < iPageObjs; ++i) {
3430 if (bExist) { 3493 FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i);
3431 UnavailObjList.Add(dwPageObjNum); 3494 FX_BOOL bExist = FALSE;
3432 } 3495 CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist);
3433 continue; 3496 if (!pObj) {
3434 } 3497 if (bExist) {
3435 if (pObj->GetType() == PDFOBJ_ARRAY) { 3498 UnavailObjList.Add(dwPageObjNum);
3436 CPDF_Array *pArray = pObj->GetArray(); 3499 }
3437 if (pArray) { 3500 continue;
3438 int32_t iSize = pArray->GetCount(); 3501 }
3439 CPDF_Object *pItem = NULL; 3502 if (pObj->GetType() == PDFOBJ_ARRAY) {
3440 for (int32_t j = 0; j < iSize; ++j) { 3503 CPDF_Array* pArray = pObj->GetArray();
3441 pItem = pArray->GetElement(j); 3504 if (pArray) {
3442 if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) { 3505 int32_t iSize = pArray->GetCount();
3443 UnavailObjList.Add(((CPDF_Reference *)pItem)->GetRefObjN um()); 3506 CPDF_Object* pItem = NULL;
3444 } 3507 for (int32_t j = 0; j < iSize; ++j) {
3445 } 3508 pItem = pArray->GetElement(j);
3446 } 3509 if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) {
3447 } 3510 UnavailObjList.Add(((CPDF_Reference*)pItem)->GetRefObjNum());
3448 if (pObj->GetType() != PDFOBJ_DICTIONARY) { 3511 }
3449 pObj->Release(); 3512 }
3450 continue; 3513 }
3451 } 3514 }
3452 CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type")); 3515 if (pObj->GetType() != PDFOBJ_DICTIONARY) {
3453 if (type == FX_BSTRC("Pages")) { 3516 pObj->Release();
3454 m_PagesArray.Add(pObj); 3517 continue;
3455 continue; 3518 }
3456 } 3519 CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type"));
3457 pObj->Release(); 3520 if (type == FX_BSTRC("Pages")) {
3458 } 3521 m_PagesArray.Add(pObj);
3459 m_PageObjList.RemoveAll(); 3522 continue;
3460 if (UnavailObjList.GetSize()) { 3523 }
3461 m_PageObjList.Append(UnavailObjList); 3524 pObj->Release();
3462 return FALSE; 3525 }
3463 } 3526 m_PageObjList.RemoveAll();
3464 FX_DWORD iPages = m_PagesArray.GetSize(); 3527 if (UnavailObjList.GetSize()) {
3465 for (FX_DWORD i = 0; i < iPages; i++) { 3528 m_PageObjList.Append(UnavailObjList);
3466 CPDF_Object *pPages = (CPDF_Object *)m_PagesArray.GetAt(i); 3529 return FALSE;
3467 if (!pPages) { 3530 }
3468 continue; 3531 FX_DWORD iPages = m_PagesArray.GetSize();
3469 } 3532 for (FX_DWORD i = 0; i < iPages; i++) {
3470 if (!GetPageKids(m_pCurrentParser, pPages)) { 3533 CPDF_Object* pPages = (CPDF_Object*)m_PagesArray.GetAt(i);
3471 pPages->Release(); 3534 if (!pPages) {
3472 while (++i < iPages) { 3535 continue;
3473 pPages = (CPDF_Object *)m_PagesArray.GetAt(i); 3536 }
3474 pPages->Release(); 3537 if (!GetPageKids(m_pCurrentParser, pPages)) {
3475 } 3538 pPages->Release();
3476 m_PagesArray.RemoveAll(); 3539 while (++i < iPages) {
3477 m_docStatus = PDF_DATAAVAIL_ERROR; 3540 pPages = (CPDF_Object*)m_PagesArray.GetAt(i);
3478 return FALSE;
3479 }
3480 pPages->Release(); 3541 pPages->Release();
3481 } 3542 }
3482 m_PagesArray.RemoveAll(); 3543 m_PagesArray.RemoveAll();
3483 if (!m_PageObjList.GetSize()) { 3544 m_docStatus = PDF_DATAAVAIL_ERROR;
3484 m_docStatus = PDF_DATAAVAIL_DONE; 3545 return FALSE;
3485 } 3546 }
3547 pPages->Release();
3548 }
3549 m_PagesArray.RemoveAll();
3550 if (!m_PageObjList.GetSize()) {
3551 m_docStatus = PDF_DATAAVAIL_DONE;
3552 }
3553 return TRUE;
3554 }
3555 FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) {
3556 if (!pParser) {
3557 m_docStatus = PDF_DATAAVAIL_ERROR;
3558 return FALSE;
3559 }
3560 CPDF_Dictionary* pDict = pPages->GetDict();
3561 CPDF_Object* pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL;
3562 if (!pKids) {
3486 return TRUE; 3563 return TRUE;
3487 } 3564 }
3488 FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages) 3565 switch (pKids->GetType()) {
3489 { 3566 case PDFOBJ_REFERENCE: {
3490 if (!pParser) { 3567 CPDF_Reference* pKid = (CPDF_Reference*)pKids;
3491 m_docStatus = PDF_DATAAVAIL_ERROR; 3568 m_PageObjList.Add(pKid->GetRefObjNum());
3492 return FALSE; 3569 } break;
3493 } 3570 case PDFOBJ_ARRAY: {
3494 CPDF_Dictionary* pDict = pPages->GetDict(); 3571 CPDF_Array* pKidsArray = (CPDF_Array*)pKids;
3495 CPDF_Object *pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL; 3572 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
3496 if (!pKids) { 3573 CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i);
3497 return TRUE; 3574 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) {
3498 } 3575 m_PageObjList.Add(((CPDF_Reference*)pKid)->GetRefObjNum());
3499 switch (pKids->GetType()) { 3576 }
3500 case PDFOBJ_REFERENCE: { 3577 }
3501 CPDF_Reference *pKid = (CPDF_Reference *)pKids; 3578 } break;
3502 m_PageObjList.Add(pKid->GetRefObjNum()); 3579 default:
3503 } 3580 m_docStatus = PDF_DATAAVAIL_ERROR;
3504 break; 3581 return FALSE;
3505 case PDFOBJ_ARRAY: { 3582 }
3506 CPDF_Array *pKidsArray = (CPDF_Array *)pKids; 3583 return TRUE;
3507 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { 3584 }
3508 CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElement(i) ; 3585 FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) {
3509 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { 3586 FX_BOOL bExist = FALSE;
3510 m_PageObjList.Add(((CPDF_Reference *)pKid)->GetRefObjNum ()); 3587 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
3511 } 3588 if (!bExist) {
3512 } 3589 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3513 }
3514 break;
3515 default:
3516 m_docStatus = PDF_DATAAVAIL_ERROR;
3517 return FALSE;
3518 }
3519 return TRUE; 3590 return TRUE;
3520 } 3591 }
3521 FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) 3592 if (!pPages) {
3522 { 3593 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3523 FX_BOOL bExist = FALSE; 3594 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3524 CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); 3595 return TRUE;
3525 if (!bExist) { 3596 }
3526 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; 3597 return FALSE;
3527 return TRUE; 3598 }
3528 } 3599 if (!GetPageKids(m_pCurrentParser, pPages)) {
3529 if (!pPages) {
3530 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3531 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3532 return TRUE;
3533 }
3534 return FALSE;
3535 }
3536 if (!GetPageKids(m_pCurrentParser, pPages)) {
3537 pPages->Release();
3538 m_docStatus = PDF_DATAAVAIL_ERROR;
3539 return FALSE;
3540 }
3541 pPages->Release(); 3600 pPages->Release();
3542 m_docStatus = PDF_DATAAVAIL_PAGE; 3601 m_docStatus = PDF_DATAAVAIL_ERROR;
3543 return TRUE; 3602 return FALSE;
3544 } 3603 }
3545 FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) 3604 pPages->Release();
3546 { 3605 m_docStatus = PDF_DATAAVAIL_PAGE;
3547 FX_DWORD req_size = 1024; 3606 return TRUE;
3548 if ((FX_FILESIZE)req_size > m_dwFileLen) { 3607 }
3549 req_size = (FX_DWORD)m_dwFileLen; 3608 FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) {
3550 } 3609 FX_DWORD req_size = 1024;
3551 if (m_pFileAvail->IsDataAvail(0, req_size)) { 3610 if ((FX_FILESIZE)req_size > m_dwFileLen) {
3552 uint8_t buffer[1024]; 3611 req_size = (FX_DWORD)m_dwFileLen;
3553 m_pFileRead->ReadBlock(buffer, 0, req_size); 3612 }
3554 if (IsLinearizedFile(buffer, req_size)) { 3613 if (m_pFileAvail->IsDataAvail(0, req_size)) {
3555 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
3556 } else {
3557 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3558 return FALSE;
3559 }
3560 m_docStatus = PDF_DATAAVAIL_END;
3561 }
3562 return TRUE;
3563 }
3564 pHints->AddSegment(0, req_size);
3565 return FALSE;
3566 }
3567 FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints *pHints)
3568 {
3569 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
3570 CPDF_Object *pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL;
3571 if (!pEndOffSet) {
3572 m_docStatus = PDF_DATAAVAIL_ERROR;
3573 return FALSE;
3574 }
3575 CPDF_Object *pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL;
3576 if (!pXRefOffset) {
3577 m_docStatus = PDF_DATAAVAIL_ERROR;
3578 return FALSE;
3579 }
3580 CPDF_Object *pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL;
3581 if (!pFileLen) {
3582 m_docStatus = PDF_DATAAVAIL_ERROR;
3583 return FALSE;
3584 }
3585 FX_BOOL bNeedDownLoad = FALSE;
3586 if (pEndOffSet->GetType() == PDFOBJ_NUMBER) {
3587 FX_DWORD dwEnd = pEndOffSet->GetInteger();
3588 dwEnd += 512;
3589 if ((FX_FILESIZE)dwEnd > m_dwFileLen) {
3590 dwEnd = (FX_DWORD)m_dwFileLen;
3591 }
3592 int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen);
3593 int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0;
3594 if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) {
3595 pHints->AddSegment(iStartPos, iSize);
3596 bNeedDownLoad = TRUE;
3597 }
3598 }
3599 m_dwLastXRefOffset = 0;
3600 FX_FILESIZE dwFileLen = 0;
3601 if (pXRefOffset->GetType() == PDFOBJ_NUMBER) {
3602 m_dwLastXRefOffset = pXRefOffset->GetInteger();
3603 }
3604 if (pFileLen->GetType() == PDFOBJ_NUMBER) {
3605 dwFileLen = pFileLen->GetInteger();
3606 }
3607 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(dwFileLen - m_ dwLastXRefOffset))) {
3608 if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE)» {
3609 FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset);
3610 FX_FILESIZE offset = m_dwLastXRefOffset;
3611 if (dwSize < 512 && dwFileLen > 512) {
3612 dwSize = 512;
3613 offset = dwFileLen - 512;
3614 }
3615 pHints->AddSegment(offset, dwSize);
3616 }
3617 } else {
3618 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3619 }
3620 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
3621 m_docStatus = PDF_DATAAVAIL_DONE;
3622 return TRUE;
3623 }
3624 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3625 return FALSE;
3626 }
3627 CPDF_Object» * CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWOR D objnum)
3628 {
3629 FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
3630 m_syntaxParser.RestorePos(pos);
3631 FX_BOOL bIsNumber;
3632 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber);
3633 if (!bIsNumber) {
3634 return NULL;
3635 }
3636 FX_DWORD parser_objnum = FXSYS_atoi(word);
3637 if (objnum && parser_objnum != objnum) {
3638 return NULL;
3639 }
3640 word = m_syntaxParser.GetNextWord(bIsNumber);
3641 if (!bIsNumber) {
3642 return NULL;
3643 }
3644 FX_DWORD gennum = FXSYS_atoi(word);
3645 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) {
3646 m_syntaxParser.RestorePos(SavedPos);
3647 return NULL;
3648 }
3649 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0);
3650 m_syntaxParser.RestorePos(SavedPos);
3651 return pObj;
3652 }
3653 int32_t CPDF_DataAvail::IsLinearizedPDF()
3654 {
3655 FX_DWORD req_size = 1024;
3656 if (!m_pFileAvail->IsDataAvail(0, req_size)) {
3657 return PDF_UNKNOW_LINEARIZED;
3658 }
3659 if (!m_pFileRead) {
3660 return PDF_NOT_LINEARIZED;
3661 }
3662 FX_FILESIZE dwSize = m_pFileRead->GetSize();
3663 if (dwSize < (FX_FILESIZE)req_size) {
3664 return PDF_UNKNOW_LINEARIZED;
3665 }
3666 uint8_t buffer[1024]; 3614 uint8_t buffer[1024];
3667 m_pFileRead->ReadBlock(buffer, 0, req_size); 3615 m_pFileRead->ReadBlock(buffer, 0, req_size);
3668 if (IsLinearizedFile(buffer, req_size)) { 3616 if (IsLinearizedFile(buffer, req_size)) {
3669 return PDF_IS_LINEARIZED; 3617 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
3670 } 3618 } else {
3619 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
3620 return FALSE;
3621 }
3622 m_docStatus = PDF_DATAAVAIL_END;
3623 }
3624 return TRUE;
3625 }
3626 pHints->AddSegment(0, req_size);
3627 return FALSE;
3628 }
3629 FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints* pHints) {
3630 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
3631 CPDF_Object* pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL;
3632 if (!pEndOffSet) {
3633 m_docStatus = PDF_DATAAVAIL_ERROR;
3634 return FALSE;
3635 }
3636 CPDF_Object* pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL;
3637 if (!pXRefOffset) {
3638 m_docStatus = PDF_DATAAVAIL_ERROR;
3639 return FALSE;
3640 }
3641 CPDF_Object* pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL;
3642 if (!pFileLen) {
3643 m_docStatus = PDF_DATAAVAIL_ERROR;
3644 return FALSE;
3645 }
3646 FX_BOOL bNeedDownLoad = FALSE;
3647 if (pEndOffSet->GetType() == PDFOBJ_NUMBER) {
3648 FX_DWORD dwEnd = pEndOffSet->GetInteger();
3649 dwEnd += 512;
3650 if ((FX_FILESIZE)dwEnd > m_dwFileLen) {
3651 dwEnd = (FX_DWORD)m_dwFileLen;
3652 }
3653 int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen);
3654 int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0;
3655 if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) {
3656 pHints->AddSegment(iStartPos, iSize);
3657 bNeedDownLoad = TRUE;
3658 }
3659 }
3660 m_dwLastXRefOffset = 0;
3661 FX_FILESIZE dwFileLen = 0;
3662 if (pXRefOffset->GetType() == PDFOBJ_NUMBER) {
3663 m_dwLastXRefOffset = pXRefOffset->GetInteger();
3664 }
3665 if (pFileLen->GetType() == PDFOBJ_NUMBER) {
3666 dwFileLen = pFileLen->GetInteger();
3667 }
3668 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
3669 (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) {
3670 if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) {
3671 FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset);
3672 FX_FILESIZE offset = m_dwLastXRefOffset;
3673 if (dwSize < 512 && dwFileLen > 512) {
3674 dwSize = 512;
3675 offset = dwFileLen - 512;
3676 }
3677 pHints->AddSegment(offset, dwSize);
3678 }
3679 } else {
3680 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3681 }
3682 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
3683 m_docStatus = PDF_DATAAVAIL_DONE;
3684 return TRUE;
3685 }
3686 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3687 return FALSE;
3688 }
3689 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos,
3690 FX_DWORD objnum) {
3691 FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
3692 m_syntaxParser.RestorePos(pos);
3693 FX_BOOL bIsNumber;
3694 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber);
3695 if (!bIsNumber) {
3696 return NULL;
3697 }
3698 FX_DWORD parser_objnum = FXSYS_atoi(word);
3699 if (objnum && parser_objnum != objnum) {
3700 return NULL;
3701 }
3702 word = m_syntaxParser.GetNextWord(bIsNumber);
3703 if (!bIsNumber) {
3704 return NULL;
3705 }
3706 FX_DWORD gennum = FXSYS_atoi(word);
3707 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) {
3708 m_syntaxParser.RestorePos(SavedPos);
3709 return NULL;
3710 }
3711 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0);
3712 m_syntaxParser.RestorePos(SavedPos);
3713 return pObj;
3714 }
3715 int32_t CPDF_DataAvail::IsLinearizedPDF() {
3716 FX_DWORD req_size = 1024;
3717 if (!m_pFileAvail->IsDataAvail(0, req_size)) {
3718 return PDF_UNKNOW_LINEARIZED;
3719 }
3720 if (!m_pFileRead) {
3671 return PDF_NOT_LINEARIZED; 3721 return PDF_NOT_LINEARIZED;
3672 } 3722 }
3673 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) 3723 FX_FILESIZE dwSize = m_pFileRead->GetSize();
3674 { 3724 if (dwSize < (FX_FILESIZE)req_size) {
3675 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pData, (size_t)d wLen, FALSE)); 3725 return PDF_UNKNOW_LINEARIZED;
3676 int32_t offset = GetHeaderOffset(file.Get()); 3726 }
3677 if (offset == -1) { 3727 uint8_t buffer[1024];
3728 m_pFileRead->ReadBlock(buffer, 0, req_size);
3729 if (IsLinearizedFile(buffer, req_size)) {
3730 return PDF_IS_LINEARIZED;
3731 }
3732 return PDF_NOT_LINEARIZED;
3733 }
3734 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) {
3735 CFX_SmartPointer<IFX_FileStream> file(
3736 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE));
3737 int32_t offset = GetHeaderOffset(file.Get());
3738 if (offset == -1) {
3739 m_docStatus = PDF_DATAAVAIL_ERROR;
3740 return FALSE;
3741 }
3742 m_dwHeaderOffset = offset;
3743 m_syntaxParser.InitParser(file.Get(), offset);
3744 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
3745 FX_BOOL bNumber = FALSE;
3746 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber);
3747 if (!bNumber) {
3748 return FALSE;
3749 }
3750 FX_DWORD objnum = FXSYS_atoi(wordObjNum);
3751 if (m_pLinearized) {
3752 m_pLinearized->Release();
3753 m_pLinearized = NULL;
3754 }
3755 m_pLinearized =
3756 ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum);
3757 if (!m_pLinearized) {
3758 return FALSE;
3759 }
3760 if (m_pLinearized->GetDict() &&
3761 m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {
3762 CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
3763 if (!pLen) {
3764 return FALSE;
3765 }
3766 if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) {
3767 return FALSE;
3768 }
3769 m_bLinearized = TRUE;
3770 CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
3771 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
3772 m_dwFirstPageNo = pNo->GetInteger();
3773 }
3774 return TRUE;
3775 }
3776 return FALSE;
3777 }
3778 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) {
3779 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);
3780 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos);
3781 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
3782 uint8_t buffer[1024];
3783 m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
3784 CFX_SmartPointer<IFX_FileStream> file(
3785 FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE));
3786 m_syntaxParser.InitParser(file.Get(), 0);
3787 m_syntaxParser.RestorePos(dwSize - 1);
3788 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) {
3789 FX_BOOL bNumber;
3790 m_syntaxParser.GetNextWord(bNumber);
3791 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber);
3792 if (!bNumber) {
3678 m_docStatus = PDF_DATAAVAIL_ERROR; 3793 m_docStatus = PDF_DATAAVAIL_ERROR;
3679 return FALSE; 3794 return FALSE;
3680 } 3795 }
3681 m_dwHeaderOffset = offset; 3796 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
3682 m_syntaxParser.InitParser(file.Get(), offset); 3797 if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
3683 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
3684 FX_BOOL bNumber = FALSE;
3685 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber);
3686 if (!bNumber) {
3687 return FALSE;
3688 }
3689 FX_DWORD objnum = FXSYS_atoi(wordObjNum);
3690 if (m_pLinearized) {
3691 m_pLinearized->Release();
3692 m_pLinearized = NULL;
3693 }
3694 m_pLinearized = ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, obj num);
3695 if (!m_pLinearized) {
3696 return FALSE;
3697 }
3698 if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTR C("Linearized"))) {
3699 CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
3700 if (!pLen) {
3701 return FALSE;
3702 }
3703 if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) {
3704 return FALSE;
3705 }
3706 m_bLinearized = TRUE;
3707 CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
3708 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
3709 m_dwFirstPageNo = pNo->GetInteger();
3710 }
3711 return TRUE;
3712 }
3713 return FALSE;
3714 }
3715 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints)
3716 {
3717 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);
3718 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos);
3719 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
3720 uint8_t buffer[1024];
3721 m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
3722 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(buffer, (siz e_t)dwSize, FALSE));
3723 m_syntaxParser.InitParser(file.Get(), 0);
3724 m_syntaxParser.RestorePos(dwSize - 1);
3725 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize )) {
3726 FX_BOOL bNumber;
3727 m_syntaxParser.GetNextWord(bNumber);
3728 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber);
3729 if (!bNumber) {
3730 m_docStatus = PDF_DATAAVAIL_ERROR;
3731 return FALSE;
3732 }
3733 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
3734 if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
3735 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3736 return TRUE;
3737 }
3738 m_dwLastXRefOffset = m_dwXRefOffset;
3739 SetStartOffset(m_dwXRefOffset);
3740 m_docStatus = PDF_DATAAVAIL_CROSSREF;
3741 return TRUE;
3742 }
3743 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; 3798 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3744 return TRUE; 3799 return TRUE;
3745 } 3800 }
3746 pHints->AddSegment(req_pos, dwSize); 3801 m_dwLastXRefOffset = m_dwXRefOffset;
3747 return FALSE; 3802 SetStartOffset(m_dwXRefOffset);
3748 } 3803 m_docStatus = PDF_DATAAVAIL_CROSSREF;
3749 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, FX_FILESI ZE &xref_offset) 3804 return TRUE;
3750 { 3805 }
3751 xref_offset = 0; 3806 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3752 FX_DWORD req_size = (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_P os : 512); 3807 return TRUE;
3753 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { 3808 }
3754 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); 3809 pHints->AddSegment(req_pos, dwSize);
3755 CFX_BinaryBuf buf(iSize); 3810 return FALSE;
3756 uint8_t* pBuf = buf.GetBuffer(); 3811 }
3757 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); 3812 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints,
3758 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_ t)iSize, FALSE)); 3813 FX_FILESIZE& xref_offset) {
3759 m_parser.m_Syntax.InitParser(file.Get(), 0); 3814 xref_offset = 0;
3760 FX_BOOL bNumber = FALSE; 3815 FX_DWORD req_size =
3761 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); 3816 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
3762 if (!bNumber) { 3817 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) {
3763 return -1; 3818 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam);
3764 } 3819 CFX_BinaryBuf buf(iSize);
3765 FX_DWORD objNum = FXSYS_atoi(objnum); 3820 uint8_t* pBuf = buf.GetBuffer();
3766 CPDF_Object *pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL ); 3821 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
3767 if (!pObj) { 3822 CFX_SmartPointer<IFX_FileStream> file(
3768 m_Pos += m_parser.m_Syntax.SavePos(); 3823 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
3769 return 0; 3824 m_parser.m_Syntax.InitParser(file.Get(), 0);
3770 } 3825 FX_BOOL bNumber = FALSE;
3771 CPDF_Dictionary* pDict = pObj->GetDict(); 3826 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber);
3772 CPDF_Object *pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL; 3827 if (!bNumber) {
3773 if (pName && pName->GetType() == PDFOBJ_NAME) { 3828 return -1;
3774 if (pName->GetString() == FX_BSTRC("XRef")) { 3829 }
3775 m_Pos += m_parser.m_Syntax.SavePos(); 3830 FX_DWORD objNum = FXSYS_atoi(objnum);
3776 xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev")); 3831 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL);
3777 pObj->Release(); 3832 if (!pObj) {
3778 return 1; 3833 m_Pos += m_parser.m_Syntax.SavePos();
3779 } 3834 return 0;
3780 } 3835 }
3836 CPDF_Dictionary* pDict = pObj->GetDict();
3837 CPDF_Object* pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL;
3838 if (pName && pName->GetType() == PDFOBJ_NAME) {
3839 if (pName->GetString() == FX_BSTRC("XRef")) {
3840 m_Pos += m_parser.m_Syntax.SavePos();
3841 xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev"));
3781 pObj->Release(); 3842 pObj->Release();
3782 return -1; 3843 return 1;
3783 } 3844 }
3784 pHints->AddSegment(m_Pos, req_size); 3845 }
3785 return 0; 3846 pObj->Release();
3786 } 3847 return -1;
3787 inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) 3848 }
3788 { 3849 pHints->AddSegment(m_Pos, req_size);
3789 m_Pos = dwOffset; 3850 return 0;
3851 }
3852 inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) {
3853 m_Pos = dwOffset;
3790 } 3854 }
3791 #define MAX_WORD_BUFFER 256 3855 #define MAX_WORD_BUFFER 256
3792 FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString &token) 3856 FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString& token) {
3793 { 3857 m_WordSize = 0;
3794 m_WordSize = 0; 3858 uint8_t ch;
3795 uint8_t ch; 3859 if (!GetNextChar(ch)) {
3796 if (!GetNextChar(ch)) { 3860 return FALSE;
3861 }
3862 uint8_t type = PDF_CharType[ch];
3863 while (1) {
3864 while (type == 'W') {
3865 if (!GetNextChar(ch)) {
3797 return FALSE; 3866 return FALSE;
3798 } 3867 }
3799 uint8_t type = PDF_CharType[ch]; 3868 type = PDF_CharType[ch];
3869 }
3870 if (ch != '%') {
3871 break;
3872 }
3800 while (1) { 3873 while (1) {
3801 while (type == 'W') { 3874 if (!GetNextChar(ch)) {
3802 if (!GetNextChar(ch)) { 3875 return FALSE;
3803 return FALSE; 3876 }
3804 } 3877 if (ch == '\r' || ch == '\n') {
3805 type = PDF_CharType[ch]; 3878 break;
3806 } 3879 }
3807 if (ch != '%') { 3880 }
3808 break; 3881 type = PDF_CharType[ch];
3809 } 3882 }
3810 while (1) { 3883 if (type == 'D') {
3811 if (!GetNextChar(ch)) { 3884 m_WordBuffer[m_WordSize++] = ch;
3812 return FALSE; 3885 if (ch == '/') {
3813 } 3886 while (1) {
3814 if (ch == '\r' || ch == '\n') { 3887 if (!GetNextChar(ch)) {
3815 break; 3888 return FALSE;
3816 }
3817 } 3889 }
3818 type = PDF_CharType[ch]; 3890 type = PDF_CharType[ch];
3819 } 3891 if (type != 'R' && type != 'N') {
3820 if (type == 'D') { 3892 m_Pos--;
3893 CFX_ByteString ret(m_WordBuffer, m_WordSize);
3894 token = ret;
3895 return TRUE;
3896 }
3897 if (m_WordSize < MAX_WORD_BUFFER) {
3898 m_WordBuffer[m_WordSize++] = ch;
3899 }
3900 }
3901 } else if (ch == '<') {
3902 if (!GetNextChar(ch)) {
3903 return FALSE;
3904 }
3905 if (ch == '<') {
3821 m_WordBuffer[m_WordSize++] = ch; 3906 m_WordBuffer[m_WordSize++] = ch;
3822 if (ch == '/') { 3907 } else {
3823 while (1) { 3908 m_Pos--;
3824 if (!GetNextChar(ch)) { 3909 }
3825 return FALSE; 3910 } else if (ch == '>') {
3826 } 3911 if (!GetNextChar(ch)) {
3827 type = PDF_CharType[ch]; 3912 return FALSE;
3828 if (type != 'R' && type != 'N') { 3913 }
3829 m_Pos --; 3914 if (ch == '>') {
3830 CFX_ByteString ret(m_WordBuffer, m_WordSize); 3915 m_WordBuffer[m_WordSize++] = ch;
3831 token = ret; 3916 } else {
3832 return TRUE; 3917 m_Pos--;
3833 } 3918 }
3834 if (m_WordSize < MAX_WORD_BUFFER) {
3835 m_WordBuffer[m_WordSize++] = ch;
3836 }
3837 }
3838 } else if (ch == '<') {
3839 if (!GetNextChar(ch)) {
3840 return FALSE;
3841 }
3842 if (ch == '<') {
3843 m_WordBuffer[m_WordSize++] = ch;
3844 } else {
3845 m_Pos --;
3846 }
3847 } else if (ch == '>') {
3848 if (!GetNextChar(ch)) {
3849 return FALSE;
3850 }
3851 if (ch == '>') {
3852 m_WordBuffer[m_WordSize++] = ch;
3853 } else {
3854 m_Pos --;
3855 }
3856 }
3857 CFX_ByteString ret(m_WordBuffer, m_WordSize);
3858 token = ret;
3859 return TRUE;
3860 }
3861 while (1) {
3862 if (m_WordSize < MAX_WORD_BUFFER) {
3863 m_WordBuffer[m_WordSize++] = ch;
3864 }
3865 if (!GetNextChar(ch)) {
3866 return FALSE;
3867 }
3868 type = PDF_CharType[ch];
3869 if (type == 'D' || type == 'W') {
3870 m_Pos --;
3871 break;
3872 }
3873 } 3919 }
3874 CFX_ByteString ret(m_WordBuffer, m_WordSize); 3920 CFX_ByteString ret(m_WordBuffer, m_WordSize);
3875 token = ret; 3921 token = ret;
3876 return TRUE; 3922 return TRUE;
3877 } 3923 }
3878 FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t &ch) 3924 while (1) {
3879 { 3925 if (m_WordSize < MAX_WORD_BUFFER) {
3880 FX_FILESIZE pos = m_Pos; 3926 m_WordBuffer[m_WordSize++] = ch;
3881 if (pos >= m_dwFileLen) { 3927 }
3928 if (!GetNextChar(ch)) {
3929 return FALSE;
3930 }
3931 type = PDF_CharType[ch];
3932 if (type == 'D' || type == 'W') {
3933 m_Pos--;
3934 break;
3935 }
3936 }
3937 CFX_ByteString ret(m_WordBuffer, m_WordSize);
3938 token = ret;
3939 return TRUE;
3940 }
3941 FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) {
3942 FX_FILESIZE pos = m_Pos;
3943 if (pos >= m_dwFileLen) {
3944 return FALSE;
3945 }
3946 if (m_bufferOffset >= pos ||
3947 (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) {
3948 FX_FILESIZE read_pos = pos;
3949 FX_DWORD read_size = 512;
3950 if ((FX_FILESIZE)read_size > m_dwFileLen) {
3951 read_size = (FX_DWORD)m_dwFileLen;
3952 }
3953 if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) {
3954 read_pos = m_dwFileLen - read_size;
3955 }
3956 if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) {
3957 return FALSE;
3958 }
3959 m_bufferOffset = read_pos;
3960 m_bufferSize = read_size;
3961 }
3962 ch = m_bufferData[pos - m_bufferOffset];
3963 m_Pos++;
3964 return TRUE;
3965 }
3966 FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints* pHints) {
3967 int32_t iSize = 0;
3968 CFX_ByteString token;
3969 while (1) {
3970 if (!GetNextToken(token)) {
3971 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
3972 pHints->AddSegment(m_Pos, iSize);
3973 return FALSE;
3974 }
3975 if (token == "trailer") {
3976 m_dwTrailerOffset = m_Pos;
3977 m_docStatus = PDF_DATAAVAIL_TRAILER;
3978 return TRUE;
3979 }
3980 }
3981 }
3982 FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints* pHints) {
3983 FX_FILESIZE xref_offset = 0;
3984 int32_t nRet = CheckCrossRefStream(pHints, xref_offset);
3985 if (nRet == 1) {
3986 if (!xref_offset) {
3987 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF;
3988 } else {
3989 m_dwCurrentXRefSteam = xref_offset;
3990 m_Pos = xref_offset;
3991 }
3992 return TRUE;
3993 }
3994 if (nRet == -1) {
3995 m_docStatus = PDF_DATAAVAIL_ERROR;
3996 }
3997 return FALSE;
3998 }
3999 FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) {
4000 int32_t iSize = 0;
4001 CFX_ByteString token;
4002 if (!GetNextToken(token)) {
4003 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
4004 pHints->AddSegment(m_Pos, iSize);
4005 return FALSE;
4006 }
4007 if (token == "xref") {
4008 m_CrossOffset.InsertAt(0, m_dwXRefOffset);
4009 while (1) {
4010 if (!GetNextToken(token)) {
4011 iSize =
4012 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
4013 pHints->AddSegment(m_Pos, iSize);
4014 m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
3882 return FALSE; 4015 return FALSE;
3883 } 4016 }
3884 if (m_bufferOffset >= pos || (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) { 4017 if (token == "trailer") {
3885 FX_FILESIZE read_pos = pos; 4018 m_dwTrailerOffset = m_Pos;
3886 FX_DWORD read_size = 512; 4019 m_docStatus = PDF_DATAAVAIL_TRAILER;
3887 if ((FX_FILESIZE)read_size > m_dwFileLen) { 4020 return TRUE;
3888 read_size = (FX_DWORD)m_dwFileLen; 4021 }
3889 } 4022 }
3890 if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) { 4023 } else {
3891 read_pos = m_dwFileLen - read_size; 4024 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3892 }
3893 if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) {
3894 return FALSE;
3895 }
3896 m_bufferOffset = read_pos;
3897 m_bufferSize = read_size;
3898 }
3899 ch = m_bufferData[pos - m_bufferOffset];
3900 m_Pos ++;
3901 return TRUE; 4025 return TRUE;
3902 } 4026 }
3903 FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints *pHints) 4027 return FALSE;
3904 { 4028 }
3905 int32_t iSize = 0; 4029 FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) {
3906 CFX_ByteString token; 4030 if (m_Pos < m_dwFileLen) {
3907 while (1) { 4031 FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos();
3908 if (!GetNextToken(token)) { 4032 int32_t iSize = (int32_t)(
3909 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); 4033 dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512);
3910 pHints->AddSegment(m_Pos, iSize); 4034 if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) {
3911 return FALSE; 4035 pHints->AddSegment(dwAppendPos, iSize);
3912 } 4036 return FALSE;
3913 if (token == "trailer") { 4037 }
3914 m_dwTrailerOffset = m_Pos; 4038 }
3915 m_docStatus = PDF_DATAAVAIL_TRAILER; 4039 if (m_dwPrevXRefOffset) {
3916 return TRUE; 4040 SetStartOffset(m_dwPrevXRefOffset);
3917 } 4041 m_docStatus = PDF_DATAAVAIL_CROSSREF;
3918 } 4042 } else {
3919 } 4043 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF;
3920 FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints *pHints) 4044 }
3921 { 4045 return TRUE;
3922 FX_FILESIZE xref_offset = 0; 4046 }
3923 int32_t nRet = CheckCrossRefStream(pHints, xref_offset); 4047 FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) {
3924 if (nRet == 1) { 4048 int32_t iTrailerSize =
3925 if (!xref_offset) { 4049 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
3926 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; 4050 if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
3927 } else { 4051 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
3928 m_dwCurrentXRefSteam = xref_offset; 4052 CFX_BinaryBuf buf(iSize);
3929 m_Pos = xref_offset; 4053 uint8_t* pBuf = buf.GetBuffer();
3930 } 4054 if (!pBuf) {
3931 return TRUE; 4055 m_docStatus = PDF_DATAAVAIL_ERROR;
3932 } 4056 return FALSE;
3933 if (nRet == -1) { 4057 }
3934 m_docStatus = PDF_DATAAVAIL_ERROR; 4058 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) {
3935 } 4059 return FALSE;
3936 return FALSE; 4060 }
3937 } 4061 CFX_SmartPointer<IFX_FileStream> file(
3938 FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) 4062 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
3939 { 4063 m_syntaxParser.InitParser(file.Get(), 0);
3940 int32_t iSize = 0; 4064 CPDF_Object* pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0);
3941 CFX_ByteString token; 4065 if (!pTrailer) {
3942 if (!GetNextToken(token)) { 4066 m_Pos += m_syntaxParser.SavePos();
3943 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512) ; 4067 pHints->AddSegment(m_Pos, iTrailerSize);
3944 pHints->AddSegment(m_Pos, iSize); 4068 return FALSE;
3945 return FALSE; 4069 }
3946 } 4070 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) {
3947 if (token == "xref") { 4071 return FALSE;
3948 m_CrossOffset.InsertAt(0, m_dwXRefOffset); 4072 }
3949 while (1) { 4073 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict();
3950 if (!GetNextToken(token)) { 4074 if (pTrailerDict) {
3951 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Po s : 512); 4075 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt");
3952 pHints->AddSegment(m_Pos, iSize); 4076 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) {
3953 m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
3954 return FALSE;
3955 }
3956 if (token == "trailer") {
3957 m_dwTrailerOffset = m_Pos;
3958 m_docStatus = PDF_DATAAVAIL_TRAILER;
3959 return TRUE;
3960 }
3961 }
3962 } else {
3963 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; 4077 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3964 return TRUE;
3965 }
3966 return FALSE;
3967 }
3968 FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints)
3969 {
3970 if (m_Pos < m_dwFileLen) {
3971 FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos();
3972 int32_t iSize = (int32_t)(dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512);
3973 if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) {
3974 pHints->AddSegment(dwAppendPos, iSize);
3975 return FALSE;
3976 }
3977 }
3978 if (m_dwPrevXRefOffset) {
3979 SetStartOffset(m_dwPrevXRefOffset);
3980 m_docStatus = PDF_DATAAVAIL_CROSSREF;
3981 } else {
3982 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF;
3983 }
3984 return TRUE;
3985 }
3986 FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints)
3987 {
3988 int32_t iTrailerSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m _Pos : 512);
3989 if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
3990 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
3991 CFX_BinaryBuf buf(iSize);
3992 uint8_t* pBuf = buf.GetBuffer();
3993 if (!pBuf) {
3994 m_docStatus = PDF_DATAAVAIL_ERROR;
3995 return FALSE;
3996 }
3997 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) {
3998 return FALSE;
3999 }
4000 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_ t)iSize, FALSE));
4001 m_syntaxParser.InitParser(file.Get(), 0);
4002 CPDF_Object *pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0);
4003 if (!pTrailer) {
4004 m_Pos += m_syntaxParser.SavePos();
4005 pHints->AddSegment(m_Pos, iTrailerSize);
4006 return FALSE;
4007 }
4008 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) {
4009 return FALSE;
4010 }
4011 CPDF_Dictionary *pTrailerDict = pTrailer->GetDict();
4012 if (pTrailerDict) {
4013 CPDF_Object *pEncrypt = pTrailerDict->GetElement("Encrypt");
4014 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) {
4015 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
4016 pTrailer->Release();
4017 return TRUE;
4018 }
4019 }
4020 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev" ));
4021 if (xrefpos) {
4022 m_dwPrevXRefOffset = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC( "XRefStm"));
4023 pTrailer->Release();
4024 if (m_dwPrevXRefOffset) {
4025 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
4026 } else {
4027 m_dwPrevXRefOffset = xrefpos;
4028 if (m_dwPrevXRefOffset >= m_dwFileLen) {
4029 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
4030 } else {
4031 SetStartOffset(m_dwPrevXRefOffset);
4032 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
4033 }
4034 }
4035 return TRUE;
4036 }
4037 m_dwPrevXRefOffset = 0;
4038 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
4039 pTrailer->Release(); 4078 pTrailer->Release();
4040 return TRUE; 4079 return TRUE;
4041 } 4080 }
4042 pHints->AddSegment(m_Pos, iTrailerSize); 4081 }
4043 return FALSE; 4082 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev"));
4044 } 4083 if (xrefpos) {
4045 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) 4084 m_dwPrevXRefOffset =
4046 { 4085 GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm"));
4047 while (TRUE) { 4086 pTrailer->Release();
4048 switch (m_docStatus) { 4087 if (m_dwPrevXRefOffset) {
4049 case PDF_DATAAVAIL_PAGETREE: 4088 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
4050 if (!LoadDocPages(pHints)) { 4089 } else {
4051 return FALSE; 4090 m_dwPrevXRefOffset = xrefpos;
4052 } 4091 if (m_dwPrevXRefOffset >= m_dwFileLen) {
4053 break; 4092 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
4054 case PDF_DATAAVAIL_PAGE: 4093 } else {
4055 if (!LoadDocPage(iPage, pHints)) { 4094 SetStartOffset(m_dwPrevXRefOffset);
4056 return FALSE; 4095 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
4057 } 4096 }
4058 break; 4097 }
4059 case PDF_DATAAVAIL_ERROR: 4098 return TRUE;
4060 return LoadAllFile(pHints); 4099 }
4061 default: 4100 m_dwPrevXRefOffset = 0;
4062 m_bPagesTreeLoad = TRUE; 4101 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
4063 m_bPagesLoad = TRUE; 4102 pTrailer->Release();
4064 m_bCurPageDictLoadOK = TRUE; 4103 return TRUE;
4065 m_docStatus = PDF_DATAAVAIL_PAGE; 4104 }
4066 return TRUE; 4105 pHints->AddSegment(m_Pos, iTrailerSize);
4067 } 4106 return FALSE;
4068 } 4107 }
4069 } 4108 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) {
4070 FX_BOOL»CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPa geNode, IFX_DownloadHints* pHints) 4109 while (TRUE) {
4071 { 4110 switch (m_docStatus) {
4072 FX_BOOL bExist = FALSE; 4111 case PDF_DATAAVAIL_PAGETREE:
4073 CPDF_Object *pPages = GetObject(dwPageNo, pHints, &bExist); 4112 if (!LoadDocPages(pHints)) {
4074 if (!bExist) { 4113 return FALSE;
4075 m_docStatus = PDF_DATAAVAIL_ERROR; 4114 }
4076 return FALSE; 4115 break;
4077 } 4116 case PDF_DATAAVAIL_PAGE:
4078 if (!pPages) { 4117 if (!LoadDocPage(iPage, pHints)) {
4079 if (m_docStatus == PDF_DATAAVAIL_ERROR) { 4118 return FALSE;
4080 m_docStatus = PDF_DATAAVAIL_ERROR; 4119 }
4081 return FALSE; 4120 break;
4082 } 4121 case PDF_DATAAVAIL_ERROR:
4083 return FALSE; 4122 return LoadAllFile(pHints);
4084 } 4123 default:
4085 if (pPages->GetType() != PDFOBJ_ARRAY) { 4124 m_bPagesTreeLoad = TRUE;
4086 pPages->Release(); 4125 m_bPagesLoad = TRUE;
4087 m_docStatus = PDF_DATAAVAIL_ERROR; 4126 m_bCurPageDictLoadOK = TRUE;
4088 return FALSE; 4127 m_docStatus = PDF_DATAAVAIL_PAGE;
4089 } 4128 return TRUE;
4129 }
4130 }
4131 }
4132 FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo,
4133 CPDF_PageNode* pPageNode,
4134 IFX_DownloadHints* pHints) {
4135 FX_BOOL bExist = FALSE;
4136 CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist);
4137 if (!bExist) {
4138 m_docStatus = PDF_DATAAVAIL_ERROR;
4139 return FALSE;
4140 }
4141 if (!pPages) {
4142 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
4143 m_docStatus = PDF_DATAAVAIL_ERROR;
4144 return FALSE;
4145 }
4146 return FALSE;
4147 }
4148 if (pPages->GetType() != PDFOBJ_ARRAY) {
4149 pPages->Release();
4150 m_docStatus = PDF_DATAAVAIL_ERROR;
4151 return FALSE;
4152 }
4153 pPageNode->m_type = PDF_PAGENODE_PAGES;
4154 CPDF_Array* pArray = (CPDF_Array*)pPages;
4155 for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) {
4156 CPDF_Object* pKid = (CPDF_Object*)pArray->GetElement(i);
4157 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {
4158 continue;
4159 }
4160 CPDF_PageNode* pNode = new CPDF_PageNode();
4161 pPageNode->m_childNode.Add(pNode);
4162 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum();
4163 }
4164 pPages->Release();
4165 return TRUE;
4166 }
4167 FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo,
4168 CPDF_PageNode* pPageNode,
4169 IFX_DownloadHints* pHints) {
4170 FX_BOOL bExist = FALSE;
4171 CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist);
4172 if (!bExist) {
4173 m_docStatus = PDF_DATAAVAIL_ERROR;
4174 return FALSE;
4175 }
4176 if (!pPage) {
4177 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
4178 m_docStatus = PDF_DATAAVAIL_ERROR;
4179 return FALSE;
4180 }
4181 return FALSE;
4182 }
4183 if (pPage->GetType() == PDFOBJ_ARRAY) {
4184 pPageNode->m_dwPageNo = dwPageNo;
4185 pPageNode->m_type = PDF_PAGENODE_ARRAY;
4186 pPage->Release();
4187 return TRUE;
4188 }
4189 if (pPage->GetType() != PDFOBJ_DICTIONARY) {
4190 pPage->Release();
4191 m_docStatus = PDF_DATAAVAIL_ERROR;
4192 return FALSE;
4193 }
4194 pPageNode->m_dwPageNo = dwPageNo;
4195 CPDF_Dictionary* pDict = pPage->GetDict();
4196 CFX_ByteString type =
4197 pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteString();
4198 if (type == FX_BSTRC("Pages")) {
4090 pPageNode->m_type = PDF_PAGENODE_PAGES; 4199 pPageNode->m_type = PDF_PAGENODE_PAGES;
4091 CPDF_Array* pArray = (CPDF_Array*)pPages; 4200 CPDF_Object* pKids = pDict->GetElement(FX_BSTRC("Kids"));
4092 for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) { 4201 if (!pKids) {
4093 CPDF_Object *pKid = (CPDF_Object *)pArray->GetElement(i); 4202 m_docStatus = PDF_DATAAVAIL_PAGE;
4094 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { 4203 return TRUE;
4204 }
4205 switch (pKids->GetType()) {
4206 case PDFOBJ_REFERENCE: {
4207 CPDF_Reference* pKid = (CPDF_Reference*)pKids;
4208 CPDF_PageNode* pNode = new CPDF_PageNode();
4209 pPageNode->m_childNode.Add(pNode);
4210 pNode->m_dwPageNo = pKid->GetRefObjNum();
4211 } break;
4212 case PDFOBJ_ARRAY: {
4213 CPDF_Array* pKidsArray = (CPDF_Array*)pKids;
4214 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
4215 CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i);
4216 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {
4095 continue; 4217 continue;
4096 } 4218 }
4097 CPDF_PageNode *pNode = new CPDF_PageNode(); 4219 CPDF_PageNode* pNode = new CPDF_PageNode();
4098 pPageNode->m_childNode.Add(pNode); 4220 pPageNode->m_childNode.Add(pNode);
4099 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); 4221 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum();
4100 } 4222 }
4223 } break;
4224 default:
4225 break;
4226 }
4227 } else if (type == FX_BSTRC("Page")) {
4228 pPageNode->m_type = PDF_PAGENODE_PAGE;
4229 } else {
4230 pPage->Release();
4231 m_docStatus = PDF_DATAAVAIL_ERROR;
4232 return FALSE;
4233 }
4234 pPage->Release();
4235 return TRUE;
4236 }
4237 FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes,
4238 int32_t iPage,
4239 int32_t& iCount,
4240 IFX_DownloadHints* pHints) {
4241 int32_t iSize = pageNodes.m_childNode.GetSize();
4242 if (iSize <= 0 || iPage >= iSize) {
4243 m_docStatus = PDF_DATAAVAIL_ERROR;
4244 return FALSE;
4245 }
4246 for (int32_t i = 0; i < iSize; ++i) {
4247 CPDF_PageNode* pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i);
4248 if (!pNode) {
4249 continue;
4250 }
4251 switch (pNode->m_type) {
4252 case PDF_PAGENODE_UNKOWN:
4253 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) {
4254 return FALSE;
4255 }
4256 --i;
4257 break;
4258 case PDF_PAGENODE_PAGE:
4259 iCount++;
4260 if (iPage == iCount && m_pDocument) {
4261 m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo);
4262 }
4263 break;
4264 case PDF_PAGENODE_PAGES:
4265 if (!CheckPageNode(*pNode, iPage, iCount, pHints)) {
4266 return FALSE;
4267 }
4268 break;
4269 case PDF_PAGENODE_ARRAY:
4270 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) {
4271 return FALSE;
4272 }
4273 --i;
4274 break;
4275 }
4276 if (iPage == iCount) {
4277 m_docStatus = PDF_DATAAVAIL_DONE;
4278 return TRUE;
4279 }
4280 }
4281 return TRUE;
4282 }
4283 FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) {
4284 if (m_pDocument->GetPageCount() <= iPage ||
4285 m_pDocument->m_PageList.GetAt(iPage)) {
4286 m_docStatus = PDF_DATAAVAIL_DONE;
4287 return TRUE;
4288 }
4289 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) {
4290 if (iPage == 0) {
4291 m_docStatus = PDF_DATAAVAIL_DONE;
4292 return TRUE;
4293 }
4294 m_docStatus = PDF_DATAAVAIL_ERROR;
4295 return TRUE;
4296 }
4297 int32_t iCount = -1;
4298 return CheckPageNode(m_pageNodes, iPage, iCount, pHints);
4299 }
4300 FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) {
4301 FX_BOOL bExist = FALSE;
4302 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
4303 if (!bExist) {
4304 m_docStatus = PDF_DATAAVAIL_ERROR;
4305 return FALSE;
4306 }
4307 if (!pPages) {
4308 return FALSE;
4309 }
4310 CPDF_Dictionary* pPagesDict = pPages->GetDict();
4311 if (!pPagesDict) {
4312 pPages->Release();
4313 m_docStatus = PDF_DATAAVAIL_ERROR;
4314 return FALSE;
4315 }
4316 if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) {
4101 pPages->Release(); 4317 pPages->Release();
4102 return TRUE; 4318 return TRUE;
4103 } 4319 }
4104 FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pP ageNode, IFX_DownloadHints* pHints) 4320 int count = pPagesDict->GetInteger(FX_BSTRC("Count"));
4105 { 4321 if (count > 0) {
4106 FX_BOOL bExist = FALSE; 4322 pPages->Release();
4107 CPDF_Object *pPage = GetObject(dwPageNo, pHints, &bExist);
4108 if (!bExist) {
4109 m_docStatus = PDF_DATAAVAIL_ERROR;
4110 return FALSE;
4111 }
4112 if (!pPage) {
4113 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
4114 m_docStatus = PDF_DATAAVAIL_ERROR;
4115 return FALSE;
4116 }
4117 return FALSE;
4118 }
4119 if (pPage->GetType() == PDFOBJ_ARRAY) {
4120 pPageNode->m_dwPageNo = dwPageNo;
4121 pPageNode->m_type = PDF_PAGENODE_ARRAY;
4122 pPage->Release();
4123 return TRUE;
4124 }
4125 if (pPage->GetType() != PDFOBJ_DICTIONARY) {
4126 pPage->Release();
4127 m_docStatus = PDF_DATAAVAIL_ERROR;
4128 return FALSE;
4129 }
4130 pPageNode->m_dwPageNo = dwPageNo;
4131 CPDF_Dictionary* pDict = pPage->GetDict();
4132 CFX_ByteString type = pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteS tring();
4133 if (type == FX_BSTRC("Pages")) {
4134 pPageNode->m_type = PDF_PAGENODE_PAGES;
4135 CPDF_Object *pKids = pDict->GetElement(FX_BSTRC("Kids"));
4136 if (!pKids) {
4137 m_docStatus = PDF_DATAAVAIL_PAGE;
4138 return TRUE;
4139 }
4140 switch (pKids->GetType()) {
4141 case PDFOBJ_REFERENCE: {
4142 CPDF_Reference *pKid = (CPDF_Reference *)pKids;
4143 CPDF_PageNode *pNode = new CPDF_PageNode();
4144 pPageNode->m_childNode.Add(pNode);
4145 pNode->m_dwPageNo = pKid->GetRefObjNum();
4146 }
4147 break;
4148 case PDFOBJ_ARRAY: {
4149 CPDF_Array *pKidsArray = (CPDF_Array *)pKids;
4150 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
4151 CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElemen t(i);
4152 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {
4153 continue;
4154 }
4155 CPDF_PageNode *pNode = new CPDF_PageNode();
4156 pPageNode->m_childNode.Add(pNode);
4157 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNu m();
4158 }
4159 }
4160 break;
4161 default:
4162 break;
4163 }
4164 } else if (type == FX_BSTRC("Page")) {
4165 pPageNode->m_type = PDF_PAGENODE_PAGE;
4166 } else {
4167 pPage->Release();
4168 m_docStatus = PDF_DATAAVAIL_ERROR;
4169 return FALSE;
4170 }
4171 pPage->Release();
4172 return TRUE; 4323 return TRUE;
4173 } 4324 }
4174 FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode &pageNodes, int32_t iPage, i nt32_t &iCount, IFX_DownloadHints* pHints) 4325 pPages->Release();
4175 { 4326 return FALSE;
4176 int32_t iSize = pageNodes.m_childNode.GetSize(); 4327 }
4177 if (iSize <= 0 || iPage >= iSize) { 4328 FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) {
4178 m_docStatus = PDF_DATAAVAIL_ERROR; 4329 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) {
4179 return FALSE; 4330 return FALSE;
4180 } 4331 }
4181 for (int32_t i = 0; i < iSize; ++i) { 4332 if (CheckPageCount(pHints)) {
4182 CPDF_PageNode *pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i); 4333 m_docStatus = PDF_DATAAVAIL_PAGE;
4183 if (!pNode) {
4184 continue;
4185 }
4186 switch (pNode->m_type) {
4187 case PDF_PAGENODE_UNKOWN:
4188 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) {
4189 return FALSE;
4190 }
4191 --i;
4192 break;
4193 case PDF_PAGENODE_PAGE:
4194 iCount++;
4195 if (iPage == iCount && m_pDocument) {
4196 m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo);
4197 }
4198 break;
4199 case PDF_PAGENODE_PAGES:
4200 if (!CheckPageNode(*pNode, iPage, iCount, pHints)) {
4201 return FALSE;
4202 }
4203 break;
4204 case PDF_PAGENODE_ARRAY:
4205 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) {
4206 return FALSE;
4207 }
4208 --i;
4209 break;
4210 }
4211 if (iPage == iCount) {
4212 m_docStatus = PDF_DATAAVAIL_DONE;
4213 return TRUE;
4214 }
4215 }
4216 return TRUE; 4334 return TRUE;
4217 } 4335 }
4218 FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) 4336 m_bTotalLoadPageTree = TRUE;
4219 { 4337 return FALSE;
4220 if (m_pDocument->GetPageCount() <= iPage || m_pDocument->m_PageList.GetAt(iP age)) { 4338 }
4221 m_docStatus = PDF_DATAAVAIL_DONE; 4339 FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) {
4222 return TRUE; 4340 while (!m_bPagesTreeLoad) {
4223 } 4341 if (!CheckPageStatus(pHints)) {
4224 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { 4342 return FALSE;
4225 if (iPage == 0) { 4343 }
4226 m_docStatus = PDF_DATAAVAIL_DONE; 4344 }
4227 return TRUE; 4345 if (m_bPagesLoad) {
4228 } 4346 return TRUE;
4229 m_docStatus = PDF_DATAAVAIL_ERROR; 4347 }
4230 return TRUE; 4348 m_pDocument->LoadPages();
4231 } 4349 return FALSE;
4232 int32_t iCount = -1; 4350 }
4233 return CheckPageNode(m_pageNodes, iPage, iCount, pHints); 4351 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) {
4234 } 4352 if (m_bLinearedDataOK) {
4235 FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) 4353 return TRUE;
4236 { 4354 }
4237 FX_BOOL bExist = FALSE; 4355
4238 CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); 4356 if (!m_bMainXRefLoadTried) {
4239 if (!bExist) { 4357 FX_SAFE_DWORD data_size = m_dwFileLen;
4240 m_docStatus = PDF_DATAAVAIL_ERROR; 4358 data_size -= m_dwLastXRefOffset;
4241 return FALSE; 4359 if (!data_size.IsValid()) {
4242 } 4360 return FALSE;
4243 if (!pPages) { 4361 }
4244 return FALSE; 4362 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
4245 } 4363 data_size.ValueOrDie())) {
4246 CPDF_Dictionary* pPagesDict = pPages->GetDict(); 4364 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie());
4247 if (!pPagesDict) { 4365 return FALSE;
4248 pPages->Release(); 4366 }
4249 m_docStatus = PDF_DATAAVAIL_ERROR; 4367 FX_DWORD dwRet =
4250 return FALSE; 4368 ((CPDF_Parser*)m_pDocument->GetParser())->LoadLinearizedMainXRefTable();
4251 } 4369 m_bMainXRefLoadTried = TRUE;
4252 if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) { 4370 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
4253 pPages->Release(); 4371 return FALSE;
4254 return TRUE; 4372 }
4255 } 4373 if (!PreparePageItem()) {
4256 int count = pPagesDict->GetInteger(FX_BSTRC("Count")); 4374 return FALSE;
4257 if (count > 0) { 4375 }
4258 pPages->Release(); 4376 m_bMainXRefLoadedOK = TRUE;
4259 return TRUE; 4377 m_bLinearedDataOK = TRUE;
4260 } 4378 }
4261 pPages->Release(); 4379
4262 return FALSE; 4380 return m_bLinearedDataOK;
4263 } 4381 }
4264 FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) 4382 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage,
4265 { 4383 IFX_DownloadHints* pHints) {
4266 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) { 4384 if (!m_objs_array.GetSize()) {
4267 return FALSE;
4268 }
4269 if (CheckPageCount(pHints)) {
4270 m_docStatus = PDF_DATAAVAIL_PAGE;
4271 return TRUE;
4272 }
4273 m_bTotalLoadPageTree = TRUE;
4274 return FALSE;
4275 }
4276 FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints)
4277 {
4278 while (!m_bPagesTreeLoad) {
4279 if (!CheckPageStatus(pHints)) {
4280 return FALSE;
4281 }
4282 }
4283 if (m_bPagesLoad) {
4284 return TRUE;
4285 }
4286 m_pDocument->LoadPages();
4287 return FALSE;
4288 }
4289 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints)
4290 {
4291 if (m_bLinearedDataOK) {
4292 return TRUE;
4293 }
4294
4295 if (!m_bMainXRefLoadTried) {
4296 FX_SAFE_DWORD data_size = m_dwFileLen;
4297 data_size -= m_dwLastXRefOffset;
4298 if (!data_size.IsValid()) {
4299 return FALSE;
4300 }
4301 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, data_size.ValueOrDie( ))) {
4302 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie());
4303 return FALSE;
4304 }
4305 FX_DWORD dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLineariz edMainXRefTable();
4306 m_bMainXRefLoadTried = TRUE;
4307 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
4308 return FALSE;
4309 }
4310 if (!PreparePageItem()) {
4311 return FALSE;
4312 }
4313 m_bMainXRefLoadedOK = TRUE;
4314 m_bLinearedDataOK = TRUE;
4315 }
4316
4317 return m_bLinearedDataOK;
4318 }
4319 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, IFX_DownloadHints* pHints )
4320 {
4321 if (!m_objs_array.GetSize()) {
4322 m_objs_array.RemoveAll();
4323 m_objnum_array.RemoveAll();
4324 CPDF_Dictionary *pPageDict = m_pDocument->GetPage(iPage);
4325 if (!pPageDict) {
4326 return TRUE;
4327 }
4328 CPDF_Object *pAnnots = pPageDict->GetElement(FX_BSTRC("Annots"));
4329 if (!pAnnots) {
4330 return TRUE;
4331 }
4332 CFX_PtrArray obj_array;
4333 obj_array.Add(pAnnots);
4334 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
4335 if (bRet) {
4336 m_objs_array.RemoveAll();
4337 }
4338 return bRet;
4339 }
4340 CFX_PtrArray new_objs_array;
4341 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4342 m_objs_array.RemoveAll(); 4385 m_objs_array.RemoveAll();
4343 if (!bRet) { 4386 m_objnum_array.RemoveAll();
4344 m_objs_array.Append(new_objs_array); 4387 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage);
4388 if (!pPageDict) {
4389 return TRUE;
4390 }
4391 CPDF_Object* pAnnots = pPageDict->GetElement(FX_BSTRC("Annots"));
4392 if (!pAnnots) {
4393 return TRUE;
4394 }
4395 CFX_PtrArray obj_array;
4396 obj_array.Add(pAnnots);
4397 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
4398 if (bRet) {
4399 m_objs_array.RemoveAll();
4345 } 4400 }
4346 return bRet; 4401 return bRet;
4347 } 4402 }
4348 FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage, IFX_DownloadHint s* pHints) 4403 CFX_PtrArray new_objs_array;
4349 { 4404 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4350 if (!m_bAnnotsLoad) { 4405 m_objs_array.RemoveAll();
4351 if (!CheckPageAnnots(iPage, pHints)) { 4406 if (!bRet) {
4352 return FALSE; 4407 m_objs_array.Append(new_objs_array);
4353 } 4408 }
4354 m_bAnnotsLoad = TRUE; 4409 return bRet;
4355 } 4410 }
4356 if (m_bAnnotsLoad) { 4411 FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage,
4357 if (!CheckLinearizedData(pHints)) 4412 IFX_DownloadHints* pHints) {
4358 return FALSE; 4413 if (!m_bAnnotsLoad) {
4359 } 4414 if (!CheckPageAnnots(iPage, pHints)) {
4360 m_bPageLoadedOK = FALSE; 4415 return FALSE;
4416 }
4417 m_bAnnotsLoad = TRUE;
4418 }
4419 if (m_bAnnotsLoad) {
4420 if (!CheckLinearizedData(pHints))
4421 return FALSE;
4422 }
4423 m_bPageLoadedOK = FALSE;
4424 return TRUE;
4425 }
4426 FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) {
4427 CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth);
4428 if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) {
4429 return FALSE;
4430 }
4431 CPDF_Object* pParent = pDict->GetElement("Parent");
4432 if (!pParent) {
4433 return FALSE;
4434 }
4435 CPDF_Dictionary* pParentDict = pParent->GetDict();
4436 if (!pParentDict) {
4437 return FALSE;
4438 }
4439 CPDF_Object* pRet = pParentDict->GetElement("Resources");
4440 if (pRet) {
4441 m_pPageResource = pRet;
4361 return TRUE; 4442 return TRUE;
4362 } 4443 }
4363 FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary *pDict) 4444 return HaveResourceAncestor(pParentDict);
4364 { 4445 }
4365 CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth); 4446 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) {
4366 if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) { 4447 if (!m_pDocument) {
4367 return FALSE; 4448 return FALSE;
4368 } 4449 }
4369 CPDF_Object *pParent = pDict->GetElement("Parent"); 4450 if (IsFirstCheck(iPage)) {
4370 if (!pParent) { 4451 m_bCurPageDictLoadOK = FALSE;
4371 return FALSE;
4372 }
4373 CPDF_Dictionary *pParentDict = pParent->GetDict();
4374 if (!pParentDict) {
4375 return FALSE;
4376 }
4377 CPDF_Object *pRet = pParentDict->GetElement("Resources");
4378 if (pRet) {
4379 m_pPageResource = pRet;
4380 return TRUE;
4381 }
4382 return HaveResourceAncestor(pParentDict);
4383 }
4384 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints)
4385 {
4386 if (!m_pDocument) {
4387 return FALSE;
4388 }
4389 if (IsFirstCheck(iPage)) {
4390 m_bCurPageDictLoadOK = FALSE;
4391 m_bPageLoadedOK = FALSE;
4392 m_bAnnotsLoad = FALSE;
4393 m_bNeedDownLoadResource = FALSE;
4394 m_objs_array.RemoveAll();
4395 m_objnum_array.RemoveAll();
4396 }
4397 if (m_pagesLoadState == NULL) {
4398 m_pagesLoadState = new CFX_CMapDWordToDWord();
4399 }
4400 FX_DWORD dwPageLoad = 0;
4401 if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) {
4402 return TRUE;
4403 }
4404 if (m_bLinearized) {
4405 if ((FX_DWORD)iPage == m_dwFirstPageNo) {
4406 m_pagesLoadState->SetAt(iPage, TRUE);
4407 return TRUE;
4408 }
4409 if (!CheckLinearizedData(pHints)) {
4410 return FALSE;
4411 }
4412 if (m_bMainXRefLoadedOK) {
4413 if (m_bTotalLoadPageTree) {
4414 if (!LoadPages(pHints)) {
4415 return FALSE;
4416 }
4417 } else {
4418 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4419 return FALSE;
4420 }
4421 }
4422 } else {
4423 if (!LoadAllFile(pHints)) {
4424 return FALSE;
4425 }
4426 ((CPDF_Parser *)m_pDocument->GetParser())->RebuildCrossRef();
4427 ResetFirstCheck(iPage);
4428 return TRUE;
4429 }
4430 } else {
4431 if (!m_bTotalLoadPageTree) {
4432 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4433 return FALSE;
4434 }
4435 }
4436 }
4437 if (m_bHaveAcroForm && !m_bAcroFormLoad) {
4438 if (!CheckAcroFormSubObject(pHints)) {
4439 return FALSE;
4440 }
4441 m_bAcroFormLoad = TRUE;
4442 }
4443 if (!m_bPageLoadedOK) {
4444 if (!m_objs_array.GetSize()) {
4445 m_objs_array.RemoveAll();
4446 m_objnum_array.RemoveAll();
4447 m_pPageDict = m_pDocument->GetPage(iPage);
4448 if (!m_pPageDict) {
4449 ResetFirstCheck(iPage);
4450 return TRUE;
4451 }
4452 CFX_PtrArray obj_array;
4453 obj_array.Add(m_pPageDict);
4454 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array) ;
4455 if (bRet) {
4456 m_objs_array.RemoveAll();
4457 m_bPageLoadedOK = TRUE;
4458 } else {
4459 return bRet;
4460 }
4461 } else {
4462 CFX_PtrArray new_objs_array;
4463 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_ array);
4464 m_objs_array.RemoveAll();
4465 if (bRet) {
4466 m_bPageLoadedOK = TRUE;
4467 } else {
4468 m_objs_array.Append(new_objs_array);
4469 return bRet;
4470 }
4471 }
4472 }
4473 if (m_bPageLoadedOK) {
4474 if (!m_bAnnotsLoad) {
4475 if (!CheckPageAnnots(iPage, pHints)) {
4476 return FALSE;
4477 }
4478 m_bAnnotsLoad = TRUE;
4479 }
4480 }
4481 if (m_pPageDict && !m_bNeedDownLoadResource) {
4482 m_pPageResource = m_pPageDict->GetElement("Resources");
4483 if (!m_pPageResource) {
4484 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);
4485 } else {
4486 m_bNeedDownLoadResource = TRUE;
4487 }
4488 }
4489 if (m_bNeedDownLoadResource) {
4490 FX_BOOL bRet = CheckResources(pHints);
4491 if (!bRet) {
4492 return FALSE;
4493 }
4494 m_bNeedDownLoadResource = FALSE;
4495 }
4496 m_bPageLoadedOK = FALSE; 4452 m_bPageLoadedOK = FALSE;
4497 m_bAnnotsLoad = FALSE; 4453 m_bAnnotsLoad = FALSE;
4498 m_bCurPageDictLoadOK = FALSE; 4454 m_bNeedDownLoadResource = FALSE;
4499 ResetFirstCheck(iPage); 4455 m_objs_array.RemoveAll();
4500 m_pagesLoadState->SetAt(iPage, TRUE); 4456 m_objnum_array.RemoveAll();
4457 }
4458 if (m_pagesLoadState == NULL) {
4459 m_pagesLoadState = new CFX_CMapDWordToDWord();
4460 }
4461 FX_DWORD dwPageLoad = 0;
4462 if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) {
4501 return TRUE; 4463 return TRUE;
4502 } 4464 }
4503 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) 4465 if (m_bLinearized) {
4504 { 4466 if ((FX_DWORD)iPage == m_dwFirstPageNo) {
4467 m_pagesLoadState->SetAt(iPage, TRUE);
4468 return TRUE;
4469 }
4470 if (!CheckLinearizedData(pHints)) {
4471 return FALSE;
4472 }
4473 if (m_bMainXRefLoadedOK) {
4474 if (m_bTotalLoadPageTree) {
4475 if (!LoadPages(pHints)) {
4476 return FALSE;
4477 }
4478 } else {
4479 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4480 return FALSE;
4481 }
4482 }
4483 } else {
4484 if (!LoadAllFile(pHints)) {
4485 return FALSE;
4486 }
4487 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef();
4488 ResetFirstCheck(iPage);
4489 return TRUE;
4490 }
4491 } else {
4492 if (!m_bTotalLoadPageTree) {
4493 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4494 return FALSE;
4495 }
4496 }
4497 }
4498 if (m_bHaveAcroForm && !m_bAcroFormLoad) {
4499 if (!CheckAcroFormSubObject(pHints)) {
4500 return FALSE;
4501 }
4502 m_bAcroFormLoad = TRUE;
4503 }
4504 if (!m_bPageLoadedOK) {
4505 if (!m_objs_array.GetSize()) { 4505 if (!m_objs_array.GetSize()) {
4506 m_objs_array.RemoveAll();
4507 m_objnum_array.RemoveAll();
4508 m_pPageDict = m_pDocument->GetPage(iPage);
4509 if (!m_pPageDict) {
4510 ResetFirstCheck(iPage);
4511 return TRUE;
4512 }
4513 CFX_PtrArray obj_array;
4514 obj_array.Add(m_pPageDict);
4515 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
4516 if (bRet) {
4506 m_objs_array.RemoveAll(); 4517 m_objs_array.RemoveAll();
4507 CFX_PtrArray obj_array; 4518 m_bPageLoadedOK = TRUE;
4508 obj_array.Add(m_pPageResource); 4519 } else {
4509 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
4510 if (bRet) {
4511 m_objs_array.RemoveAll();
4512 }
4513 return bRet; 4520 return bRet;
4514 } 4521 }
4515 CFX_PtrArray new_objs_array; 4522 } else {
4516 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); 4523 CFX_PtrArray new_objs_array;
4524 FX_BOOL bRet =
4525 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4526 m_objs_array.RemoveAll();
4527 if (bRet) {
4528 m_bPageLoadedOK = TRUE;
4529 } else {
4530 m_objs_array.Append(new_objs_array);
4531 return bRet;
4532 }
4533 }
4534 }
4535 if (m_bPageLoadedOK) {
4536 if (!m_bAnnotsLoad) {
4537 if (!CheckPageAnnots(iPage, pHints)) {
4538 return FALSE;
4539 }
4540 m_bAnnotsLoad = TRUE;
4541 }
4542 }
4543 if (m_pPageDict && !m_bNeedDownLoadResource) {
4544 m_pPageResource = m_pPageDict->GetElement("Resources");
4545 if (!m_pPageResource) {
4546 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);
4547 } else {
4548 m_bNeedDownLoadResource = TRUE;
4549 }
4550 }
4551 if (m_bNeedDownLoadResource) {
4552 FX_BOOL bRet = CheckResources(pHints);
4553 if (!bRet) {
4554 return FALSE;
4555 }
4556 m_bNeedDownLoadResource = FALSE;
4557 }
4558 m_bPageLoadedOK = FALSE;
4559 m_bAnnotsLoad = FALSE;
4560 m_bCurPageDictLoadOK = FALSE;
4561 ResetFirstCheck(iPage);
4562 m_pagesLoadState->SetAt(iPage, TRUE);
4563 return TRUE;
4564 }
4565 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) {
4566 if (!m_objs_array.GetSize()) {
4517 m_objs_array.RemoveAll(); 4567 m_objs_array.RemoveAll();
4518 if (!bRet) { 4568 CFX_PtrArray obj_array;
4519 m_objs_array.Append(new_objs_array); 4569 obj_array.Add(m_pPageResource);
4570 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
4571 if (bRet) {
4572 m_objs_array.RemoveAll();
4520 } 4573 }
4521 return bRet; 4574 return bRet;
4522 } 4575 }
4523 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSiz e) 4576 CFX_PtrArray new_objs_array;
4524 { 4577 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4525 if (pPos) { 4578 m_objs_array.RemoveAll();
4526 *pPos = m_dwLastXRefOffset; 4579 if (!bRet) {
4527 } 4580 m_objs_array.Append(new_objs_array);
4528 if (pSize) { 4581 }
4529 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); 4582 return bRet;
4530 } 4583 }
4531 } 4584 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
4532 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints *pHints) 4585 FX_DWORD* pSize) {
4533 { 4586 if (pPos) {
4534 if (!m_pDocument) { 4587 *pPos = m_dwLastXRefOffset;
4535 return PDFFORM_AVAIL; 4588 }
4536 } 4589 if (pSize) {
4537 if (!m_bLinearizedFormParamLoad) { 4590 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset);
4538 CPDF_Dictionary *pRoot = m_pDocument->GetRoot(); 4591 }
4539 if (!pRoot) { 4592 }
4540 return PDFFORM_AVAIL; 4593 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) {
4541 } 4594 if (!m_pDocument) {
4542 CPDF_Object *pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm"));
4543 if (!pAcroForm) {
4544 return PDFFORM_NOTEXIST;
4545 }
4546 if (!CheckLinearizedData(pHints)) {
4547 return PDFFORM_NOTAVAIL;
4548 }
4549 if (!m_objs_array.GetSize()) {
4550 m_objs_array.Add(pAcroForm->GetDict());
4551 }
4552 m_bLinearizedFormParamLoad = TRUE;
4553 }
4554 CFX_PtrArray new_objs_array;
4555 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4556 m_objs_array.RemoveAll();
4557 if (!bRet) {
4558 m_objs_array.Append(new_objs_array);
4559 return PDFFORM_NOTAVAIL;
4560 }
4561 return PDFFORM_AVAIL; 4595 return PDFFORM_AVAIL;
4562 } 4596 }
4563 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) 4597 if (!m_bLinearizedFormParamLoad) {
4564 { 4598 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
4565 int32_t iNext = 0; 4599 if (!pRoot) {
4566 if (BinarySearch(dwObjNum, iNext)) { 4600 return PDFFORM_AVAIL;
4567 return; 4601 }
4568 } 4602 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm"));
4569 m_number_array.InsertAt(iNext, dwObjNum); 4603 if (!pAcroForm) {
4570 } 4604 return PDFFORM_NOTEXIST;
4571 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) 4605 }
4572 { 4606 if (!CheckLinearizedData(pHints)) {
4573 int32_t iNext = 0; 4607 return PDFFORM_NOTAVAIL;
4574 return BinarySearch(dwObjNum, iNext); 4608 }
4575 } 4609 if (!m_objs_array.GetSize()) {
4576 FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t &iNext) 4610 m_objs_array.Add(pAcroForm->GetDict());
4577 { 4611 }
4578 int32_t iLow = 0; 4612 m_bLinearizedFormParamLoad = TRUE;
4579 int32_t iHigh = m_number_array.GetSize() - 1; 4613 }
4580 while (iLow <= iHigh) { 4614 CFX_PtrArray new_objs_array;
4581 int32_t iMid = (iLow + iHigh) / 2; 4615 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4582 if (m_number_array.GetAt(iMid) == value) { 4616 m_objs_array.RemoveAll();
4583 iNext = iMid; 4617 if (!bRet) {
4584 return TRUE; 4618 m_objs_array.Append(new_objs_array);
4585 } 4619 return PDFFORM_NOTAVAIL;
4586 if (m_number_array.GetAt(iMid) > value) { 4620 }
4587 iHigh = iMid - 1; 4621 return PDFFORM_AVAIL;
4588 } else if (m_number_array.GetAt(iMid) < value) { 4622 }
4589 iLow = iMid + 1; 4623 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) {
4590 } 4624 int32_t iNext = 0;
4591 } 4625 if (BinarySearch(dwObjNum, iNext)) {
4592 iNext = iLow; 4626 return;
4593 return FALSE; 4627 }
4594 } 4628 m_number_array.InsertAt(iNext, dwObjNum);
4595 CPDF_PageNode::~CPDF_PageNode() 4629 }
4596 { 4630 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) {
4597 int32_t iSize = m_childNode.GetSize(); 4631 int32_t iNext = 0;
4598 for (int32_t i = 0; i < iSize; ++i) { 4632 return BinarySearch(dwObjNum, iNext);
4599 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; 4633 }
4600 delete pNode; 4634 FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t& iNext) {
4601 } 4635 int32_t iLow = 0;
4602 m_childNode.RemoveAll(); 4636 int32_t iHigh = m_number_array.GetSize() - 1;
4603 } 4637 while (iLow <= iHigh) {
4638 int32_t iMid = (iLow + iHigh) / 2;
4639 if (m_number_array.GetAt(iMid) == value) {
4640 iNext = iMid;
4641 return TRUE;
4642 }
4643 if (m_number_array.GetAt(iMid) > value) {
4644 iHigh = iMid - 1;
4645 } else if (m_number_array.GetAt(iMid) < value) {
4646 iLow = iMid + 1;
4647 }
4648 }
4649 iNext = iLow;
4650 return FALSE;
4651 }
4652 CPDF_PageNode::~CPDF_PageNode() {
4653 int32_t iSize = m_childNode.GetSize();
4654 for (int32_t i = 0; i < iSize; ++i) {
4655 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i];
4656 delete pNode;
4657 }
4658 m_childNode.RemoveAll();
4659 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698