1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fpdfapi/fpdf_parser.h"
8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../../../include/fpdfapi/fpdf_page.h"
10 #include "../../../../third_party/numerics/safe_math.h"
11 #include "../fpdf_page/pageint.h"
15 #define _PARSER_OBJECT_LEVLE_ 64
16 extern const FX_LPCSTR _PDF_CharType;
17 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict)
19 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));
21 pType = pDict->GetElementValue(FX_BSTRC("FT"));
26 if (pType->GetString() == FX_BSTRC("Sig")) {
31 static int _CompareFileSize(const void* p1, const void* p2)
33 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2);
42 CPDF_Parser::CPDF_Parser()
46 m_pEncryptDict = NULL;
47 m_pSecurityHandler = NULL;
50 m_dwXrefStartObjNum = 0;
51 m_bOwnFileRead = TRUE;
53 m_bForceUseSecurityHandler = FALSE;
55 CPDF_Parser::~CPDF_Parser()
59 FX_DWORD CPDF_Parser::GetLastObjNum()
61 FX_DWORD dwSize = m_CrossRef.GetSize();
62 return dwSize ? dwSize - 1 : 0;
64 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict)
66 m_pEncryptDict = pDict;
68 void CPDF_Parser::CloseParser(FX_BOOL bReParse)
70 m_bVersionUpdated = FALSE;
71 if (m_pDocument && !bReParse) {
76 m_pTrailer->Release();
79 ReleaseEncryptHandler();
80 SetEncryptDictionary(NULL);
81 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) {
82 m_Syntax.m_pFileAccess->Release();
83 m_Syntax.m_pFileAccess = NULL;
85 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
88 CPDF_StreamAcc* pStream;
89 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
92 m_ObjectStreamMap.RemoveAll();
93 m_SortedOffset.RemoveAll();
94 m_CrossRef.RemoveAll();
96 m_ObjVersion.RemoveAll();
97 FX_INT32 iLen = m_Trailers.GetSize();
98 for (FX_INT32 i = 0; i < iLen; ++i) {
99 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i))
102 m_Trailers.RemoveAll();
104 m_pLinearized->Release();
105 m_pLinearized = NULL;
108 static FX_INT32 GetHeaderOffset(IFX_FileRead* pFile)
110 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
114 if (!pFile->ReadBlock(buf, offset, 4)) {
117 if (*(FX_DWORD*)buf == tag) {
127 FX_DWORD CPDF_Parser::StartParse(FX_LPCSTR filename, FX_BOOL bReParse)
129 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
131 return PDFPARSE_ERROR_FILE;
133 return StartParse(pFileAccess, bReParse);
135 FX_DWORD CPDF_Parser::StartParse(FX_LPCWSTR filename, FX_BOOL bReParse)
137 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
139 return PDFPARSE_ERROR_FILE;
141 return StartParse(pFileAccess, bReParse);
143 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler();
144 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*);
145 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)
147 CloseParser(bReParse);
148 m_bXRefStream = FALSE;
149 m_LastXRefOffset = 0;
150 m_bOwnFileRead = bOwnFileRead;
151 FX_INT32 offset = GetHeaderOffset(pFileAccess);
153 if (bOwnFileRead && pFileAccess) {
154 pFileAccess->Release();
156 return PDFPARSE_ERROR_FORMAT;
158 m_Syntax.InitParser(pFileAccess, offset);
160 if (!m_Syntax.GetCharAt(5, ch)) {
161 return PDFPARSE_ERROR_FORMAT;
163 if (ch >= '0' && ch <= '9') {
164 m_FileVersion = (ch - '0') * 10;
166 if (!m_Syntax.GetCharAt(7, ch)) {
167 return PDFPARSE_ERROR_FORMAT;
169 if (ch >= '0' && ch <= '9') {
170 m_FileVersion += ch - '0';
172 if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) {
173 return PDFPARSE_ERROR_FORMAT;
175 m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9);
177 m_pDocument = FX_NEW CPDF_Document(this);
179 FX_BOOL bXRefRebuilt = FALSE;
180 if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) {
181 FX_FILESIZE startxref_offset = m_Syntax.SavePos();
182 FX_LPVOID pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
183 if (pResult == NULL) {
184 m_SortedOffset.Add(startxref_offset);
186 m_Syntax.GetKeyword();
188 CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber);
190 return PDFPARSE_ERROR_FORMAT;
192 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
193 if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRefOffset)) {
194 if (!RebuildCrossRef()) {
195 return PDFPARSE_ERROR_FORMAT;
198 m_LastXRefOffset = 0;
201 if (!RebuildCrossRef()) {
202 return PDFPARSE_ERROR_FORMAT;
206 FX_DWORD dwRet = SetEncryptHandler();
207 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
210 m_pDocument->LoadDoc();
211 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
213 return PDFPARSE_ERROR_FORMAT;
215 ReleaseEncryptHandler();
216 if (!RebuildCrossRef()) {
217 return PDFPARSE_ERROR_FORMAT;
219 dwRet = SetEncryptHandler();
220 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
223 m_pDocument->LoadDoc();
224 if (m_pDocument->GetRoot() == NULL) {
225 return PDFPARSE_ERROR_FORMAT;
228 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
229 FX_DWORD RootObjNum = GetRootObjNum();
230 if (RootObjNum == 0) {
231 ReleaseEncryptHandler();
233 RootObjNum = GetRootObjNum();
234 if (RootObjNum == 0) {
235 return PDFPARSE_ERROR_FORMAT;
237 dwRet = SetEncryptHandler();
238 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
242 if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {
243 CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));
244 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
245 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();
248 return PDFPARSE_ERROR_SUCCESS;
250 FX_DWORD CPDF_Parser::SetEncryptHandler()
252 ReleaseEncryptHandler();
253 SetEncryptDictionary(NULL);
254 if (m_pTrailer == NULL) {
255 return PDFPARSE_ERROR_FORMAT;
257 CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt"));
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*)pEncryptObj)->GetRefObjNum());
264 SetEncryptDictionary(pEncryptObj->GetDict());
268 if (m_bForceUseSecurityHandler) {
269 FX_DWORD err = PDFPARSE_ERROR_HANDLER;
270 if (m_pSecurityHandler == NULL) {
271 return PDFPARSE_ERROR_HANDLER;
273 if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) {
276 CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHandler();
277 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
278 delete pCryptoHandler;
279 pCryptoHandler = NULL;
280 return PDFPARSE_ERROR_HANDLER;
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;
291 if (pSecurityHandler == NULL) {
292 return PDFPARSE_ERROR_HANDLER;
294 if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) {
295 delete pSecurityHandler;
296 pSecurityHandler = NULL;
299 m_pSecurityHandler = pSecurityHandler;
300 CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandler();
301 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
302 delete pCryptoHandler;
303 pCryptoHandler = NULL;
304 return PDFPARSE_ERROR_HANDLER;
306 m_Syntax.SetEncrypt(pCryptoHandler);
308 return PDFPARSE_ERROR_SUCCESS;
310 void CPDF_Parser::ReleaseEncryptHandler()
312 if (m_Syntax.m_pCryptoHandler) {
313 delete m_Syntax.m_pCryptoHandler;
314 m_Syntax.m_pCryptoHandler = NULL;
316 if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {
317 delete m_pSecurityHandler;
318 m_pSecurityHandler = NULL;
321 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum)
323 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
326 if (m_V5Type[objnum] == 1) {
327 return m_CrossRef[objnum];
329 if (m_V5Type[objnum] == 2) {
330 return m_CrossRef[(FX_INT32)m_CrossRef[objnum]];
334 static FX_INT32 GetDirectInteger(CPDF_Dictionary* pDict, FX_BSTR key)
336 CPDF_Object* pObj = pDict->GetElement(key);
340 if (pObj->GetType() == PDFOBJ_NUMBER) {
341 return ((CPDF_Number*)pObj)->GetInteger();
345 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, FX_BSTR key, FX_INT32 iType)
347 CPDF_Object* pObj = pDict->GetElement(key);
351 return pObj->GetType() == iType;
353 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos)
355 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {
358 m_pTrailer = LoadTrailerV4();
359 if (m_pTrailer == NULL) {
362 FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
363 if (xrefsize <= 0 || xrefsize > (1 << 20)) {
366 m_CrossRef.SetSize(xrefsize);
367 m_V5Type.SetSize(xrefsize);
368 CFX_FileSizeArray CrossRefList, XRefStreamList;
369 CrossRefList.Add(xrefpos);
370 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
371 if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
374 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
375 if (newxrefpos == xrefpos) {
378 xrefpos = newxrefpos;
380 CrossRefList.InsertAt(0, xrefpos);
381 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
382 CPDF_Dictionary* pDict = LoadTrailerV4();
386 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
390 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
391 if (newxrefpos == xrefpos) {
395 xrefpos = newxrefpos;
396 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
397 m_Trailers.Add(pDict);
399 for (FX_INT32 i = 0; i < CrossRefList.GetSize(); i ++)
400 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
405 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD dwObjCount)
407 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) {
410 m_pTrailer = LoadTrailerV4();
411 if (m_pTrailer == NULL) {
414 FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
418 CFX_FileSizeArray CrossRefList, XRefStreamList;
419 CrossRefList.Add(xrefpos);
420 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
421 xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
423 CrossRefList.InsertAt(0, xrefpos);
424 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
425 CPDF_Dictionary* pDict = LoadTrailerV4();
429 xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
430 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
431 m_Trailers.Add(pDict);
433 for (FX_INT32 i = 1; i < CrossRefList.GetSize(); i ++)
434 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
439 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount)
441 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset;
442 m_Syntax.RestorePos(dwStartPos);
443 FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
444 if (pResult == NULL) {
445 m_SortedOffset.Add(pos);
447 FX_DWORD start_objnum = 0;
448 FX_DWORD count = dwObjCount;
449 FX_FILESIZE SavedPos = m_Syntax.SavePos();
450 FX_INT32 recordsize = 20;
451 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
452 pBuf[1024 * recordsize] = '\0';
453 FX_INT32 nBlocks = count / 1024 + 1;
454 for (FX_INT32 block = 0; block < nBlocks; block ++) {
455 FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;
456 FX_DWORD dwReadSize = block_size * recordsize;
457 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) {
461 if (!m_Syntax.ReadBlock((FX_LPBYTE)pBuf, dwReadSize)) {
465 for (FX_INT32 i = 0; i < block_size; i ++) {
466 FX_DWORD objnum = start_objnum + block * 1024 + i;
467 char* pEntry = pBuf + i * recordsize;
468 if (pEntry[17] == 'f') {
469 m_CrossRef.SetAtGrow(objnum, 0);
470 m_V5Type.SetAtGrow(objnum, 0);
472 FX_INT32 offset = FXSYS_atoi(pEntry);
474 for (FX_INT32 c = 0; c < 10; c ++) {
475 if (pEntry[c] < '0' || pEntry[c] > '9') {
481 m_CrossRef.SetAtGrow(objnum, offset);
482 FX_INT32 version = FXSYS_atoi(pEntry + 11);
484 m_bVersionUpdated = TRUE;
486 m_ObjVersion.SetAtGrow(objnum, version);
487 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
488 FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
489 if (pResult == NULL) {
490 m_SortedOffset.Add(m_CrossRef[objnum]);
493 m_V5Type.SetAtGrow(objnum, 1);
498 m_Syntax.RestorePos(SavedPos + count * recordsize);
501 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip, FX_BOOL bFirst)
503 m_Syntax.RestorePos(pos);
504 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {
507 FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
508 if (pResult == NULL) {
509 m_SortedOffset.Add(pos);
512 FX_LPVOID pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
513 if (pResult == NULL) {
514 m_SortedOffset.Add(streampos);
518 FX_FILESIZE SavedPos = m_Syntax.SavePos();
520 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
521 if (word.IsEmpty()) {
525 m_Syntax.RestorePos(SavedPos);
528 FX_DWORD start_objnum = FXSYS_atoi(word);
529 if (start_objnum >= (1 << 20)) {
532 FX_DWORD count = m_Syntax.GetDirectNum();
533 m_Syntax.ToNextWord();
534 SavedPos = m_Syntax.SavePos();
535 FX_BOOL bFirstItem = FALSE;
536 FX_INT32 recordsize = 20;
540 m_dwXrefStartObjNum = start_objnum;
542 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
543 pBuf[1024 * recordsize] = '\0';
544 FX_INT32 nBlocks = count / 1024 + 1;
545 FX_BOOL bFirstBlock = TRUE;
546 for (FX_INT32 block = 0; block < nBlocks; block ++) {
547 FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;
548 m_Syntax.ReadBlock((FX_LPBYTE)pBuf, block_size * recordsize);
549 for (FX_INT32 i = 0; i < block_size; i ++) {
550 FX_DWORD objnum = start_objnum + block * 1024 + i;
551 char* pEntry = pBuf + i * recordsize;
552 if (pEntry[17] == 'f') {
558 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
559 FX_INT32 version = FXSYS_atoi(pEntry + 11);
560 if (offset == 0 && version == 65535 && start_objnum != 0) {
565 m_CrossRef.SetAtGrow(objnum, 0);
566 m_V5Type.SetAtGrow(objnum, 0);
568 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
570 for (FX_INT32 c = 0; c < 10; c ++) {
571 if (pEntry[c] < '0' || pEntry[c] > '9') {
577 m_CrossRef.SetAtGrow(objnum, offset);
578 FX_INT32 version = FXSYS_atoi(pEntry + 11);
580 m_bVersionUpdated = TRUE;
582 m_ObjVersion.SetAtGrow(objnum, version);
583 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
584 FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
585 if (pResult == NULL) {
586 m_SortedOffset.Add(m_CrossRef[objnum]);
589 m_V5Type.SetAtGrow(objnum, 1);
598 m_Syntax.RestorePos(SavedPos + count * recordsize);
601 if (!LoadCrossRefV5(streampos, streampos, FALSE)) {
606 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos)
608 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {
612 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
615 m_ObjectStreamMap.InitHashTable(101, FALSE);
616 m_bXRefStream = TRUE;
619 FX_BOOL CPDF_Parser::RebuildCrossRef()
621 m_CrossRef.RemoveAll();
622 m_V5Type.RemoveAll();
623 m_SortedOffset.RemoveAll();
624 m_ObjVersion.RemoveAll();
626 m_pTrailer->Release();
630 FX_INT32 inside_index = 0;
631 FX_DWORD objnum, gennum;
633 FX_LPBYTE buffer = FX_Alloc(FX_BYTE, 4096);
634 FX_FILESIZE pos = m_Syntax.m_HeaderOffset;
635 FX_FILESIZE start_pos, start_pos1;
636 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;
637 FX_BOOL bInUpdate = FALSE;
638 while (pos < m_Syntax.m_FileLen) {
639 FX_BOOL bOverFlow = FALSE;
640 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);
644 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {
647 for (FX_DWORD i = 0; i < size; i ++) {
648 FX_BYTE byte = buffer[i];
651 if (_PDF_CharType[byte] == 'W') {
654 if (byte <= '9' && byte >= '0') {
679 if (_PDF_CharType[byte] == 'W') {
681 } else if (byte <= '9' && byte >= '0') {
685 } else if (byte == 't') {
688 } else if (byte == 'x') {
697 if (byte <= '9' && byte >= '0') {
698 objnum = objnum * 10 + byte - '0';
700 } else if (_PDF_CharType[byte] == 'W') {
709 if (byte <= '9' && byte >= '0') {
710 start_pos1 = pos + i;
713 } else if (_PDF_CharType[byte] == 'W') {
715 } else if (byte == 't') {
724 if (byte <= '9' && byte >= '0') {
725 gennum = gennum * 10 + byte - '0';
727 } else if (_PDF_CharType[byte] == 'W') {
738 } else if (_PDF_CharType[byte] == 'W') {
740 } else if (byte <= '9' && byte >= '0') {
743 start_pos = start_pos1;
744 start_pos1 = pos + i;
746 } else if (byte == 't') {
755 switch (inside_index) {
773 if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {
774 if (objnum > 0x1000000) {
778 FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset;
779 last_obj = start_pos;
780 FX_LPVOID pResult = FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
781 if (pResult == NULL) {
782 m_SortedOffset.Add(obj_pos);
784 FX_FILESIZE obj_end = 0;
785 CPDF_Object *pObject = ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, NULL, &obj_end);
787 int iType = pObject->GetType();
788 if (iType == PDFOBJ_STREAM) {
789 CPDF_Stream* pStream = (CPDF_Stream*)pObject;
790 CPDF_Dictionary* pDict = pStream->GetDict();
792 if (pDict->KeyExist(FX_BSTRC("Type"))) {
793 CFX_ByteString bsValue = pDict->GetString(FX_BSTRC("Type"));
794 if (bsValue == FX_BSTRC("XRef") && pDict->KeyExist(FX_BSTRC("Size"))) {
795 CPDF_Object* pRoot = pDict->GetElement(FX_BSTRC("Root"));
796 if (pRoot && pRoot->GetDict() && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) {
798 m_pTrailer->Release();
800 m_pTrailer = (CPDF_Dictionary*)pDict->Clone();
807 FX_FILESIZE offset = 0;
808 m_Syntax.RestorePos(obj_pos);
809 offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0);
815 FX_FILESIZE nLen = obj_end - obj_pos - offset;
816 if ((FX_DWORD)nLen > size - i) {
817 pos = obj_end + m_Syntax.m_HeaderOffset;
822 if (m_CrossRef.GetSize() > (FX_INT32)objnum && m_CrossRef[objnum]) {
824 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum);
825 m_CrossRef[objnum] = obj_pos;
826 m_ObjVersion.SetAt(objnum, (FX_SHORT)gennum);
827 if (oldgen != gennum) {
828 m_bVersionUpdated = TRUE;
832 m_CrossRef.SetAtGrow(objnum, obj_pos);
833 m_V5Type.SetAtGrow(objnum, 1);
834 m_ObjVersion.SetAtGrow(objnum, (FX_SHORT)gennum);
846 if (inside_index == 7) {
847 if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {
848 last_trailer = pos + i - 7;
849 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset);
850 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
852 if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj->GetType() != PDFOBJ_STREAM) {
855 CPDF_Dictionary* pTrailer = NULL;
856 if (pObj->GetType() == PDFOBJ_STREAM) {
857 pTrailer = ((CPDF_Stream*)pObj)->GetDict();
859 pTrailer = (CPDF_Dictionary*)pObj;
863 CPDF_Object* pRoot = pTrailer->GetElement(FX_BSTRC("Root"));
864 if (pRoot == NULL || (pRoot->GetType() == PDFOBJ_REFERENCE &&
865 (FX_DWORD)m_CrossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() &&
866 m_CrossRef.GetAt(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) {
867 FX_POSITION pos = pTrailer->GetStartPos();
870 CPDF_Object* pObj = pTrailer->GetNextElement(pos, key);
871 m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument);
878 if (pObj->GetType() == PDFOBJ_STREAM) {
879 m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone();
882 m_pTrailer = pTrailer;
884 FX_FILESIZE dwSavePos = m_Syntax.SavePos();
885 CFX_ByteString strWord = m_Syntax.GetKeyword();
886 if (!strWord.Compare(FX_BSTRC("startxref"))) {
887 FX_BOOL bNumber = FALSE;
888 CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber);
890 m_LastXRefOffset = FXSYS_atoi(bsOffset);
893 m_Syntax.RestorePos(dwSavePos);
904 } else if (byte == "trailer"[inside_index]) {
912 if (inside_index == 4) {
913 last_xref = pos + i - 4;
915 } else if (byte == "xref"[inside_index]) {
923 if (byte == '\r' || byte == '\n') {
932 } else if (byte == '(') {
940 if (byte == '<' && inside_index == 1) {
942 } else if (byte == '>') {
952 if (_PDF_CharType[byte] == 'D' || _PDF_CharType[byte] == 'W') {
958 if (_PDF_CharType[byte] == 'W') {
960 } else if (byte == '%' || byte == '(' || byte == '<' || byte == '\\') {
963 } else if (inside_index == 6) {
966 } else if (byte == "endobj"[inside_index]) {
978 if (last_xref != -1 && last_xref > last_obj) {
979 last_trailer = last_xref;
980 } else if (last_trailer == -1 || last_xref < last_obj) {
981 last_trailer = m_Syntax.m_FileLen;
983 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;
984 FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
985 if (pResult == NULL) {
986 m_SortedOffset.Add(offset);
991 static FX_DWORD _GetVarInt(FX_LPCBYTE p, FX_INT32 n)
994 for (FX_INT32 i = 0; i < n; i ++) {
995 result = result * 256 + p[i];
999 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef)
1001 CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL);
1006 CPDF_Dictionary * pDict = m_pDocument->GetRoot();
1007 if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) {
1008 m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream);
1010 if (pStream->GetType() == PDFOBJ_STREAM) {
1016 if (pStream->GetType() != PDFOBJ_STREAM) {
1019 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev"));
1020 FX_INT32 size = pStream->GetDict()->GetInteger(FX_BSTRC("Size"));
1026 m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone();
1027 m_CrossRef.SetSize(size);
1028 if (m_V5Type.SetSize(size)) {
1029 FXSYS_memset32(m_V5Type.GetData(), 0, size);
1032 m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone());
1034 std::vector<std::pair<FX_INT32, FX_INT32> > arrIndex;
1035 CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index"));
1037 FX_DWORD nPairSize = pArray->GetCount() / 2;
1038 for (FX_DWORD i = 0; i < nPairSize; i++) {
1039 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2);
1040 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1);
1041 if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER
1042 && pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) {
1043 arrIndex.push_back(std::make_pair(pStartNumObj->GetInteger(), pCountObj->GetInteger()));
1047 if (arrIndex.size() == 0) {
1048 arrIndex.push_back(std::make_pair(0, size));
1050 pArray = pStream->GetDict()->GetArray(FX_BSTRC("W"));
1051 if (pArray == NULL) {
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];
1061 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) {
1065 FX_DWORD totalWidth = dwAccWidth.ValueOrDie();
1067 acc.LoadAllData(pStream);
1068 FX_LPCBYTE 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 FX_INT32 startnum = arrIndex[i].first;
1076 m_dwXrefStartObjNum = base::checked_cast<FX_DWORD, FX_INT32> (startnum);
1077 FX_DWORD count = base::checked_cast<FX_DWORD, FX_INT32> (arrIndex[i].second);
1078 FX_SAFE_DWORD dwCaculatedSize = segindex;
1079 dwCaculatedSize += count;
1080 dwCaculatedSize *= totalWidth;
1081 if (!dwCaculatedSize.IsValid() || dwCaculatedSize.ValueOrDie() > dwTotalSize) {
1084 FX_LPCBYTE segstart = pData + segindex * totalWidth;
1085 FX_SAFE_DWORD dwMaxObjNum = startnum;
1086 dwMaxObjNum += count;
1087 FX_DWORD dwV5Size = base::checked_cast<FX_DWORD, FX_INT32> (m_V5Type.GetSize());
1088 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) {
1091 for (FX_DWORD j = 0; j < count; j ++) {
1093 FX_LPCBYTE entrystart = segstart + j * totalWidth;
1094 if (WidthArray[0]) {
1095 type = _GetVarInt(entrystart, WidthArray[0]);
1097 if (m_V5Type[startnum + j] == 255) {
1098 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
1099 m_CrossRef[startnum + j] = offset;
1100 FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1101 if (pResult == NULL) {
1102 m_SortedOffset.Add(offset);
1106 if (m_V5Type[startnum + j]) {
1109 m_V5Type[startnum + j] = type;
1111 m_CrossRef[startnum + j] = 0;
1113 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
1114 m_CrossRef[startnum + j] = offset;
1116 FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1117 if (pResult == NULL) {
1118 m_SortedOffset.Add(offset);
1121 if (offset < 0 || offset >= m_V5Type.GetSize()) {
1125 m_V5Type[offset] = 255;
1134 CPDF_Array* CPDF_Parser::GetIDArray()
1136 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL;
1140 if (pID->GetType() == PDFOBJ_REFERENCE) {
1141 pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());
1142 m_pTrailer->SetAt(FX_BSTRC("ID"), pID);
1144 if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {
1147 return (CPDF_Array*)pID;
1149 FX_DWORD CPDF_Parser::GetRootObjNum()
1151 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL;
1152 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
1155 return ((CPDF_Reference*) pRef)->GetRefObjNum();
1157 FX_DWORD CPDF_Parser::GetInfoObjNum()
1159 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL;
1160 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
1163 return ((CPDF_Reference*) pRef)->GetRefObjNum();
1165 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm)
1168 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1171 if (m_V5Type[objnum] == 0) {
1174 if (m_V5Type[objnum] == 2) {
1177 FX_FILESIZE pos = m_CrossRef[objnum];
1178 FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1179 if (pResult == NULL) {
1182 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {
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);
1192 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext)
1194 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1197 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1198 FX_FILESIZE pos = m_CrossRef[objnum];
1202 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);
1204 if (m_V5Type[objnum] == 2) {
1205 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
1206 if (pObjStream == NULL) {
1209 FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
1210 FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
1211 CPDF_SyntaxParser syntax;
1212 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));
1213 syntax.InitParser((IFX_FileStream*)file, 0);
1214 CPDF_Object* pRet = NULL;
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, 0, pContext);
1229 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum)
1231 CPDF_StreamAcc* pStreamAcc = NULL;
1232 if (m_ObjectStreamMap.Lookup((void*)(FX_UINTPTR)objnum, (void*&)pStreamAcc)) {
1235 const CPDF_Stream* pStream = m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL;
1236 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
1239 pStreamAcc = FX_NEW CPDF_StreamAcc;
1240 pStreamAcc->LoadAllData(pStream);
1241 m_ObjectStreamMap.SetAt((void*)(FX_UINTPTR)objnum, pStreamAcc);
1244 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum)
1246 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1249 if (m_V5Type[objnum] == 2) {
1250 objnum = (FX_DWORD)m_CrossRef[objnum];
1252 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
1253 FX_FILESIZE offset = m_CrossRef[objnum];
1257 FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1258 if (pResult == NULL) {
1261 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {
1264 return ((FX_FILESIZE*)pResult)[1] - offset;
1268 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, FX_LPBYTE& pBuffer, FX_DWORD& size)
1272 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
1275 if (m_V5Type[objnum] == 2) {
1276 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
1277 if (pObjStream == NULL) {
1280 FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
1281 FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
1282 CPDF_SyntaxParser syntax;
1283 FX_LPCBYTE pData = pObjStream->GetData();
1284 FX_DWORD totalsize = pObjStream->GetSize();
1285 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pData, (size_t)totalsize, FALSE));
1286 syntax.InitParser((IFX_FileStream*)file, 0);
1288 FX_DWORD thisnum = syntax.GetDirectNum();
1289 FX_DWORD thisoff = syntax.GetDirectNum();
1290 if (thisnum == objnum) {
1292 size = totalsize - (thisoff + offset);
1294 syntax.GetDirectNum(); // Skip nextnum.
1295 FX_DWORD nextoff = syntax.GetDirectNum();
1296 size = nextoff - thisoff;
1298 pBuffer = FX_Alloc(FX_BYTE, size);
1299 FXSYS_memcpy32(pBuffer, pData + thisoff + offset, size);
1306 if (m_V5Type[objnum] == 1) {
1307 FX_FILESIZE pos = m_CrossRef[objnum];
1311 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1312 m_Syntax.RestorePos(pos);
1314 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1316 m_Syntax.RestorePos(SavedPos);
1319 FX_DWORD parser_objnum = FXSYS_atoi(word);
1320 if (parser_objnum && parser_objnum != objnum) {
1321 m_Syntax.RestorePos(SavedPos);
1324 word = m_Syntax.GetNextWord(bIsNumber);
1326 m_Syntax.RestorePos(SavedPos);
1329 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1330 m_Syntax.RestorePos(SavedPos);
1333 FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1334 if (pResult == NULL) {
1335 m_Syntax.RestorePos(SavedPos);
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;
1352 if (!bNextOffValid) {
1353 m_Syntax.RestorePos(pos);
1355 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) {
1358 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) {
1362 nextoff = m_Syntax.SavePos();
1364 size = (FX_DWORD)(nextoff - pos);
1365 pBuffer = FX_Alloc(FX_BYTE, size);
1366 m_Syntax.RestorePos(pos);
1367 m_Syntax.ReadBlock(pBuffer, size);
1368 m_Syntax.RestorePos(SavedPos);
1371 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
1372 PARSE_CONTEXT* pContext)
1374 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1375 m_Syntax.RestorePos(pos);
1377 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1379 m_Syntax.RestorePos(SavedPos);
1382 FX_FILESIZE objOffset = m_Syntax.SavePos();
1383 objOffset -= word.GetLength();
1384 FX_DWORD parser_objnum = FXSYS_atoi(word);
1385 if (objnum && parser_objnum != objnum) {
1386 m_Syntax.RestorePos(SavedPos);
1389 word = m_Syntax.GetNextWord(bIsNumber);
1391 m_Syntax.RestorePos(SavedPos);
1394 FX_DWORD parser_gennum = FXSYS_atoi(word);
1395 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1396 m_Syntax.RestorePos(SavedPos);
1399 CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, parser_gennum, 0, pContext);
1400 FX_FILESIZE endOffset = m_Syntax.SavePos();
1401 CFX_ByteString bsWord = m_Syntax.GetKeyword();
1402 if (bsWord == FX_BSTRC("endobj")) {
1403 endOffset = m_Syntax.SavePos();
1405 m_Syntax.RestorePos(SavedPos);
1408 pObj->m_ObjNum = parser_objnum;
1410 pObj->m_GenNum = parser_gennum;
1414 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
1415 struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos)
1417 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1418 m_Syntax.RestorePos(pos);
1420 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1422 m_Syntax.RestorePos(SavedPos);
1425 FX_DWORD parser_objnum = FXSYS_atoi(word);
1426 if (objnum && parser_objnum != objnum) {
1427 m_Syntax.RestorePos(SavedPos);
1430 word = m_Syntax.GetNextWord(bIsNumber);
1432 m_Syntax.RestorePos(SavedPos);
1435 FX_DWORD gennum = FXSYS_atoi(word);
1436 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1437 m_Syntax.RestorePos(SavedPos);
1440 CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, 0, pContext);
1442 *pResultPos = m_Syntax.m_Pos;
1444 m_Syntax.RestorePos(SavedPos);
1447 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4()
1449 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) {
1452 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
1453 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) {
1459 return (CPDF_Dictionary*)pObj;
1461 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision)
1463 if (m_pSecurityHandler == NULL) {
1464 return (FX_DWORD) - 1;
1466 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions();
1467 if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) {
1468 dwPermission &= 0xFFFFFFFC;
1469 dwPermission |= 0xFFFFF0C0;
1470 if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) {
1471 dwPermission &= 0xFFFFF0FF;
1474 return dwPermission;
1476 FX_BOOL CPDF_Parser::IsOwner()
1478 return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner();
1480 void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_BOOL bForced)
1482 ASSERT(m_pSecurityHandler == NULL);
1483 if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {
1484 delete m_pSecurityHandler;
1485 m_pSecurityHandler = NULL;
1487 m_bForceUseSecurityHandler = bForced;
1488 m_pSecurityHandler = pSecurityHandler;
1489 if (m_bForceUseSecurityHandler) {
1492 m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler();
1493 m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler);
1495 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset)
1497 m_Syntax.InitParser(pFileAccess, offset);
1498 m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9);
1499 FX_FILESIZE SavedPos = m_Syntax.SavePos();
1501 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
1505 FX_DWORD objnum = FXSYS_atoi(word);
1506 word = m_Syntax.GetNextWord(bIsNumber);
1510 FX_DWORD gennum = FXSYS_atoi(word);
1511 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
1512 m_Syntax.RestorePos(SavedPos);
1515 m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0);
1516 if (!m_pLinearized) {
1519 if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {
1520 m_Syntax.GetNextWord(bIsNumber);
1521 CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
1523 m_pLinearized->Release();
1524 m_pLinearized = NULL;
1527 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) {
1530 CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
1531 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
1532 m_dwFirstPageNo = pNo->GetInteger();
1534 CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T"));
1535 if (pTable && pTable->GetType() == PDFOBJ_NUMBER) {
1536 m_LastXRefOffset = pTable->GetInteger();
1540 m_pLinearized->Release();
1541 m_pLinearized = NULL;
1544 FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)
1546 CloseParser(bReParse);
1547 m_bXRefStream = FALSE;
1548 m_LastXRefOffset = 0;
1549 m_bOwnFileRead = bOwnFileRead;
1550 FX_INT32 offset = GetHeaderOffset(pFileAccess);
1552 return PDFPARSE_ERROR_FORMAT;
1554 if (!IsLinearizedFile(pFileAccess, offset)) {
1555 m_Syntax.m_pFileAccess = NULL;
1556 return StartParse(pFileAccess, bReParse, bOwnFileRead);
1559 m_pDocument = FX_NEW CPDF_Document(this);
1561 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos();
1562 FX_BOOL bXRefRebuilt = FALSE;
1563 FX_BOOL bLoadV4 = FALSE;
1564 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) {
1565 if (!RebuildCrossRef()) {
1566 return PDFPARSE_ERROR_FORMAT;
1568 bXRefRebuilt = TRUE;
1569 m_LastXRefOffset = 0;
1572 m_pTrailer = LoadTrailerV4();
1573 if (m_pTrailer == NULL) {
1576 FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
1577 if (xrefsize == 0) {
1580 m_CrossRef.SetSize(xrefsize);
1581 m_V5Type.SetSize(xrefsize);
1583 FX_DWORD dwRet = SetEncryptHandler();
1584 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1587 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
1588 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
1590 return PDFPARSE_ERROR_FORMAT;
1592 ReleaseEncryptHandler();
1593 if (!RebuildCrossRef()) {
1594 return PDFPARSE_ERROR_FORMAT;
1596 dwRet = SetEncryptHandler();
1597 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1600 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
1601 if (m_pDocument->GetRoot() == NULL) {
1602 return PDFPARSE_ERROR_FORMAT;
1605 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1606 FX_DWORD RootObjNum = GetRootObjNum();
1607 if (RootObjNum == 0) {
1608 ReleaseEncryptHandler();
1610 RootObjNum = GetRootObjNum();
1611 if (RootObjNum == 0) {
1612 return PDFPARSE_ERROR_FORMAT;
1614 dwRet = SetEncryptHandler();
1615 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
1619 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {
1620 CPDF_Object* pMetadata = m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));
1621 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
1622 m_Syntax.m_MetadataObjnum = ((CPDF_Reference*) pMetadata)->GetRefObjNum();
1625 return PDFPARSE_ERROR_SUCCESS;
1627 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos)
1629 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
1633 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
1636 m_ObjectStreamMap.InitHashTable(101, FALSE);
1637 m_bXRefStream = TRUE;
1640 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable()
1642 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum;
1643 m_Syntax.m_MetadataObjnum = 0;
1645 m_pTrailer->Release();
1648 m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset);
1650 FX_DWORD dwCount = 0;
1651 m_Syntax.GetNextChar(ch);
1652 FX_INT32 type = _PDF_CharType[ch];
1653 while (type == 'W') {
1655 if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) {
1658 m_Syntax.GetNextChar(ch);
1659 type = _PDF_CharType[ch];
1661 m_LastXRefOffset += dwCount;
1662 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
1665 CPDF_StreamAcc* pStream;
1666 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
1669 m_ObjectStreamMap.RemoveAll();
1670 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
1671 m_LastXRefOffset = 0;
1672 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
1673 return PDFPARSE_ERROR_FORMAT;
1675 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
1676 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
1677 return PDFPARSE_ERROR_SUCCESS;
1679 CPDF_SyntaxParser::CPDF_SyntaxParser()
1681 m_pFileAccess = NULL;
1682 m_pCryptoHandler = NULL;
1684 m_BufSize = CPDF_ModuleMgr::Get()->m_FileBufSize;
1686 m_MetadataObjnum = 0;
1688 m_bFileStream = FALSE;
1690 CPDF_SyntaxParser::~CPDF_SyntaxParser()
1693 FX_Free(m_pFileBuf);
1696 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, FX_BYTE& ch)
1698 FX_FILESIZE save_pos = m_Pos;
1700 FX_BOOL ret = GetNextChar(ch);
1704 FX_BOOL CPDF_SyntaxParser::GetNextChar(FX_BYTE& ch)
1706 FX_FILESIZE pos = m_Pos + m_HeaderOffset;
1707 if (pos >= m_FileLen) {
1710 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
1711 FX_FILESIZE read_pos = pos;
1712 FX_DWORD read_size = m_BufSize;
1713 if ((FX_FILESIZE)read_size > m_FileLen) {
1714 read_size = (FX_DWORD)m_FileLen;
1716 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
1717 if (m_FileLen < (FX_FILESIZE)read_size) {
1719 read_size = (FX_DWORD)m_FileLen;
1721 read_pos = m_FileLen - read_size;
1724 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
1727 m_BufOffset = read_pos;
1729 ch = m_pFileBuf[pos - m_BufOffset];
1733 FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, FX_BYTE& ch)
1735 pos += m_HeaderOffset;
1736 if (pos >= m_FileLen) {
1739 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
1740 FX_FILESIZE read_pos;
1741 if (pos < (FX_FILESIZE)m_BufSize) {
1744 read_pos = pos - m_BufSize + 1;
1746 FX_DWORD read_size = m_BufSize;
1747 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
1748 if (m_FileLen < (FX_FILESIZE)read_size) {
1750 read_size = (FX_DWORD)m_FileLen;
1752 read_pos = m_FileLen - read_size;
1755 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
1758 m_BufOffset = read_pos;
1760 ch = m_pFileBuf[pos - m_BufOffset];
1763 FX_BOOL CPDF_SyntaxParser::ReadBlock(FX_LPBYTE pBuf, FX_DWORD size)
1765 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) {
1771 #define MAX_WORD_BUFFER 256
1772 void CPDF_SyntaxParser::GetNextWord()
1777 if (!GetNextChar(ch)) {
1780 FX_BYTE type = _PDF_CharType[ch];
1782 while (type == 'W') {
1783 if (!GetNextChar(ch)) {
1786 type = _PDF_CharType[ch];
1792 if (!GetNextChar(ch)) {
1795 if (ch == '\r' || ch == '\n') {
1799 type = _PDF_CharType[ch];
1802 m_bIsNumber = FALSE;
1803 m_WordBuffer[m_WordSize++] = ch;
1806 if (!GetNextChar(ch)) {
1809 type = _PDF_CharType[ch];
1810 if (type != 'R' && type != 'N') {
1814 if (m_WordSize < MAX_WORD_BUFFER) {
1815 m_WordBuffer[m_WordSize++] = ch;
1818 } else if (ch == '<') {
1819 if (!GetNextChar(ch)) {
1823 m_WordBuffer[m_WordSize++] = ch;
1827 } else if (ch == '>') {
1828 if (!GetNextChar(ch)) {
1832 m_WordBuffer[m_WordSize++] = ch;
1840 if (m_WordSize < MAX_WORD_BUFFER) {
1841 m_WordBuffer[m_WordSize++] = ch;
1844 m_bIsNumber = FALSE;
1846 if (!GetNextChar(ch)) {
1849 type = _PDF_CharType[ch];
1850 if (type == 'D' || type == 'W') {
1856 CFX_ByteString CPDF_SyntaxParser::ReadString()
1859 if (!GetNextChar(ch)) {
1860 return CFX_ByteString();
1862 CFX_ByteTextBuf buf;
1863 FX_INT32 parlevel = 0;
1864 FX_INT32 status = 0, iEscCode = 0;
1869 if (parlevel == 0) {
1870 return buf.GetByteString();
1873 buf.AppendChar(')');
1874 } else if (ch == '(') {
1876 buf.AppendChar('(');
1877 } else if (ch == '\\') {
1884 if (ch >= '0' && ch <= '7') {
1885 iEscCode = ch - '0';
1890 buf.AppendChar('\n');
1891 } else if (ch == 'r') {
1892 buf.AppendChar('\r');
1893 } else if (ch == 't') {
1894 buf.AppendChar('\t');
1895 } else if (ch == 'b') {
1896 buf.AppendChar('\b');
1897 } else if (ch == 'f') {
1898 buf.AppendChar('\f');
1899 } else if (ch == '\r') {
1902 } else if (ch == '\n') {
1909 if (ch >= '0' && ch <= '7') {
1910 iEscCode = iEscCode * 8 + ch - '0';
1913 buf.AppendChar(iEscCode);
1919 if (ch >= '0' && ch <= '7') {
1920 iEscCode = iEscCode * 8 + ch - '0';
1921 buf.AppendChar(iEscCode);
1924 buf.AppendChar(iEscCode);
1936 if (!GetNextChar(ch)) {
1941 return buf.GetByteString();
1943 CFX_ByteString CPDF_SyntaxParser::ReadHexString()
1946 if (!GetNextChar(ch)) {
1947 return CFX_ByteString();
1950 FX_BOOL bFirst = TRUE;
1956 if (ch >= '0' && ch <= '9') {
1958 code = (ch - '0') * 16;
1961 buf.AppendByte((FX_BYTE)code);
1964 } else if (ch >= 'A' && ch <= 'F') {
1966 code = (ch - 'A' + 10) * 16;
1968 code += ch - 'A' + 10;
1969 buf.AppendByte((FX_BYTE)code);
1972 } else if (ch >= 'a' && ch <= 'f') {
1974 code = (ch - 'a' + 10) * 16;
1976 code += ch - 'a' + 10;
1977 buf.AppendByte((FX_BYTE)code);
1981 if (!GetNextChar(ch)) {
1986 buf.AppendByte((FX_BYTE)code);
1988 return buf.GetByteString();
1990 void CPDF_SyntaxParser::ToNextLine()
1994 if (!GetNextChar(ch)) {
2011 void CPDF_SyntaxParser::ToNextWord()
2014 if (!GetNextChar(ch)) {
2017 FX_BYTE type = _PDF_CharType[ch];
2019 while (type == 'W') {
2020 m_dwWordPos = m_Pos;
2021 if (!GetNextChar(ch)) {
2024 type = _PDF_CharType[ch];
2030 if (!GetNextChar(ch)) {
2033 if (ch == '\r' || ch == '\n') {
2037 type = _PDF_CharType[ch];
2041 CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber)
2044 bIsNumber = m_bIsNumber;
2045 return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);
2047 CFX_ByteString CPDF_SyntaxParser::GetKeyword()
2050 return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);
2052 CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, FX_INT32 level, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt)
2054 if (level > _PARSER_OBJECT_LEVLE_) {
2057 FX_FILESIZE SavedPos = m_Pos;
2058 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
2060 CFX_ByteString word = GetNextWord(bIsNumber);
2061 CPDF_Object* pRet = NULL;
2062 if (word.GetLength() == 0) {
2064 return (CPDF_Object*)PDFOBJ_INVALID;
2069 FX_FILESIZE SavedPos = m_Pos;
2070 CFX_ByteString nextword = GetNextWord(bIsNumber);
2072 CFX_ByteString nextword2 = GetNextWord(bIsNumber);
2073 if (nextword2 == FX_BSTRC("R")) {
2074 FX_DWORD objnum = FXSYS_atoi(word);
2076 return (CPDF_Object*)PDFOBJ_REFERENCE;
2078 pRet = CPDF_Reference::Create(pObjList, objnum);
2083 return (CPDF_Object*)PDFOBJ_NUMBER;
2085 pRet = CPDF_Number::Create(word);
2091 return (CPDF_Object*)PDFOBJ_NUMBER;
2093 pRet = CPDF_Number::Create(word);
2097 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2099 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2101 pRet = CPDF_Boolean::Create(word == FX_BSTRC("true"));
2104 if (word == FX_BSTRC("null")) {
2106 return (CPDF_Object*)PDFOBJ_NULL;
2108 pRet = CPDF_Null::Create();
2111 if (word == FX_BSTRC("(")) {
2113 return (CPDF_Object*)PDFOBJ_STRING;
2115 CFX_ByteString str = ReadString();
2116 if (m_pCryptoHandler && bDecrypt) {
2117 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2119 pRet = CPDF_String::Create(str, FALSE);
2122 if (word == FX_BSTRC("<")) {
2124 return (CPDF_Object*)PDFOBJ_STRING;
2126 CFX_ByteString str = ReadHexString();
2127 if (m_pCryptoHandler && bDecrypt) {
2128 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2130 pRet = CPDF_String::Create(str, TRUE);
2133 if (word == FX_BSTRC("[")) {
2135 return (CPDF_Object*)PDFOBJ_ARRAY;
2137 CPDF_Array* pArray = CPDF_Array::Create();
2139 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
2146 if (word[0] == '/') {
2148 return (CPDF_Object*)PDFOBJ_NAME;
2150 pRet = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
2153 if (word == FX_BSTRC("<<")) {
2154 FX_FILESIZE saveDictOffset = m_Pos - 2;
2155 FX_DWORD dwDictSize = 0;
2157 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2160 pContext->m_DictStart = SavedPos;
2162 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2164 FX_FILESIZE dwSignValuePos = 0;
2167 CFX_ByteString key = GetNextWord(bIsNumber);
2168 if (key.IsEmpty()) {
2173 FX_FILESIZE SavedPos = m_Pos - key.GetLength();
2174 if (key == FX_BSTRC(">>")) {
2175 dwDictSize = m_Pos - saveDictOffset;
2178 if (key == FX_BSTRC("endobj")) {
2179 dwDictSize = m_Pos - 6 - saveDictOffset;
2183 if (key[0] != '/') {
2187 key = PDF_NameDecode(key);
2188 if (key == FX_BSTRC("/Contents")) {
2189 dwSignValuePos = m_Pos;
2191 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
2195 if (key.GetLength() >= 1) {
2197 pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
2199 pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
2203 if (IsSignatureDict(pDict)) {
2204 FX_FILESIZE dwSavePos = m_Pos;
2205 m_Pos = dwSignValuePos;
2206 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1, NULL, FALSE);
2207 pDict->SetAt(FX_BSTRC("Contents"), pObj);
2211 pContext->m_DictEnd = m_Pos;
2212 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2216 FX_FILESIZE SavedPos = m_Pos;
2218 CFX_ByteString nextword = GetNextWord(bIsNumber);
2219 if (nextword == FX_BSTRC("stream")) {
2220 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2232 if (word == FX_BSTRC(">>")) {
2237 return (CPDF_Object*)PDFOBJ_INVALID;
2241 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum,
2242 FX_INT32 level, struct PARSE_CONTEXT* pContext)
2244 if (level > _PARSER_OBJECT_LEVLE_) {
2247 FX_FILESIZE SavedPos = m_Pos;
2248 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
2250 CFX_ByteString word = GetNextWord(bIsNumber);
2251 if (word.GetLength() == 0) {
2253 return (CPDF_Object*)PDFOBJ_INVALID;
2258 FX_FILESIZE SavedPos = m_Pos;
2259 CFX_ByteString nextword = GetNextWord(bIsNumber);
2261 CFX_ByteString nextword2 = GetNextWord(bIsNumber);
2262 if (nextword2 == FX_BSTRC("R")) {
2263 FX_DWORD objnum = FXSYS_atoi(word);
2265 return (CPDF_Object*)PDFOBJ_REFERENCE;
2267 return CPDF_Reference::Create(pObjList, objnum);
2271 return (CPDF_Object*)PDFOBJ_NUMBER;
2273 return CPDF_Number::Create(word);
2278 return (CPDF_Object*)PDFOBJ_NUMBER;
2280 return CPDF_Number::Create(word);
2283 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
2285 return (CPDF_Object*)PDFOBJ_BOOLEAN;
2287 return CPDF_Boolean::Create(word == FX_BSTRC("true"));
2289 if (word == FX_BSTRC("null")) {
2291 return (CPDF_Object*)PDFOBJ_NULL;
2293 return CPDF_Null::Create();
2295 if (word == FX_BSTRC("(")) {
2297 return (CPDF_Object*)PDFOBJ_STRING;
2299 CFX_ByteString str = ReadString();
2300 if (m_pCryptoHandler) {
2301 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2303 return CPDF_String::Create(str, FALSE);
2305 if (word == FX_BSTRC("<")) {
2307 return (CPDF_Object*)PDFOBJ_STRING;
2309 CFX_ByteString str = ReadHexString();
2310 if (m_pCryptoHandler) {
2311 m_pCryptoHandler->Decrypt(objnum, gennum, str);
2313 return CPDF_String::Create(str, TRUE);
2315 if (word == FX_BSTRC("[")) {
2317 return (CPDF_Object*)PDFOBJ_ARRAY;
2319 CPDF_Array* pArray = CPDF_Array::Create();
2321 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
2323 if (m_WordBuffer[0] == ']') {
2333 if (word[0] == '/') {
2335 return (CPDF_Object*)PDFOBJ_NAME;
2337 return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
2339 if (word == FX_BSTRC("<<")) {
2341 return (CPDF_Object*)PDFOBJ_DICTIONARY;
2344 pContext->m_DictStart = SavedPos;
2346 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
2349 FX_FILESIZE SavedPos = m_Pos;
2350 CFX_ByteString key = GetNextWord(bIsNumber);
2351 if (key.IsEmpty()) {
2356 if (key == FX_BSTRC(">>")) {
2359 if (key == FX_BSTRC("endobj")) {
2363 if (key[0] != '/') {
2366 key = PDF_NameDecode(key);
2367 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
2373 if (!GetNextChar(ch)) {
2376 if (ch == 0x0A || ch == 0x0D) {
2382 if (key.GetLength() == 1) {
2383 pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
2385 pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
2389 pContext->m_DictEnd = m_Pos;
2390 if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
2394 FX_FILESIZE SavedPos = m_Pos;
2396 CFX_ByteString nextword = GetNextWord(bIsNumber);
2397 if (nextword == FX_BSTRC("stream")) {
2398 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
2410 if (word == FX_BSTRC(">>")) {
2415 return (CPDF_Object*)PDFOBJ_INVALID;
2419 CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT* pContext,
2420 FX_DWORD objnum, FX_DWORD gennum)
2422 CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));
2423 FX_FILESIZE len = 0;
2424 if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) ||
2425 ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&
2426 ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) {
2427 len = pLenObj->GetInteger();
2431 FX_FILESIZE StreamStartPos = m_Pos;
2433 pContext->m_DataStart = m_Pos;
2436 CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;
2437 if (pCryptoHandler == NULL) {
2438 base::CheckedNumeric<FX_FILESIZE> pos = m_Pos;
2440 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) {
2441 m_Pos = pos.ValueOrDie();
2444 if (m_WordSize < 9 || FXSYS_memcmp32(m_WordBuffer, "endstream", 9)) {
2445 m_Pos = StreamStartPos;
2446 FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0);
2448 FX_FILESIZE curPos = m_Pos;
2449 m_Pos = StreamStartPos;
2450 FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0);
2451 if (endobjOffset < offset && endobjOffset >= 0) {
2452 offset = endobjOffset;
2456 FX_BYTE byte1, byte2;
2457 GetCharAt(StreamStartPos + offset - 1, byte1);
2458 GetCharAt(StreamStartPos + offset - 2, byte2);
2459 if (byte1 == 0x0a && byte2 == 0x0d) {
2461 } else if (byte1 == 0x0a || byte1 == 0x0d) {
2464 len = (FX_DWORD)offset;
2465 pDict->SetAtInteger(FX_BSTRC("Length"), len);
2467 m_Pos = StreamStartPos;
2468 if (FindTag(FX_BSTRC("endobj"), 0) < 0) {
2473 m_Pos = StreamStartPos;
2475 CPDF_Stream* pStream;
2476 FX_LPBYTE pData = FX_Alloc(FX_BYTE, len);
2480 ReadBlock(pData, len);
2481 if (pCryptoHandler) {
2482 CFX_BinaryBuf dest_buf;
2483 dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));
2484 FX_LPVOID context = pCryptoHandler->DecryptStart(objnum, gennum);
2485 pCryptoHandler->DecryptStream(context, pData, len, dest_buf);
2486 pCryptoHandler->DecryptFinish(context, dest_buf);
2488 pData = dest_buf.GetBuffer();
2489 len = dest_buf.GetSize();
2490 dest_buf.DetachBuffer();
2492 pStream = FX_NEW CPDF_Stream(pData, len, pDict);
2494 pContext->m_DataEnd = pContext->m_DataStart + len;
2496 StreamStartPos = m_Pos;
2498 if (m_WordSize == 6 && 0 == FXSYS_memcmp32(m_WordBuffer, "endobj", 6)) {
2499 m_Pos = StreamStartPos;
2503 void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset)
2506 FX_Free(m_pFileBuf);
2509 m_pFileBuf = FX_Alloc(FX_BYTE, m_BufSize);
2510 m_HeaderOffset = HeaderOffset;
2511 m_FileLen = pFileAccess->GetSize();
2513 m_pFileAccess = pFileAccess;
2515 pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize));
2517 FX_INT32 CPDF_SyntaxParser::GetDirectNum()
2523 m_WordBuffer[m_WordSize] = 0;
2524 return FXSYS_atoi((FX_LPCSTR)m_WordBuffer);
2526 FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, FX_LPCBYTE tag, FX_DWORD taglen)
2528 FX_BYTE type = _PDF_CharType[tag[0]];
2529 FX_BOOL bCheckLeft = type != 'D' && type != 'W';
2530 type = _PDF_CharType[tag[taglen - 1]];
2531 FX_BOOL bCheckRight = type != 'D' && type != 'W';
2533 if (bCheckRight && startpos + (FX_INT32)taglen <= limit && GetCharAt(startpos + (FX_INT32)taglen, ch)) {
2534 FX_BYTE type = _PDF_CharType[ch];
2535 if (type == 'N' || type == 'R') {
2539 if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
2540 FX_BYTE type = _PDF_CharType[ch];
2541 if (type == 'N' || type == 'R') {
2547 FX_BOOL CPDF_SyntaxParser::SearchWord(FX_BSTR tag, FX_BOOL bWholeWord, FX_BOOL bForward, FX_FILESIZE limit)
2549 FX_INT32 taglen = tag.GetLength();
2553 FX_FILESIZE pos = m_Pos;
2554 FX_INT32 offset = 0;
2556 offset = taglen - 1;
2558 FX_LPCBYTE tag_data = tag;
2563 if (pos >= m_Pos + limit) {
2567 if (!GetCharAt(pos, byte)) {
2572 if (pos <= m_Pos - limit) {
2576 if (!GetCharAtBackward(pos, byte)) {
2580 if (byte == tag_data[offset]) {
2583 if (offset < taglen) {
2594 FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;
2595 if (!bWholeWord || IsWholeWord(startpos, limit, tag, taglen)) {
2601 offset = byte == tag_data[0] ? 1 : 0;
2604 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;
2613 struct _SearchTagRecord {
2618 FX_INT32 CPDF_SyntaxParser::SearchMultiWord(FX_BSTR tags, FX_BOOL bWholeWord, FX_FILESIZE limit)
2620 FX_INT32 ntags = 1, i;
2621 for (i = 0; i < tags.GetLength(); i ++)
2625 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);
2626 FX_DWORD start = 0, itag = 0, max_len = 0;
2627 for (i = 0; i <= tags.GetLength(); i ++) {
2629 FX_DWORD len = i - start;
2630 if (len > max_len) {
2633 pPatterns[itag].m_pTag = tags.GetPtr() + start;
2634 pPatterns[itag].m_Len = len;
2635 pPatterns[itag].m_Offset = 0;
2640 FX_FILESIZE pos = m_Pos;
2642 GetCharAt(pos++, byte);
2643 FX_INT32 found = -1;
2645 for (i = 0; i < ntags; i ++) {
2646 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {
2647 pPatterns[i].m_Offset ++;
2648 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {
2649 if (!bWholeWord || IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag, pPatterns[i].m_Len)) {
2653 if (pPatterns[i].m_pTag[0] == byte) {
2654 pPatterns[i].m_Offset = 1;
2656 pPatterns[i].m_Offset = 0;
2661 if (pPatterns[i].m_pTag[0] == byte) {
2662 pPatterns[i].m_Offset = 1;
2664 pPatterns[i].m_Offset = 0;
2668 if (limit && pos >= m_Pos + limit) {
2671 if (!GetCharAt(pos, byte)) {
2680 FX_FILESIZE CPDF_SyntaxParser::FindTag(FX_BSTR tag, FX_FILESIZE limit)
2682 FX_INT32 taglen = tag.GetLength();
2685 FX_FILESIZE startpos = m_Pos;
2688 if (!GetNextChar(ch)) {
2691 if (ch == tag[match]) {
2693 if (match == taglen) {
2694 return m_Pos - startpos - taglen;
2697 match = ch == tag[0] ? 1 : 0;
2699 if (limit && m_Pos == limit) {
2705 void CPDF_SyntaxParser::GetBinary(FX_BYTE* buffer, FX_DWORD size)
2707 FX_DWORD offset = 0;
2710 if (!GetNextChar(ch)) {
2713 buffer[offset++] = ch;
2714 if (offset == size) {
2719 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead)
2721 m_pFileAvail = pFileAvail;
2722 m_pFileRead = pFileRead;
2726 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
2728 m_dwCurrentOffset = 0;
2732 m_dwFirstPageNo = 0;
2735 m_dwCurrentXRefSteam = 0;
2736 m_dwAcroFormObjNum = 0;
2739 m_dwEncryptObjNum = 0;
2740 m_dwPrevXRefOffset = 0;
2741 m_dwLastXRefOffset = 0;
2742 m_bDocAvail = FALSE;
2743 m_bMainXRefLoadTried = FALSE;
2744 m_bDocAvail = FALSE;
2745 m_bLinearized = FALSE;
2746 m_bPagesLoad = FALSE;
2747 m_bPagesTreeLoad = FALSE;
2748 m_bMainXRefLoadedOK = FALSE;
2749 m_bAnnotsLoad = FALSE;
2750 m_bHaveAcroForm = FALSE;
2751 m_bAcroFormLoad = FALSE;
2752 m_bPageLoadedOK = FALSE;
2753 m_bNeedDownLoadResource = FALSE;
2754 m_bLinearizedFormParamLoad = FALSE;
2755 m_pLinearized = NULL;
2758 m_pCurrentParser = NULL;
2761 m_pPageResource = NULL;
2762 m_pageMapCheckState = NULL;
2763 m_docStatus = PDF_DATAAVAIL_HEADER;
2764 m_parser.m_bOwnFileRead = FALSE;
2765 m_bTotalLoadPageTree = FALSE;
2766 m_bCurPageDictLoadOK = FALSE;
2767 m_bLinearedDataOK = FALSE;
2768 m_pagesLoadState = NULL;
2770 CPDF_DataAvail::~CPDF_DataAvail()
2772 if (m_pLinearized) {
2773 m_pLinearized->Release();
2779 m_pTrailer->Release();
2781 if (m_pageMapCheckState) {
2782 delete m_pageMapCheckState;
2784 if (m_pagesLoadState) {
2785 delete m_pagesLoadState;
2788 FX_INT32 iSize = m_arrayAcroforms.GetSize();
2789 for (i = 0; i < iSize; ++i) {
2790 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();
2793 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc)
2797 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset)
2799 CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser());
2800 if (pParser == NULL) {
2803 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {
2806 if (pParser->m_V5Type[objnum] == 2) {
2807 objnum = (FX_DWORD)pParser->m_CrossRef[objnum];
2809 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {
2810 offset = pParser->m_CrossRef[objnum];
2814 FX_LPVOID pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
2815 if (pResult == NULL) {
2818 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == pParser->m_SortedOffset.GetSize() - 1) {
2821 return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset);
2825 FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array)
2827 if (!obj_array.GetSize()) {
2831 CFX_PtrArray new_obj_array;
2833 for (i = 0; i < obj_array.GetSize(); i++) {
2834 CPDF_Object *pObj = (CPDF_Object *)obj_array[i];
2838 FX_INT32 type = pObj->GetType();
2840 case PDFOBJ_ARRAY: {
2841 CPDF_Array *pArray = pObj->GetArray();
2842 for (FX_DWORD k = 0; k < pArray->GetCount(); k++) {
2843 new_obj_array.Add(pArray->GetElement(k));
2848 pObj = pObj->GetDict();
2849 case PDFOBJ_DICTIONARY: {
2850 CPDF_Dictionary *pDict = pObj->GetDict();
2851 if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) {
2854 FX_POSITION pos = pDict->GetStartPos();
2858 value = pDict->GetNextElement(pos, key);
2859 if (key != "Parent") {
2860 new_obj_array.Add(value);
2865 case PDFOBJ_REFERENCE: {
2866 CPDF_Reference *pRef = (CPDF_Reference*)pObj;
2867 FX_DWORD dwNum = pRef->GetRefObjNum();
2869 FX_DWORD original_size = GetObjectSize(dwNum, offset);
2870 base::CheckedNumeric<FX_DWORD> size = original_size;
2871 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
2877 if (!size.IsValid()) {
2880 if (size.ValueOrDie() > m_dwFileLen) {
2881 size = m_dwFileLen - offset;
2883 size = original_size + 512;
2885 if (!size.IsValid()) {
2888 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
2889 pHints->AddSegment(offset, size.ValueOrDie());
2890 ret_array.Add(pObj);
2892 } else if (!m_objnum_array.Find(dwNum)) {
2893 m_objnum_array.AddObjNum(dwNum);
2894 CPDF_Object *pReferred = m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL);
2896 new_obj_array.Add(pReferred);
2904 FX_INT32 iSize = new_obj_array.GetSize();
2905 for (i = 0; i < iSize; ++i) {
2906 CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i];
2907 FX_INT32 type = pObj->GetType();
2908 if (type == PDFOBJ_REFERENCE) {
2909 CPDF_Reference *pRef = (CPDF_Reference *)pObj;
2910 FX_DWORD dwNum = pRef->GetRefObjNum();
2911 if (!m_objnum_array.Find(dwNum)) {
2912 ret_array.Add(pObj);
2915 ret_array.Add(pObj);
2920 obj_array.RemoveAll();
2921 obj_array.Append(new_obj_array);
2922 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
2924 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints)
2926 if (!m_dwFileLen && m_pFileRead) {
2927 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
2932 while (!m_bDocAvail) {
2933 if (!CheckDocStatus(pHints)) {
2939 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints)
2941 if (!m_objs_array.GetSize()) {
2942 m_objs_array.RemoveAll();
2943 m_objnum_array.RemoveAll();
2944 CFX_PtrArray obj_array;
2945 obj_array.Append(m_arrayAcroforms);
2946 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
2948 m_objs_array.RemoveAll();
2952 CFX_PtrArray new_objs_array;
2953 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
2955 FX_INT32 iSize = m_arrayAcroforms.GetSize();
2956 for (FX_INT32 i = 0; i < iSize; ++i) {
2957 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();
2959 m_arrayAcroforms.RemoveAll();
2961 m_objs_array.RemoveAll();
2962 m_objs_array.Append(new_objs_array);
2967 FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints)
2969 FX_BOOL bExist = FALSE;
2970 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
2972 m_docStatus = PDF_DATAAVAIL_PAGETREE;
2976 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
2977 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
2982 m_arrayAcroforms.Add(m_pAcroForm);
2983 m_docStatus = PDF_DATAAVAIL_PAGETREE;
2986 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints)
2988 switch (m_docStatus) {
2989 case PDF_DATAAVAIL_HEADER:
2990 return CheckHeader(pHints);
2991 case PDF_DATAAVAIL_FIRSTPAGE:
2992 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
2993 return CheckFirstPage(pHints);
2994 case PDF_DATAAVAIL_END:
2995 return CheckEnd(pHints);
2996 case PDF_DATAAVAIL_CROSSREF:
2997 return CheckCrossRef(pHints);
2998 case PDF_DATAAVAIL_CROSSREF_ITEM:
2999 return CheckCrossRefItem(pHints);
3000 case PDF_DATAAVAIL_CROSSREF_STREAM:
3001 return CheckAllCrossRefStream(pHints);
3002 case PDF_DATAAVAIL_TRAILER:
3003 return CheckTrailer(pHints);
3004 case PDF_DATAAVAIL_TRAILER_APPEND:
3005 return CheckTrailerAppend(pHints);
3006 case PDF_DATAAVAIL_LOADALLCRSOSSREF:
3007 return LoadAllXref(pHints);
3008 case PDF_DATAAVAIL_LOADALLFILE:
3009 return LoadAllFile(pHints);
3010 case PDF_DATAAVAIL_ROOT:
3011 return CheckRoot(pHints);
3012 case PDF_DATAAVAIL_INFO:
3013 return CheckInfo(pHints);
3014 case PDF_DATAAVAIL_ACROFORM:
3015 return CheckAcroForm(pHints);
3016 case PDF_DATAAVAIL_PAGETREE:
3017 if (m_bTotalLoadPageTree) {
3018 return CheckPages(pHints);
3020 return LoadDocPages(pHints);
3022 case PDF_DATAAVAIL_PAGE:
3023 if (m_bTotalLoadPageTree) {
3024 return CheckPage(pHints);
3026 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;
3029 case PDF_DATAAVAIL_ERROR:
3030 return LoadAllFile(pHints);
3031 case PDF_DATAAVAIL_PAGE_LATERLOAD:
3032 m_docStatus = PDF_DATAAVAIL_PAGE;
3038 FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints)
3040 switch (m_docStatus) {
3041 case PDF_DATAAVAIL_PAGETREE:
3042 return CheckPages(pHints);
3043 case PDF_DATAAVAIL_PAGE:
3044 return CheckPage(pHints);
3045 case PDF_DATAAVAIL_ERROR:
3046 return LoadAllFile(pHints);
3048 m_bPagesTreeLoad = TRUE;
3049 m_bPagesLoad = TRUE;
3053 FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints)
3055 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) {
3056 m_docStatus = PDF_DATAAVAIL_DONE;
3059 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen);
3062 FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints)
3064 m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset);
3065 m_parser.m_bOwnFileRead = FALSE;
3066 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {
3067 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
3070 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
3071 m_dwRootObjNum = m_parser.GetRootObjNum();
3072 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3073 m_pCurrentParser = &m_parser;
3074 m_docStatus = PDF_DATAAVAIL_ROOT;
3077 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile)
3079 CPDF_Object *pRet = NULL;
3080 FX_DWORD original_size = 0;
3081 FX_FILESIZE offset = 0;
3082 CPDF_Parser *pParser = NULL;
3085 *pExistInFile = TRUE;