Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "parser_int.h" | 7 #include "parser_int.h" |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "core/include/fpdfapi/fpdf_module.h" | 13 #include "core/include/fpdfapi/fpdf_module.h" |
| 14 #include "core/include/fpdfapi/fpdf_page.h" | 14 #include "core/include/fpdfapi/fpdf_page.h" |
| 15 #include "core/include/fpdfapi/fpdf_parser.h" | 15 #include "core/include/fpdfapi/fpdf_parser.h" |
| 16 #include "core/include/fxcrt/fx_ext.h" | 16 #include "core/include/fxcrt/fx_ext.h" |
| 17 #include "core/include/fxcrt/fx_safe_types.h" | 17 #include "core/include/fxcrt/fx_safe_types.h" |
| 18 #include "core/src/fpdfapi/fpdf_page/pageint.h" | 18 #include "core/src/fpdfapi/fpdf_page/pageint.h" |
| 19 #include "third_party/base/nonstd_unique_ptr.h" | 19 #include "third_party/base/nonstd_unique_ptr.h" |
| 20 #include "third_party/base/stl_util.h" | 20 #include "third_party/base/stl_util.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const int32_t kMaxRef = 1048576; | |
|
Wei Li
2015/12/21 18:06:46
Maybe still write as 1<<20 or put in the comment t
Lei Zhang
2015/12/21 19:40:04
Actually, do you think we should leave this consta
Wei Li
2015/12/21 21:45:04
Isn't the theoretical bound of max ref num 10<<10
| |
| 25 | |
| 24 struct SearchTagRecord { | 26 struct SearchTagRecord { |
| 25 const char* m_pTag; | 27 const char* m_pTag; |
| 26 FX_DWORD m_Len; | 28 FX_DWORD m_Len; |
| 27 FX_DWORD m_Offset; | 29 FX_DWORD m_Offset; |
| 28 }; | 30 }; |
| 29 | 31 |
| 30 int CompareFileSize(const void* p1, const void* p2) { | 32 int CompareFileSize(const void* p1, const void* p2) { |
| 31 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; | 33 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; |
| 32 } | 34 } |
| 33 | 35 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 m_pLinearized = NULL; | 111 m_pLinearized = NULL; |
| 110 m_dwFirstPageNo = 0; | 112 m_dwFirstPageNo = 0; |
| 111 m_dwXrefStartObjNum = 0; | 113 m_dwXrefStartObjNum = 0; |
| 112 m_bOwnFileRead = TRUE; | 114 m_bOwnFileRead = TRUE; |
| 113 m_FileVersion = 0; | 115 m_FileVersion = 0; |
| 114 m_bForceUseSecurityHandler = FALSE; | 116 m_bForceUseSecurityHandler = FALSE; |
| 115 } | 117 } |
| 116 CPDF_Parser::~CPDF_Parser() { | 118 CPDF_Parser::~CPDF_Parser() { |
| 117 CloseParser(FALSE); | 119 CloseParser(FALSE); |
| 118 } | 120 } |
| 119 FX_DWORD CPDF_Parser::GetLastObjNum() { | 121 |
| 120 FX_DWORD dwSize = m_CrossRef.GetSize(); | 122 FX_DWORD CPDF_Parser::GetLastObjNum() const { |
| 121 return dwSize ? dwSize - 1 : 0; | 123 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; |
| 122 } | 124 } |
| 125 | |
| 126 bool CPDF_Parser::IsValidObjectNumber(FX_DWORD objnum) const { | |
| 127 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; | |
| 128 } | |
| 129 | |
| 123 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { | 130 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { |
| 124 m_pEncryptDict = pDict; | 131 m_pEncryptDict = pDict; |
| 125 } | 132 } |
| 126 void CPDF_Parser::CloseParser(FX_BOOL bReParse) { | 133 void CPDF_Parser::CloseParser(FX_BOOL bReParse) { |
| 127 m_bVersionUpdated = FALSE; | 134 m_bVersionUpdated = FALSE; |
| 128 if (!bReParse) { | 135 if (!bReParse) { |
| 129 delete m_pDocument; | 136 delete m_pDocument; |
| 130 m_pDocument = NULL; | 137 m_pDocument = NULL; |
| 131 } | 138 } |
| 132 if (m_pTrailer) { | 139 if (m_pTrailer) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 143 while (pos) { | 150 while (pos) { |
| 144 void* objnum; | 151 void* objnum; |
| 145 CPDF_StreamAcc* pStream; | 152 CPDF_StreamAcc* pStream; |
| 146 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); | 153 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); |
| 147 delete pStream; | 154 delete pStream; |
| 148 } | 155 } |
| 149 m_ObjectStreamMap.RemoveAll(); | 156 m_ObjectStreamMap.RemoveAll(); |
| 150 m_ObjCache.clear(); | 157 m_ObjCache.clear(); |
| 151 | 158 |
| 152 m_SortedOffset.RemoveAll(); | 159 m_SortedOffset.RemoveAll(); |
| 153 m_CrossRef.RemoveAll(); | 160 m_ObjectInfo.clear(); |
| 154 m_V5Type.RemoveAll(); | 161 m_V5Type.RemoveAll(); |
| 155 m_ObjVersion.RemoveAll(); | 162 m_ObjVersion.RemoveAll(); |
| 156 int32_t iLen = m_Trailers.GetSize(); | 163 int32_t iLen = m_Trailers.GetSize(); |
| 157 for (int32_t i = 0; i < iLen; ++i) { | 164 for (int32_t i = 0; i < iLen; ++i) { |
| 158 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) | 165 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) |
| 159 trailer->Release(); | 166 trailer->Release(); |
| 160 } | 167 } |
| 161 m_Trailers.RemoveAll(); | 168 m_Trailers.RemoveAll(); |
| 162 if (m_pLinearized) { | 169 if (m_pLinearized) { |
| 163 m_pLinearized->Release(); | 170 m_pLinearized->Release(); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 } | 331 } |
| 325 return PDFPARSE_ERROR_SUCCESS; | 332 return PDFPARSE_ERROR_SUCCESS; |
| 326 } | 333 } |
| 327 void CPDF_Parser::ReleaseEncryptHandler() { | 334 void CPDF_Parser::ReleaseEncryptHandler() { |
| 328 m_Syntax.m_pCryptoHandler.reset(); | 335 m_Syntax.m_pCryptoHandler.reset(); |
| 329 if (!m_bForceUseSecurityHandler) { | 336 if (!m_bForceUseSecurityHandler) { |
| 330 m_pSecurityHandler.reset(); | 337 m_pSecurityHandler.reset(); |
| 331 } | 338 } |
| 332 } | 339 } |
| 333 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) { | 340 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) { |
| 334 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 341 if (!IsValidObjectNumber(objnum)) |
| 335 return 0; | 342 return 0; |
| 336 } | 343 |
| 337 if (m_V5Type[objnum] == 1) { | 344 if (m_V5Type[objnum] == 1) |
| 338 return m_CrossRef[objnum]; | 345 return m_ObjectInfo[objnum].pos; |
| 339 } | 346 |
| 340 if (m_V5Type[objnum] == 2) { | 347 if (m_V5Type[objnum] == 2) { |
| 341 return m_CrossRef[(int32_t)m_CrossRef[objnum]]; | 348 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 349 return m_ObjectInfo[pos].pos; | |
| 342 } | 350 } |
| 343 return 0; | 351 return 0; |
| 344 } | 352 } |
| 345 | 353 |
| 346 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 354 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 347 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { | 355 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { |
| 348 return FALSE; | 356 return FALSE; |
| 349 } | 357 } |
| 350 m_pTrailer = LoadTrailerV4(); | 358 m_pTrailer = LoadTrailerV4(); |
| 351 if (!m_pTrailer) { | 359 if (!m_pTrailer) { |
| 352 return FALSE; | 360 return FALSE; |
| 353 } | 361 } |
| 354 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 362 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 355 if (xrefsize <= 0 || xrefsize > (1 << 20)) { | 363 if (xrefsize <= 0 || xrefsize > kMaxRef) { |
| 356 return FALSE; | 364 return FALSE; |
| 357 } | 365 } |
| 358 m_CrossRef.SetSize(xrefsize); | 366 m_ObjectInfo[0].pos = 0; |
| 359 m_V5Type.SetSize(xrefsize); | 367 m_V5Type.SetSize(xrefsize); |
| 360 CFX_FileSizeArray CrossRefList, XRefStreamList; | 368 CFX_FileSizeArray CrossRefList, XRefStreamList; |
| 361 CrossRefList.Add(xrefpos); | 369 CrossRefList.Add(xrefpos); |
| 362 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); | 370 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); |
| 363 if (!CheckDirectType(m_pTrailer, "Prev", PDFOBJ_NUMBER)) { | 371 if (!CheckDirectType(m_pTrailer, "Prev", PDFOBJ_NUMBER)) { |
| 364 return FALSE; | 372 return FALSE; |
| 365 } | 373 } |
| 366 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 374 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
| 367 if (newxrefpos == xrefpos) { | 375 if (newxrefpos == xrefpos) { |
| 368 return FALSE; | 376 return FALSE; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { | 459 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { |
| 452 return FALSE; | 460 return FALSE; |
| 453 } | 461 } |
| 454 if (!m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(pBuf), dwReadSize)) { | 462 if (!m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(pBuf), dwReadSize)) { |
| 455 return FALSE; | 463 return FALSE; |
| 456 } | 464 } |
| 457 for (int32_t i = 0; i < block_size; i++) { | 465 for (int32_t i = 0; i < block_size; i++) { |
| 458 FX_DWORD objnum = start_objnum + block * 1024 + i; | 466 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 459 char* pEntry = pBuf + i * recordsize; | 467 char* pEntry = pBuf + i * recordsize; |
| 460 if (pEntry[17] == 'f') { | 468 if (pEntry[17] == 'f') { |
| 461 m_CrossRef.SetAtGrow(objnum, 0); | 469 m_ObjectInfo[objnum].pos = 0; |
| 462 m_V5Type.SetAtGrow(objnum, 0); | 470 m_V5Type.SetAtGrow(objnum, 0); |
| 463 } else { | 471 } else { |
| 464 int32_t offset = FXSYS_atoi(pEntry); | 472 int32_t offset = FXSYS_atoi(pEntry); |
| 465 if (offset == 0) { | 473 if (offset == 0) { |
| 466 for (int32_t c = 0; c < 10; c++) { | 474 for (int32_t c = 0; c < 10; c++) { |
| 467 if (!std::isdigit(pEntry[c])) | 475 if (!std::isdigit(pEntry[c])) |
| 468 return FALSE; | 476 return FALSE; |
| 469 } | 477 } |
| 470 } | 478 } |
| 471 m_CrossRef.SetAtGrow(objnum, offset); | 479 m_ObjectInfo[objnum].pos = offset; |
| 472 int32_t version = FXSYS_atoi(pEntry + 11); | 480 int32_t version = FXSYS_atoi(pEntry + 11); |
| 473 if (version >= 1) { | 481 if (version >= 1) { |
| 474 m_bVersionUpdated = TRUE; | 482 m_bVersionUpdated = TRUE; |
| 475 } | 483 } |
| 476 m_ObjVersion.SetAtGrow(objnum, version); | 484 m_ObjVersion.SetAtGrow(objnum, version); |
| 477 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { | 485 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen) { |
| 478 void* pResult = FXSYS_bsearch( | 486 void* pResult = FXSYS_bsearch( |
| 479 &m_CrossRef[objnum], m_SortedOffset.GetData(), | 487 &m_ObjectInfo[objnum].pos, m_SortedOffset.GetData(), |
| 480 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize); | 488 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize); |
| 481 if (!pResult) { | 489 if (!pResult) { |
| 482 m_SortedOffset.Add(m_CrossRef[objnum]); | 490 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); |
| 483 } | 491 } |
| 484 } | 492 } |
| 485 m_V5Type.SetAtGrow(objnum, 1); | 493 m_V5Type.SetAtGrow(objnum, 1); |
| 486 } | 494 } |
| 487 } | 495 } |
| 488 } | 496 } |
| 489 m_Syntax.RestorePos(SavedPos + count * recordsize); | 497 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 490 return TRUE; | 498 return TRUE; |
| 491 } | 499 } |
| 492 | 500 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 513 FX_BOOL bIsNumber; | 521 FX_BOOL bIsNumber; |
| 514 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 522 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 515 if (word.IsEmpty()) | 523 if (word.IsEmpty()) |
| 516 return false; | 524 return false; |
| 517 | 525 |
| 518 if (!bIsNumber) { | 526 if (!bIsNumber) { |
| 519 m_Syntax.RestorePos(SavedPos); | 527 m_Syntax.RestorePos(SavedPos); |
| 520 break; | 528 break; |
| 521 } | 529 } |
| 522 FX_DWORD start_objnum = FXSYS_atoi(word); | 530 FX_DWORD start_objnum = FXSYS_atoi(word); |
| 523 if (start_objnum >= (1 << 20)) | 531 if (start_objnum >= kMaxRef) |
| 524 return false; | 532 return false; |
| 525 | 533 |
| 526 FX_DWORD count = m_Syntax.GetDirectNum(); | 534 FX_DWORD count = m_Syntax.GetDirectNum(); |
| 527 m_Syntax.ToNextWord(); | 535 m_Syntax.ToNextWord(); |
| 528 SavedPos = m_Syntax.SavePos(); | 536 SavedPos = m_Syntax.SavePos(); |
| 529 const int32_t recordsize = 20; | 537 const int32_t recordsize = 20; |
| 530 m_dwXrefStartObjNum = start_objnum; | 538 m_dwXrefStartObjNum = start_objnum; |
| 531 if (!bSkip) { | 539 if (!bSkip) { |
| 532 std::vector<char> buf(1024 * recordsize + 1); | 540 std::vector<char> buf(1024 * recordsize + 1); |
| 533 char* pBuf = pdfium::vector_as_array(&buf); | 541 char* pBuf = pdfium::vector_as_array(&buf); |
| 534 pBuf[1024 * recordsize] = '\0'; | 542 pBuf[1024 * recordsize] = '\0'; |
| 535 int32_t nBlocks = count / 1024 + 1; | 543 int32_t nBlocks = count / 1024 + 1; |
| 536 for (int32_t block = 0; block < nBlocks; block++) { | 544 for (int32_t block = 0; block < nBlocks; block++) { |
| 537 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | 545 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
| 538 m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(pBuf), | 546 m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(pBuf), |
| 539 block_size * recordsize); | 547 block_size * recordsize); |
| 540 for (int32_t i = 0; i < block_size; i++) { | 548 for (int32_t i = 0; i < block_size; i++) { |
| 541 FX_DWORD objnum = start_objnum + block * 1024 + i; | 549 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 542 char* pEntry = pBuf + i * recordsize; | 550 char* pEntry = pBuf + i * recordsize; |
| 543 if (pEntry[17] == 'f') { | 551 if (pEntry[17] == 'f') { |
| 544 m_CrossRef.SetAtGrow(objnum, 0); | 552 m_ObjectInfo[objnum].pos = 0; |
| 545 m_V5Type.SetAtGrow(objnum, 0); | 553 m_V5Type.SetAtGrow(objnum, 0); |
| 546 } else { | 554 } else { |
| 547 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); | 555 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); |
| 548 if (offset == 0) { | 556 if (offset == 0) { |
| 549 for (int32_t c = 0; c < 10; c++) { | 557 for (int32_t c = 0; c < 10; c++) { |
| 550 if (!std::isdigit(pEntry[c])) | 558 if (!std::isdigit(pEntry[c])) |
| 551 return false; | 559 return false; |
| 552 } | 560 } |
| 553 } | 561 } |
| 554 m_CrossRef.SetAtGrow(objnum, offset); | 562 m_ObjectInfo[objnum].pos = offset; |
| 555 int32_t version = FXSYS_atoi(pEntry + 11); | 563 int32_t version = FXSYS_atoi(pEntry + 11); |
| 556 if (version >= 1) { | 564 if (version >= 1) { |
| 557 m_bVersionUpdated = TRUE; | 565 m_bVersionUpdated = TRUE; |
| 558 } | 566 } |
| 559 m_ObjVersion.SetAtGrow(objnum, version); | 567 m_ObjVersion.SetAtGrow(objnum, version); |
| 560 if (m_CrossRef[objnum] < m_Syntax.m_FileLen && | 568 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen && |
| 561 !FindPosInOffsets(m_CrossRef[objnum])) { | 569 !FindPosInOffsets(m_ObjectInfo[objnum].pos)) { |
| 562 m_SortedOffset.Add(m_CrossRef[objnum]); | 570 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); |
| 563 } | 571 } |
| 564 m_V5Type.SetAtGrow(objnum, 1); | 572 m_V5Type.SetAtGrow(objnum, 1); |
| 565 } | 573 } |
| 566 } | 574 } |
| 567 } | 575 } |
| 568 } | 576 } |
| 569 m_Syntax.RestorePos(SavedPos + count * recordsize); | 577 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 570 } | 578 } |
| 571 return !streampos || LoadCrossRefV5(&streampos, FALSE); | 579 return !streampos || LoadCrossRefV5(&streampos, FALSE); |
| 572 } | 580 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 585 if (seen_xrefpos.find(xrefpos) != seen_xrefpos.end()) { | 593 if (seen_xrefpos.find(xrefpos) != seen_xrefpos.end()) { |
| 586 return FALSE; | 594 return FALSE; |
| 587 } | 595 } |
| 588 } | 596 } |
| 589 m_ObjectStreamMap.InitHashTable(101, FALSE); | 597 m_ObjectStreamMap.InitHashTable(101, FALSE); |
| 590 m_bXRefStream = TRUE; | 598 m_bXRefStream = TRUE; |
| 591 return TRUE; | 599 return TRUE; |
| 592 } | 600 } |
| 593 | 601 |
| 594 FX_BOOL CPDF_Parser::RebuildCrossRef() { | 602 FX_BOOL CPDF_Parser::RebuildCrossRef() { |
| 595 m_CrossRef.RemoveAll(); | 603 m_ObjectInfo.clear(); |
| 596 m_V5Type.RemoveAll(); | 604 m_V5Type.RemoveAll(); |
| 597 m_SortedOffset.RemoveAll(); | 605 m_SortedOffset.RemoveAll(); |
| 598 m_ObjVersion.RemoveAll(); | 606 m_ObjVersion.RemoveAll(); |
| 599 if (m_pTrailer) { | 607 if (m_pTrailer) { |
| 600 m_pTrailer->Release(); | 608 m_pTrailer->Release(); |
| 601 m_pTrailer = NULL; | 609 m_pTrailer = NULL; |
| 602 } | 610 } |
| 603 int32_t status = 0; | 611 int32_t status = 0; |
| 604 int32_t inside_index = 0; | 612 int32_t inside_index = 0; |
| 605 FX_DWORD objnum = 0, gennum = 0; | 613 FX_DWORD objnum = 0, gennum = 0; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 } else { | 795 } else { |
| 788 offset += 3; | 796 offset += 3; |
| 789 } | 797 } |
| 790 FX_FILESIZE nLen = obj_end - obj_pos - offset; | 798 FX_FILESIZE nLen = obj_end - obj_pos - offset; |
| 791 if ((FX_DWORD)nLen > size - i) { | 799 if ((FX_DWORD)nLen > size - i) { |
| 792 pos = obj_end + m_Syntax.m_HeaderOffset; | 800 pos = obj_end + m_Syntax.m_HeaderOffset; |
| 793 bOverFlow = TRUE; | 801 bOverFlow = TRUE; |
| 794 } else { | 802 } else { |
| 795 i += (FX_DWORD)nLen; | 803 i += (FX_DWORD)nLen; |
| 796 } | 804 } |
| 797 if (m_CrossRef.GetSize() > (int32_t)objnum && | 805 if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) && |
| 798 m_CrossRef[objnum]) { | 806 m_ObjectInfo[objnum].pos) { |
| 799 if (pObject) { | 807 if (pObject) { |
| 800 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); | 808 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); |
| 801 m_CrossRef[objnum] = obj_pos; | 809 m_ObjectInfo[objnum].pos = obj_pos; |
| 802 m_ObjVersion.SetAt(objnum, (int16_t)gennum); | 810 m_ObjVersion.SetAt(objnum, (int16_t)gennum); |
| 803 if (oldgen != gennum) { | 811 if (oldgen != gennum) { |
| 804 m_bVersionUpdated = TRUE; | 812 m_bVersionUpdated = TRUE; |
| 805 } | 813 } |
| 806 } | 814 } |
| 807 } else { | 815 } else { |
| 808 m_CrossRef.SetAtGrow(objnum, obj_pos); | 816 m_ObjectInfo[objnum].pos = obj_pos; |
| 809 m_V5Type.SetAtGrow(objnum, 1); | 817 m_V5Type.SetAtGrow(objnum, 1); |
| 810 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); | 818 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); |
| 811 } | 819 } |
| 812 if (pObject) { | 820 if (pObject) { |
| 813 pObject->Release(); | 821 pObject->Release(); |
| 814 } | 822 } |
| 815 } | 823 } |
| 816 --i; | 824 --i; |
| 817 status = 0; | 825 status = 0; |
| 818 break; | 826 break; |
| 819 } | 827 } |
| 820 break; | 828 break; |
| 821 case 7: | 829 case 7: |
| 822 if (inside_index == 7) { | 830 if (inside_index == 7) { |
| 823 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 831 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
| 824 last_trailer = pos + i - 7; | 832 last_trailer = pos + i - 7; |
| 825 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset); | 833 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset); |
| 826 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); | 834 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); |
| 827 if (pObj) { | 835 if (pObj) { |
| 828 if (!pObj->IsDictionary() && !pObj->AsStream()) { | 836 if (!pObj->IsDictionary() && !pObj->AsStream()) { |
| 829 pObj->Release(); | 837 pObj->Release(); |
| 830 } else { | 838 } else { |
| 831 CPDF_Stream* pStream = pObj->AsStream(); | 839 CPDF_Stream* pStream = pObj->AsStream(); |
| 832 if (CPDF_Dictionary* pTrailer = | 840 if (CPDF_Dictionary* pTrailer = |
| 833 pStream ? pStream->GetDict() : pObj->AsDictionary()) { | 841 pStream ? pStream->GetDict() : pObj->AsDictionary()) { |
| 834 if (m_pTrailer) { | 842 if (m_pTrailer) { |
| 835 CPDF_Object* pRoot = pTrailer->GetElement("Root"); | 843 CPDF_Object* pRoot = pTrailer->GetElement("Root"); |
| 836 CPDF_Reference* pRef = ToReference(pRoot); | 844 CPDF_Reference* pRef = ToReference(pRoot); |
| 837 if (!pRoot || | 845 if (!pRoot || |
| 838 (pRef && | 846 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && |
| 839 (FX_DWORD)m_CrossRef.GetSize() > | 847 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { |
| 840 pRef->GetRefObjNum() && | |
| 841 m_CrossRef.GetAt(pRef->GetRefObjNum()) != 0)) { | |
| 842 FX_POSITION pos = pTrailer->GetStartPos(); | 848 FX_POSITION pos = pTrailer->GetStartPos(); |
| 843 while (pos) { | 849 while (pos) { |
| 844 CFX_ByteString key; | 850 CFX_ByteString key; |
| 845 CPDF_Object* pElement = | 851 CPDF_Object* pElement = |
| 846 pTrailer->GetNextElement(pos, key); | 852 pTrailer->GetNextElement(pos, key); |
| 847 FX_DWORD dwObjNum = | 853 FX_DWORD dwObjNum = |
| 848 pElement ? pElement->GetObjNum() : 0; | 854 pElement ? pElement->GetObjNum() : 0; |
| 849 if (dwObjNum) { | 855 if (dwObjNum) { |
| 850 m_pTrailer->SetAtReference(key, m_pDocument, | 856 m_pTrailer->SetAtReference(key, m_pDocument, |
| 851 dwObjNum); | 857 dwObjNum); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 957 last_trailer = m_Syntax.m_FileLen; | 963 last_trailer = m_Syntax.m_FileLen; |
| 958 } | 964 } |
| 959 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; | 965 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; |
| 960 void* pResult = | 966 void* pResult = |
| 961 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 967 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 962 sizeof(FX_FILESIZE), CompareFileSize); | 968 sizeof(FX_FILESIZE), CompareFileSize); |
| 963 if (!pResult) { | 969 if (!pResult) { |
| 964 m_SortedOffset.Add(offset); | 970 m_SortedOffset.Add(offset); |
| 965 } | 971 } |
| 966 FX_Free(buffer); | 972 FX_Free(buffer); |
| 967 return m_pTrailer && m_CrossRef.GetSize() > 0; | 973 return m_pTrailer && !m_ObjectInfo.empty(); |
| 968 } | 974 } |
| 969 | 975 |
| 970 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 976 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
| 971 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); | 977 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); |
| 972 if (!pObject) | 978 if (!pObject) |
| 973 return FALSE; | 979 return FALSE; |
| 974 if (m_pDocument) { | 980 if (m_pDocument) { |
| 975 FX_BOOL bInserted = FALSE; | 981 FX_BOOL bInserted = FALSE; |
| 976 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 982 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
| 977 if (!pDict || pDict->GetObjNum() != pObject->m_ObjNum) { | 983 if (!pDict || pDict->GetObjNum() != pObject->m_ObjNum) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 989 return FALSE; | 995 return FALSE; |
| 990 | 996 |
| 991 *pos = pStream->GetDict()->GetInteger("Prev"); | 997 *pos = pStream->GetDict()->GetInteger("Prev"); |
| 992 int32_t size = pStream->GetDict()->GetInteger("Size"); | 998 int32_t size = pStream->GetDict()->GetInteger("Size"); |
| 993 if (size < 0) { | 999 if (size < 0) { |
| 994 pStream->Release(); | 1000 pStream->Release(); |
| 995 return FALSE; | 1001 return FALSE; |
| 996 } | 1002 } |
| 997 if (bMainXRef) { | 1003 if (bMainXRef) { |
| 998 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); | 1004 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); |
| 999 m_CrossRef.SetSize(size); | 1005 m_ObjectInfo[0].pos = 0; |
| 1000 if (m_V5Type.SetSize(size)) { | 1006 if (m_V5Type.SetSize(size)) { |
| 1001 FXSYS_memset(m_V5Type.GetData(), 0, size); | 1007 FXSYS_memset(m_V5Type.GetData(), 0, size); |
| 1002 } | 1008 } |
| 1003 } else { | 1009 } else { |
| 1004 m_Trailers.Add(ToDictionary(pStream->GetDict()->Clone())); | 1010 m_Trailers.Add(ToDictionary(pStream->GetDict()->Clone())); |
| 1005 } | 1011 } |
| 1006 std::vector<std::pair<int32_t, int32_t> > arrIndex; | 1012 std::vector<std::pair<int32_t, int32_t> > arrIndex; |
| 1007 CPDF_Array* pArray = pStream->GetDict()->GetArray("Index"); | 1013 CPDF_Array* pArray = pStream->GetDict()->GetArray("Index"); |
| 1008 if (pArray) { | 1014 if (pArray) { |
| 1009 FX_DWORD nPairSize = pArray->GetCount() / 2; | 1015 FX_DWORD nPairSize = pArray->GetCount() / 2; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1069 } | 1075 } |
| 1070 for (FX_DWORD j = 0; j < count; j++) { | 1076 for (FX_DWORD j = 0; j < count; j++) { |
| 1071 int32_t type = 1; | 1077 int32_t type = 1; |
| 1072 const uint8_t* entrystart = segstart + j * totalWidth; | 1078 const uint8_t* entrystart = segstart + j * totalWidth; |
| 1073 if (WidthArray[0]) { | 1079 if (WidthArray[0]) { |
| 1074 type = GetVarInt(entrystart, WidthArray[0]); | 1080 type = GetVarInt(entrystart, WidthArray[0]); |
| 1075 } | 1081 } |
| 1076 if (m_V5Type[startnum + j] == 255) { | 1082 if (m_V5Type[startnum + j] == 255) { |
| 1077 FX_FILESIZE offset = | 1083 FX_FILESIZE offset = |
| 1078 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); | 1084 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 1079 m_CrossRef[startnum + j] = offset; | 1085 m_ObjectInfo[startnum + j].pos = offset; |
| 1080 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), | 1086 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1081 m_SortedOffset.GetSize(), | 1087 m_SortedOffset.GetSize(), |
| 1082 sizeof(FX_FILESIZE), CompareFileSize); | 1088 sizeof(FX_FILESIZE), CompareFileSize); |
| 1083 if (!pResult) { | 1089 if (!pResult) { |
| 1084 m_SortedOffset.Add(offset); | 1090 m_SortedOffset.Add(offset); |
| 1085 } | 1091 } |
| 1086 continue; | 1092 continue; |
| 1087 } | 1093 } |
| 1088 if (m_V5Type[startnum + j]) { | 1094 if (m_V5Type[startnum + j]) { |
| 1089 continue; | 1095 continue; |
| 1090 } | 1096 } |
| 1091 m_V5Type[startnum + j] = type; | 1097 m_V5Type[startnum + j] = type; |
| 1092 if (type == 0) { | 1098 if (type == 0) { |
| 1093 m_CrossRef[startnum + j] = 0; | 1099 m_ObjectInfo[startnum + j].pos = 0; |
| 1094 } else { | 1100 } else { |
| 1095 FX_FILESIZE offset = | 1101 FX_FILESIZE offset = |
| 1096 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); | 1102 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 1097 m_CrossRef[startnum + j] = offset; | 1103 m_ObjectInfo[startnum + j].pos = offset; |
| 1098 if (type == 1) { | 1104 if (type == 1) { |
| 1099 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), | 1105 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1100 m_SortedOffset.GetSize(), | 1106 m_SortedOffset.GetSize(), |
| 1101 sizeof(FX_FILESIZE), CompareFileSize); | 1107 sizeof(FX_FILESIZE), CompareFileSize); |
| 1102 if (!pResult) { | 1108 if (!pResult) { |
| 1103 m_SortedOffset.Add(offset); | 1109 m_SortedOffset.Add(offset); |
| 1104 } | 1110 } |
| 1105 } else { | 1111 } else { |
| 1106 if (offset < 0 || offset >= m_V5Type.GetSize()) { | 1112 if (offset < 0 || offset >= m_V5Type.GetSize()) { |
| 1107 pStream->Release(); | 1113 pStream->Release(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1132 ToReference(m_pTrailer ? m_pTrailer->GetElement("Root") : nullptr); | 1138 ToReference(m_pTrailer ? m_pTrailer->GetElement("Root") : nullptr); |
| 1133 return pRef ? pRef->GetRefObjNum() : 0; | 1139 return pRef ? pRef->GetRefObjNum() : 0; |
| 1134 } | 1140 } |
| 1135 FX_DWORD CPDF_Parser::GetInfoObjNum() { | 1141 FX_DWORD CPDF_Parser::GetInfoObjNum() { |
| 1136 CPDF_Reference* pRef = | 1142 CPDF_Reference* pRef = |
| 1137 ToReference(m_pTrailer ? m_pTrailer->GetElement("Info") : nullptr); | 1143 ToReference(m_pTrailer ? m_pTrailer->GetElement("Info") : nullptr); |
| 1138 return pRef ? pRef->GetRefObjNum() : 0; | 1144 return pRef ? pRef->GetRefObjNum() : 0; |
| 1139 } | 1145 } |
| 1140 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { | 1146 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { |
| 1141 bForm = FALSE; | 1147 bForm = FALSE; |
| 1142 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 1148 if (!IsValidObjectNumber(objnum)) |
| 1143 return TRUE; | 1149 return TRUE; |
| 1144 } | 1150 if (m_V5Type[objnum] == 0) |
| 1145 if (m_V5Type[objnum] == 0) { | |
| 1146 return TRUE; | 1151 return TRUE; |
| 1147 } | 1152 if (m_V5Type[objnum] == 2) |
| 1148 if (m_V5Type[objnum] == 2) { | |
| 1149 return TRUE; | 1153 return TRUE; |
| 1150 } | 1154 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1151 FX_FILESIZE pos = m_CrossRef[objnum]; | |
| 1152 void* pResult = | 1155 void* pResult = |
| 1153 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 1156 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1154 sizeof(FX_FILESIZE), CompareFileSize); | 1157 sizeof(FX_FILESIZE), CompareFileSize); |
| 1155 if (!pResult) { | 1158 if (!pResult) { |
| 1156 return TRUE; | 1159 return TRUE; |
| 1157 } | 1160 } |
| 1158 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == | 1161 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == |
| 1159 m_SortedOffset.GetSize() - 1) { | 1162 m_SortedOffset.GetSize() - 1) { |
| 1160 return FALSE; | 1163 return FALSE; |
| 1161 } | 1164 } |
| 1162 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; | 1165 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; |
| 1163 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1166 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1164 m_Syntax.RestorePos(pos); | 1167 m_Syntax.RestorePos(pos); |
| 1165 const char kFormStream[] = "/Form\0stream"; | 1168 const char kFormStream[] = "/Form\0stream"; |
| 1166 const CFX_ByteStringC kFormStreamStr(kFormStream, sizeof(kFormStream) - 1); | 1169 const CFX_ByteStringC kFormStreamStr(kFormStream, sizeof(kFormStream) - 1); |
| 1167 bForm = m_Syntax.SearchMultiWord(kFormStreamStr, TRUE, size) == 0; | 1170 bForm = m_Syntax.SearchMultiWord(kFormStreamStr, TRUE, size) == 0; |
| 1168 m_Syntax.RestorePos(SavedPos); | 1171 m_Syntax.RestorePos(SavedPos); |
| 1169 return TRUE; | 1172 return TRUE; |
| 1170 } | 1173 } |
| 1171 | 1174 |
| 1172 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, | 1175 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, |
| 1173 FX_DWORD objnum, | 1176 FX_DWORD objnum, |
| 1174 PARSE_CONTEXT* pContext) { | 1177 PARSE_CONTEXT* pContext) { |
| 1175 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) | 1178 if (!IsValidObjectNumber(objnum)) |
| 1176 return nullptr; | 1179 return nullptr; |
| 1177 | 1180 |
| 1178 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | 1181 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { |
| 1179 FX_FILESIZE pos = m_CrossRef[objnum]; | 1182 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1180 if (pos <= 0) | 1183 if (pos <= 0) |
| 1181 return nullptr; | 1184 return nullptr; |
| 1182 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); | 1185 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); |
| 1183 } | 1186 } |
| 1184 if (m_V5Type[objnum] != 2) | 1187 if (m_V5Type[objnum] != 2) |
| 1185 return nullptr; | 1188 return nullptr; |
| 1186 | 1189 |
| 1187 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); | 1190 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
| 1188 if (!pObjStream) | 1191 if (!pObjStream) |
| 1189 return nullptr; | 1192 return nullptr; |
| 1190 | 1193 |
| 1191 ScopedFileStream file(FX_CreateMemoryStream( | 1194 ScopedFileStream file(FX_CreateMemoryStream( |
| 1192 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); | 1195 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); |
| 1193 CPDF_SyntaxParser syntax; | 1196 CPDF_SyntaxParser syntax; |
| 1194 syntax.InitParser(file.get(), 0); | 1197 syntax.InitParser(file.get(), 0); |
| 1195 const int32_t offset = GetStreamFirst(pObjStream); | 1198 const int32_t offset = GetStreamFirst(pObjStream); |
| 1196 | 1199 |
| 1197 // Read object numbers from |pObjStream| into a cache. | 1200 // Read object numbers from |pObjStream| into a cache. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1220 ToStream(m_pDocument ? m_pDocument->GetIndirectObject(objnum) : nullptr); | 1223 ToStream(m_pDocument ? m_pDocument->GetIndirectObject(objnum) : nullptr); |
| 1221 if (!pStream) | 1224 if (!pStream) |
| 1222 return nullptr; | 1225 return nullptr; |
| 1223 | 1226 |
| 1224 pStreamAcc = new CPDF_StreamAcc; | 1227 pStreamAcc = new CPDF_StreamAcc; |
| 1225 pStreamAcc->LoadAllData(pStream); | 1228 pStreamAcc->LoadAllData(pStream); |
| 1226 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); | 1229 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); |
| 1227 return pStreamAcc; | 1230 return pStreamAcc; |
| 1228 } | 1231 } |
| 1229 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) { | 1232 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) { |
| 1230 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 1233 if (!IsValidObjectNumber(objnum)) |
| 1231 return 0; | 1234 return 0; |
| 1232 } | 1235 |
| 1233 if (m_V5Type[objnum] == 2) { | 1236 if (m_V5Type[objnum] == 2) { |
| 1234 objnum = (FX_DWORD)m_CrossRef[objnum]; | 1237 objnum = m_ObjectInfo[objnum].pos; |
| 1235 } | 1238 } |
| 1236 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | 1239 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { |
| 1237 FX_FILESIZE offset = m_CrossRef[objnum]; | 1240 FX_FILESIZE offset = m_ObjectInfo[objnum].pos; |
| 1238 if (offset == 0) { | 1241 if (offset == 0) { |
| 1239 return 0; | 1242 return 0; |
| 1240 } | 1243 } |
| 1241 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), | 1244 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1242 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), | 1245 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 1243 CompareFileSize); | 1246 CompareFileSize); |
| 1244 if (!pResult) { | 1247 if (!pResult) { |
| 1245 return 0; | 1248 return 0; |
| 1246 } | 1249 } |
| 1247 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == | 1250 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == |
| 1248 m_SortedOffset.GetSize() - 1) { | 1251 m_SortedOffset.GetSize() - 1) { |
| 1249 return 0; | 1252 return 0; |
| 1250 } | 1253 } |
| 1251 return ((FX_FILESIZE*)pResult)[1] - offset; | 1254 return ((FX_FILESIZE*)pResult)[1] - offset; |
| 1252 } | 1255 } |
| 1253 return 0; | 1256 return 0; |
| 1254 } | 1257 } |
| 1255 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, | 1258 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, |
| 1256 uint8_t*& pBuffer, | 1259 uint8_t*& pBuffer, |
| 1257 FX_DWORD& size) { | 1260 FX_DWORD& size) { |
| 1258 pBuffer = NULL; | 1261 pBuffer = NULL; |
| 1259 size = 0; | 1262 size = 0; |
| 1260 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 1263 if (!IsValidObjectNumber(objnum)) |
| 1261 return; | 1264 return; |
| 1262 } | 1265 |
| 1263 if (m_V5Type[objnum] == 2) { | 1266 if (m_V5Type[objnum] == 2) { |
| 1264 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); | 1267 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
| 1265 if (!pObjStream) | 1268 if (!pObjStream) |
| 1266 return; | 1269 return; |
| 1267 | 1270 |
| 1268 int32_t offset = GetStreamFirst(pObjStream); | 1271 int32_t offset = GetStreamFirst(pObjStream); |
| 1269 const uint8_t* pData = pObjStream->GetData(); | 1272 const uint8_t* pData = pObjStream->GetData(); |
| 1270 FX_DWORD totalsize = pObjStream->GetSize(); | 1273 FX_DWORD totalsize = pObjStream->GetSize(); |
| 1271 ScopedFileStream file( | 1274 ScopedFileStream file( |
| 1272 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); | 1275 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); |
| 1273 CPDF_SyntaxParser syntax; | 1276 CPDF_SyntaxParser syntax; |
| 1274 syntax.InitParser(file.get(), 0); | 1277 syntax.InitParser(file.get(), 0); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1288 pBuffer = FX_Alloc(uint8_t, size); | 1291 pBuffer = FX_Alloc(uint8_t, size); |
| 1289 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); | 1292 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); |
| 1290 return; | 1293 return; |
| 1291 } | 1294 } |
| 1292 return; | 1295 return; |
| 1293 } | 1296 } |
| 1294 | 1297 |
| 1295 if (m_V5Type[objnum] != 1) | 1298 if (m_V5Type[objnum] != 1) |
| 1296 return; | 1299 return; |
| 1297 | 1300 |
| 1298 FX_FILESIZE pos = m_CrossRef[objnum]; | 1301 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1299 if (pos == 0) { | 1302 if (pos == 0) { |
| 1300 return; | 1303 return; |
| 1301 } | 1304 } |
| 1302 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1305 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1303 m_Syntax.RestorePos(pos); | 1306 m_Syntax.RestorePos(pos); |
| 1304 FX_BOOL bIsNumber; | 1307 FX_BOOL bIsNumber; |
| 1305 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1308 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1306 if (!bIsNumber) { | 1309 if (!bIsNumber) { |
| 1307 m_Syntax.RestorePos(SavedPos); | 1310 m_Syntax.RestorePos(SavedPos); |
| 1308 return; | 1311 return; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 bXRefRebuilt = TRUE; | 1565 bXRefRebuilt = TRUE; |
| 1563 m_LastXRefOffset = 0; | 1566 m_LastXRefOffset = 0; |
| 1564 } | 1567 } |
| 1565 if (bLoadV4) { | 1568 if (bLoadV4) { |
| 1566 m_pTrailer = LoadTrailerV4(); | 1569 m_pTrailer = LoadTrailerV4(); |
| 1567 if (!m_pTrailer) { | 1570 if (!m_pTrailer) { |
| 1568 return FALSE; | 1571 return FALSE; |
| 1569 } | 1572 } |
| 1570 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1573 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 1571 if (xrefsize > 0) { | 1574 if (xrefsize > 0) { |
| 1572 m_CrossRef.SetSize(xrefsize); | 1575 m_ObjectInfo[0].pos = 0; |
| 1573 m_V5Type.SetSize(xrefsize); | 1576 m_V5Type.SetSize(xrefsize); |
| 1574 } | 1577 } |
| 1575 } | 1578 } |
| 1576 FX_DWORD dwRet = SetEncryptHandler(); | 1579 FX_DWORD dwRet = SetEncryptHandler(); |
| 1577 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1580 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 1578 return dwRet; | 1581 return dwRet; |
| 1579 } | 1582 } |
| 1580 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); | 1583 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); |
| 1581 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { | 1584 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { |
| 1582 if (bXRefRebuilt) { | 1585 if (bXRefRebuilt) { |
| (...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2957 int iSize = m_arrayAcroforms.GetSize(); | 2960 int iSize = m_arrayAcroforms.GetSize(); |
| 2958 for (int i = 0; i < iSize; ++i) { | 2961 for (int i = 0; i < iSize; ++i) { |
| 2959 m_arrayAcroforms.GetAt(i)->Release(); | 2962 m_arrayAcroforms.GetAt(i)->Release(); |
| 2960 } | 2963 } |
| 2961 } | 2964 } |
| 2962 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { | 2965 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { |
| 2963 m_pDocument = pDoc; | 2966 m_pDocument = pDoc; |
| 2964 } | 2967 } |
| 2965 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { | 2968 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { |
| 2966 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 2969 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
| 2967 if (!pParser) { | 2970 if (!pParser || !pParser->IsValidObjectNumber(objnum)) |
| 2968 return 0; | 2971 return 0; |
| 2969 } | 2972 |
| 2970 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) { | |
| 2971 return 0; | |
| 2972 } | |
| 2973 if (pParser->m_V5Type[objnum] == 2) { | 2973 if (pParser->m_V5Type[objnum] == 2) { |
| 2974 objnum = (FX_DWORD)pParser->m_CrossRef[objnum]; | 2974 objnum = pParser->m_ObjectInfo[objnum].pos; |
| 2975 } | 2975 } else if (pParser->m_V5Type[objnum] == 1 || |
| 2976 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) { | 2976 pParser->m_V5Type[objnum] == 255) { |
| 2977 offset = pParser->m_CrossRef[objnum]; | 2977 offset = pParser->m_ObjectInfo[objnum].pos; |
| 2978 if (offset == 0) { | 2978 if (offset == 0) { |
| 2979 return 0; | 2979 return 0; |
| 2980 } | 2980 } |
| 2981 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), | 2981 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), |
| 2982 pParser->m_SortedOffset.GetSize(), | 2982 pParser->m_SortedOffset.GetSize(), |
| 2983 sizeof(FX_FILESIZE), CompareFileSize); | 2983 sizeof(FX_FILESIZE), CompareFileSize); |
| 2984 if (!pResult) { | 2984 if (!pResult) { |
| 2985 return 0; | 2985 return 0; |
| 2986 } | 2986 } |
| 2987 if ((FX_FILESIZE*)pResult - | 2987 if ((FX_FILESIZE*)pResult - |
| (...skipping 1993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4981 if (!m_pLinearizedDict) | 4981 if (!m_pLinearizedDict) |
| 4982 return -1; | 4982 return -1; |
| 4983 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4983 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4984 if (!pRange) | 4984 if (!pRange) |
| 4985 return -1; | 4985 return -1; |
| 4986 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4986 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4987 if (!pStreamLen) | 4987 if (!pStreamLen) |
| 4988 return -1; | 4988 return -1; |
| 4989 return pStreamLen->GetInteger(); | 4989 return pStreamLen->GetInteger(); |
| 4990 } | 4990 } |
| OLD | NEW |