| 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 "core/include/fpdfapi/fpdf_parser.h" | 7 #include "core/include/fpdfapi/fpdf_parser.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 bool CPDF_Parser::IsValidObjectNumber(FX_DWORD objnum) const { | 118 bool CPDF_Parser::IsValidObjectNumber(FX_DWORD objnum) const { |
| 119 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; | 119 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; |
| 120 } | 120 } |
| 121 | 121 |
| 122 FX_FILESIZE CPDF_Parser::GetObjectPositionOrZero(FX_DWORD objnum) const { | 122 FX_FILESIZE CPDF_Parser::GetObjectPositionOrZero(FX_DWORD objnum) const { |
| 123 auto it = m_ObjectInfo.find(objnum); | 123 auto it = m_ObjectInfo.find(objnum); |
| 124 return it != m_ObjectInfo.end() ? it->second.pos : 0; | 124 return it != m_ObjectInfo.end() ? it->second.pos : 0; |
| 125 } | 125 } |
| 126 | 126 |
| 127 uint8_t CPDF_Parser::GetObjectType(FX_DWORD objnum) const { | 127 uint8_t CPDF_Parser::GetObjectType(FX_DWORD objnum) const { |
| 128 return m_V5Type[objnum]; | 128 ASSERT(IsValidObjectNumber(objnum)); |
| 129 auto it = m_ObjectInfo.find(objnum); |
| 130 return it != m_ObjectInfo.end() ? it->second.type : 0; |
| 129 } | 131 } |
| 130 | 132 |
| 131 uint16_t CPDF_Parser::GetObjectGenNum(FX_DWORD objnum) const { | 133 uint16_t CPDF_Parser::GetObjectGenNum(FX_DWORD objnum) const { |
| 132 return m_ObjVersion[objnum]; | 134 return m_ObjVersion[objnum]; |
| 133 } | 135 } |
| 134 | 136 |
| 135 bool CPDF_Parser::IsObjectFreeOrNull(FX_DWORD objnum) const { | 137 bool CPDF_Parser::IsObjectFreeOrNull(FX_DWORD objnum) const { |
| 136 uint8_t type = GetObjectType(objnum); | 138 uint8_t type = GetObjectType(objnum); |
| 137 return type == 0 || type == 255; | 139 return type == 0 || type == 255; |
| 138 } | 140 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 SetEncryptDictionary(nullptr); | 172 SetEncryptDictionary(nullptr); |
| 171 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { | 173 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { |
| 172 m_Syntax.m_pFileAccess->Release(); | 174 m_Syntax.m_pFileAccess->Release(); |
| 173 m_Syntax.m_pFileAccess = nullptr; | 175 m_Syntax.m_pFileAccess = nullptr; |
| 174 } | 176 } |
| 175 m_ObjectStreamMap.clear(); | 177 m_ObjectStreamMap.clear(); |
| 176 m_ObjCache.clear(); | 178 m_ObjCache.clear(); |
| 177 | 179 |
| 178 m_SortedOffset.RemoveAll(); | 180 m_SortedOffset.RemoveAll(); |
| 179 m_ObjectInfo.clear(); | 181 m_ObjectInfo.clear(); |
| 180 m_V5Type.RemoveAll(); | |
| 181 m_ObjVersion.RemoveAll(); | 182 m_ObjVersion.RemoveAll(); |
| 182 int32_t iLen = m_Trailers.GetSize(); | 183 int32_t iLen = m_Trailers.GetSize(); |
| 183 for (int32_t i = 0; i < iLen; ++i) { | 184 for (int32_t i = 0; i < iLen; ++i) { |
| 184 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) | 185 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) |
| 185 trailer->Release(); | 186 trailer->Release(); |
| 186 } | 187 } |
| 187 m_Trailers.RemoveAll(); | 188 m_Trailers.RemoveAll(); |
| 188 if (m_pLinearized) { | 189 if (m_pLinearized) { |
| 189 m_pLinearized->Release(); | 190 m_pLinearized->Release(); |
| 190 m_pLinearized = nullptr; | 191 m_pLinearized = nullptr; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 335 |
| 335 void CPDF_Parser::ReleaseEncryptHandler() { | 336 void CPDF_Parser::ReleaseEncryptHandler() { |
| 336 m_Syntax.m_pCryptoHandler.reset(); | 337 m_Syntax.m_pCryptoHandler.reset(); |
| 337 m_pSecurityHandler.reset(); | 338 m_pSecurityHandler.reset(); |
| 338 } | 339 } |
| 339 | 340 |
| 340 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) const { | 341 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) const { |
| 341 if (!IsValidObjectNumber(objnum)) | 342 if (!IsValidObjectNumber(objnum)) |
| 342 return 0; | 343 return 0; |
| 343 | 344 |
| 344 if (m_V5Type[objnum] == 1) | 345 if (GetObjectType(objnum) == 1) |
| 345 return GetObjectPositionOrZero(objnum); | 346 return GetObjectPositionOrZero(objnum); |
| 346 | 347 |
| 347 if (m_V5Type[objnum] == 2) { | 348 if (GetObjectType(objnum) == 2) { |
| 348 FX_FILESIZE pos = GetObjectPositionOrZero(objnum); | 349 FX_FILESIZE pos = GetObjectPositionOrZero(objnum); |
| 349 return GetObjectPositionOrZero(pos); | 350 return GetObjectPositionOrZero(pos); |
| 350 } | 351 } |
| 351 return 0; | 352 return 0; |
| 352 } | 353 } |
| 353 | 354 |
| 354 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 355 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 355 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { | 356 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { |
| 356 return FALSE; | 357 return FALSE; |
| 357 } | 358 } |
| 358 m_pTrailer = LoadTrailerV4(); | 359 m_pTrailer = LoadTrailerV4(); |
| 359 if (!m_pTrailer) { | 360 if (!m_pTrailer) { |
| 360 return FALSE; | 361 return FALSE; |
| 361 } | 362 } |
| 362 | 363 |
| 363 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 364 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 364 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) { | 365 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) |
| 365 ShrinkObjectMap(xrefsize); | 366 ShrinkObjectMap(xrefsize); |
| 366 m_V5Type.SetSize(xrefsize); | |
| 367 } | |
| 368 | 367 |
| 369 CFX_FileSizeArray CrossRefList; | 368 CFX_FileSizeArray CrossRefList; |
| 370 CFX_FileSizeArray XRefStreamList; | 369 CFX_FileSizeArray XRefStreamList; |
| 371 CrossRefList.Add(xrefpos); | 370 CrossRefList.Add(xrefpos); |
| 372 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); | 371 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); |
| 373 | 372 |
| 374 std::set<FX_FILESIZE> seen_xrefpos; | 373 std::set<FX_FILESIZE> seen_xrefpos; |
| 375 seen_xrefpos.insert(xrefpos); | 374 seen_xrefpos.insert(xrefpos); |
| 376 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not | 375 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not |
| 377 // numerical, GetDirectInteger() returns 0. Loading will end. | 376 // numerical, GetDirectInteger() returns 0. Loading will end. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 } | 465 } |
| 467 if (!m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), | 466 if (!m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), |
| 468 dwReadSize)) { | 467 dwReadSize)) { |
| 469 return FALSE; | 468 return FALSE; |
| 470 } | 469 } |
| 471 for (int32_t i = 0; i < block_size; i++) { | 470 for (int32_t i = 0; i < block_size; i++) { |
| 472 FX_DWORD objnum = start_objnum + block * 1024 + i; | 471 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 473 char* pEntry = &buf[i * recordsize]; | 472 char* pEntry = &buf[i * recordsize]; |
| 474 if (pEntry[17] == 'f') { | 473 if (pEntry[17] == 'f') { |
| 475 m_ObjectInfo[objnum].pos = 0; | 474 m_ObjectInfo[objnum].pos = 0; |
| 476 m_V5Type.SetAtGrow(objnum, 0); | 475 m_ObjectInfo[objnum].type = 0; |
| 477 } else { | 476 } else { |
| 478 int32_t offset = FXSYS_atoi(pEntry); | 477 int32_t offset = FXSYS_atoi(pEntry); |
| 479 if (offset == 0) { | 478 if (offset == 0) { |
| 480 for (int32_t c = 0; c < 10; c++) { | 479 for (int32_t c = 0; c < 10; c++) { |
| 481 if (!std::isdigit(pEntry[c])) | 480 if (!std::isdigit(pEntry[c])) |
| 482 return FALSE; | 481 return FALSE; |
| 483 } | 482 } |
| 484 } | 483 } |
| 485 m_ObjectInfo[objnum].pos = offset; | 484 m_ObjectInfo[objnum].pos = offset; |
| 486 int32_t version = FXSYS_atoi(pEntry + 11); | 485 int32_t version = FXSYS_atoi(pEntry + 11); |
| 487 if (version >= 1) { | 486 if (version >= 1) { |
| 488 m_bVersionUpdated = TRUE; | 487 m_bVersionUpdated = TRUE; |
| 489 } | 488 } |
| 490 m_ObjVersion.SetAtGrow(objnum, version); | 489 m_ObjVersion.SetAtGrow(objnum, version); |
| 491 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen) { | 490 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen) { |
| 492 void* pResult = FXSYS_bsearch( | 491 void* pResult = FXSYS_bsearch( |
| 493 &m_ObjectInfo[objnum].pos, m_SortedOffset.GetData(), | 492 &m_ObjectInfo[objnum].pos, m_SortedOffset.GetData(), |
| 494 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize); | 493 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize); |
| 495 if (!pResult) { | 494 if (!pResult) { |
| 496 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); | 495 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); |
| 497 } | 496 } |
| 498 } | 497 } |
| 499 m_V5Type.SetAtGrow(objnum, 1); | 498 m_ObjectInfo[objnum].type = 1; |
| 500 } | 499 } |
| 501 } | 500 } |
| 502 } | 501 } |
| 503 m_Syntax.RestorePos(SavedPos + count * recordsize); | 502 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 504 return TRUE; | 503 return TRUE; |
| 505 } | 504 } |
| 506 | 505 |
| 507 bool CPDF_Parser::FindPosInOffsets(FX_FILESIZE pos) const { | 506 bool CPDF_Parser::FindPosInOffsets(FX_FILESIZE pos) const { |
| 508 return FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 507 return FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 509 sizeof(FX_FILESIZE), CompareFileSize); | 508 sizeof(FX_FILESIZE), CompareFileSize); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 int32_t nBlocks = count / 1024 + 1; | 547 int32_t nBlocks = count / 1024 + 1; |
| 549 for (int32_t block = 0; block < nBlocks; block++) { | 548 for (int32_t block = 0; block < nBlocks; block++) { |
| 550 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | 549 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
| 551 m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), | 550 m_Syntax.ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), |
| 552 block_size * recordsize); | 551 block_size * recordsize); |
| 553 for (int32_t i = 0; i < block_size; i++) { | 552 for (int32_t i = 0; i < block_size; i++) { |
| 554 FX_DWORD objnum = start_objnum + block * 1024 + i; | 553 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 555 char* pEntry = &buf[i * recordsize]; | 554 char* pEntry = &buf[i * recordsize]; |
| 556 if (pEntry[17] == 'f') { | 555 if (pEntry[17] == 'f') { |
| 557 m_ObjectInfo[objnum].pos = 0; | 556 m_ObjectInfo[objnum].pos = 0; |
| 558 m_V5Type.SetAtGrow(objnum, 0); | 557 m_ObjectInfo[objnum].type = 0; |
| 559 } else { | 558 } else { |
| 560 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); | 559 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); |
| 561 if (offset == 0) { | 560 if (offset == 0) { |
| 562 for (int32_t c = 0; c < 10; c++) { | 561 for (int32_t c = 0; c < 10; c++) { |
| 563 if (!std::isdigit(pEntry[c])) | 562 if (!std::isdigit(pEntry[c])) |
| 564 return false; | 563 return false; |
| 565 } | 564 } |
| 566 } | 565 } |
| 567 m_ObjectInfo[objnum].pos = offset; | 566 m_ObjectInfo[objnum].pos = offset; |
| 568 int32_t version = FXSYS_atoi(pEntry + 11); | 567 int32_t version = FXSYS_atoi(pEntry + 11); |
| 569 if (version >= 1) { | 568 if (version >= 1) { |
| 570 m_bVersionUpdated = TRUE; | 569 m_bVersionUpdated = TRUE; |
| 571 } | 570 } |
| 572 m_ObjVersion.SetAtGrow(objnum, version); | 571 m_ObjVersion.SetAtGrow(objnum, version); |
| 573 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen && | 572 if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen && |
| 574 !FindPosInOffsets(m_ObjectInfo[objnum].pos)) { | 573 !FindPosInOffsets(m_ObjectInfo[objnum].pos)) { |
| 575 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); | 574 m_SortedOffset.Add(m_ObjectInfo[objnum].pos); |
| 576 } | 575 } |
| 577 m_V5Type.SetAtGrow(objnum, 1); | 576 m_ObjectInfo[objnum].type = 1; |
| 578 } | 577 } |
| 579 } | 578 } |
| 580 } | 579 } |
| 581 } | 580 } |
| 582 m_Syntax.RestorePos(SavedPos + count * recordsize); | 581 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 583 } | 582 } |
| 584 return !streampos || LoadCrossRefV5(&streampos, FALSE); | 583 return !streampos || LoadCrossRefV5(&streampos, FALSE); |
| 585 } | 584 } |
| 586 | 585 |
| 587 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { | 586 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 599 return FALSE; | 598 return FALSE; |
| 600 } | 599 } |
| 601 } | 600 } |
| 602 m_ObjectStreamMap.clear(); | 601 m_ObjectStreamMap.clear(); |
| 603 m_bXRefStream = TRUE; | 602 m_bXRefStream = TRUE; |
| 604 return TRUE; | 603 return TRUE; |
| 605 } | 604 } |
| 606 | 605 |
| 607 FX_BOOL CPDF_Parser::RebuildCrossRef() { | 606 FX_BOOL CPDF_Parser::RebuildCrossRef() { |
| 608 m_ObjectInfo.clear(); | 607 m_ObjectInfo.clear(); |
| 609 m_V5Type.RemoveAll(); | |
| 610 m_SortedOffset.RemoveAll(); | 608 m_SortedOffset.RemoveAll(); |
| 611 m_ObjVersion.RemoveAll(); | 609 m_ObjVersion.RemoveAll(); |
| 612 if (m_pTrailer) { | 610 if (m_pTrailer) { |
| 613 m_pTrailer->Release(); | 611 m_pTrailer->Release(); |
| 614 m_pTrailer = NULL; | 612 m_pTrailer = NULL; |
| 615 } | 613 } |
| 616 int32_t status = 0; | 614 int32_t status = 0; |
| 617 int32_t inside_index = 0; | 615 int32_t inside_index = 0; |
| 618 FX_DWORD objnum = 0; | 616 FX_DWORD objnum = 0; |
| 619 FX_DWORD gennum = 0; | 617 FX_DWORD gennum = 0; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 if (pObject) { | 813 if (pObject) { |
| 816 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); | 814 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); |
| 817 m_ObjectInfo[objnum].pos = obj_pos; | 815 m_ObjectInfo[objnum].pos = obj_pos; |
| 818 m_ObjVersion.SetAt(objnum, (int16_t)gennum); | 816 m_ObjVersion.SetAt(objnum, (int16_t)gennum); |
| 819 if (oldgen != gennum) { | 817 if (oldgen != gennum) { |
| 820 m_bVersionUpdated = TRUE; | 818 m_bVersionUpdated = TRUE; |
| 821 } | 819 } |
| 822 } | 820 } |
| 823 } else { | 821 } else { |
| 824 m_ObjectInfo[objnum].pos = obj_pos; | 822 m_ObjectInfo[objnum].pos = obj_pos; |
| 825 m_V5Type.SetAtGrow(objnum, 1); | 823 m_ObjectInfo[objnum].type = 1; |
| 826 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); | 824 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); |
| 827 } | 825 } |
| 828 if (pObject) { | 826 if (pObject) { |
| 829 pObject->Release(); | 827 pObject->Release(); |
| 830 } | 828 } |
| 831 } | 829 } |
| 832 --i; | 830 --i; |
| 833 status = 0; | 831 status = 0; |
| 834 break; | 832 break; |
| 835 } | 833 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 | 1007 |
| 1010 *pos = pStream->GetDict()->GetIntegerBy("Prev"); | 1008 *pos = pStream->GetDict()->GetIntegerBy("Prev"); |
| 1011 int32_t size = pStream->GetDict()->GetIntegerBy("Size"); | 1009 int32_t size = pStream->GetDict()->GetIntegerBy("Size"); |
| 1012 if (size < 0) { | 1010 if (size < 0) { |
| 1013 pStream->Release(); | 1011 pStream->Release(); |
| 1014 return FALSE; | 1012 return FALSE; |
| 1015 } | 1013 } |
| 1016 if (bMainXRef) { | 1014 if (bMainXRef) { |
| 1017 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); | 1015 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); |
| 1018 ShrinkObjectMap(size); | 1016 ShrinkObjectMap(size); |
| 1019 if (m_V5Type.SetSize(size)) { | 1017 for (auto it : m_ObjectInfo) |
| 1020 FXSYS_memset(m_V5Type.GetData(), 0, size); | 1018 it.second.type = 0; |
| 1021 } | |
| 1022 } else { | 1019 } else { |
| 1023 m_Trailers.Add(ToDictionary(pStream->GetDict()->Clone())); | 1020 m_Trailers.Add(ToDictionary(pStream->GetDict()->Clone())); |
| 1024 } | 1021 } |
| 1025 std::vector<std::pair<int32_t, int32_t> > arrIndex; | 1022 std::vector<std::pair<int32_t, int32_t> > arrIndex; |
| 1026 CPDF_Array* pArray = pStream->GetDict()->GetArrayBy("Index"); | 1023 CPDF_Array* pArray = pStream->GetDict()->GetArrayBy("Index"); |
| 1027 if (pArray) { | 1024 if (pArray) { |
| 1028 FX_DWORD nPairSize = pArray->GetCount() / 2; | 1025 FX_DWORD nPairSize = pArray->GetCount() / 2; |
| 1029 for (FX_DWORD i = 0; i < nPairSize; i++) { | 1026 for (FX_DWORD i = 0; i < nPairSize; i++) { |
| 1030 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); | 1027 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); |
| 1031 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); | 1028 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 FX_SAFE_DWORD dwCaculatedSize = segindex; | 1071 FX_SAFE_DWORD dwCaculatedSize = segindex; |
| 1075 dwCaculatedSize += count; | 1072 dwCaculatedSize += count; |
| 1076 dwCaculatedSize *= totalWidth; | 1073 dwCaculatedSize *= totalWidth; |
| 1077 if (!dwCaculatedSize.IsValid() || | 1074 if (!dwCaculatedSize.IsValid() || |
| 1078 dwCaculatedSize.ValueOrDie() > dwTotalSize) { | 1075 dwCaculatedSize.ValueOrDie() > dwTotalSize) { |
| 1079 continue; | 1076 continue; |
| 1080 } | 1077 } |
| 1081 const uint8_t* segstart = pData + segindex * totalWidth; | 1078 const uint8_t* segstart = pData + segindex * totalWidth; |
| 1082 FX_SAFE_DWORD dwMaxObjNum = startnum; | 1079 FX_SAFE_DWORD dwMaxObjNum = startnum; |
| 1083 dwMaxObjNum += count; | 1080 dwMaxObjNum += count; |
| 1084 FX_DWORD dwV5Size = | 1081 FX_DWORD dwV5Size = m_ObjectInfo.empty() ? 0 : GetLastObjNum() + 1; |
| 1085 pdfium::base::checked_cast<FX_DWORD, int32_t>(m_V5Type.GetSize()); | |
| 1086 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { | 1082 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { |
| 1087 continue; | 1083 continue; |
| 1088 } | 1084 } |
| 1089 for (FX_DWORD j = 0; j < count; j++) { | 1085 for (FX_DWORD j = 0; j < count; j++) { |
| 1090 int32_t type = 1; | 1086 int32_t type = 1; |
| 1091 const uint8_t* entrystart = segstart + j * totalWidth; | 1087 const uint8_t* entrystart = segstart + j * totalWidth; |
| 1092 if (WidthArray[0]) { | 1088 if (WidthArray[0]) { |
| 1093 type = GetVarInt(entrystart, WidthArray[0]); | 1089 type = GetVarInt(entrystart, WidthArray[0]); |
| 1094 } | 1090 } |
| 1095 if (m_V5Type[startnum + j] == 255) { | 1091 if (GetObjectType(startnum + j) == 255) { |
| 1096 FX_FILESIZE offset = | 1092 FX_FILESIZE offset = |
| 1097 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); | 1093 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 1098 m_ObjectInfo[startnum + j].pos = offset; | 1094 m_ObjectInfo[startnum + j].pos = offset; |
| 1099 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), | 1095 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1100 m_SortedOffset.GetSize(), | 1096 m_SortedOffset.GetSize(), |
| 1101 sizeof(FX_FILESIZE), CompareFileSize); | 1097 sizeof(FX_FILESIZE), CompareFileSize); |
| 1102 if (!pResult) { | 1098 if (!pResult) { |
| 1103 m_SortedOffset.Add(offset); | 1099 m_SortedOffset.Add(offset); |
| 1104 } | 1100 } |
| 1105 continue; | 1101 continue; |
| 1106 } | 1102 } |
| 1107 if (m_V5Type[startnum + j]) { | 1103 if (GetObjectType(startnum + j)) { |
| 1108 continue; | 1104 continue; |
| 1109 } | 1105 } |
| 1110 m_V5Type[startnum + j] = type; | 1106 m_ObjectInfo[startnum + j].type = type; |
| 1111 if (type == 0) { | 1107 if (type == 0) { |
| 1112 m_ObjectInfo[startnum + j].pos = 0; | 1108 m_ObjectInfo[startnum + j].pos = 0; |
| 1113 } else { | 1109 } else { |
| 1114 FX_FILESIZE offset = | 1110 FX_FILESIZE offset = |
| 1115 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); | 1111 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 1116 m_ObjectInfo[startnum + j].pos = offset; | 1112 m_ObjectInfo[startnum + j].pos = offset; |
| 1117 if (type == 1) { | 1113 if (type == 1) { |
| 1118 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), | 1114 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1119 m_SortedOffset.GetSize(), | 1115 m_SortedOffset.GetSize(), |
| 1120 sizeof(FX_FILESIZE), CompareFileSize); | 1116 sizeof(FX_FILESIZE), CompareFileSize); |
| 1121 if (!pResult) { | 1117 if (!pResult) { |
| 1122 m_SortedOffset.Add(offset); | 1118 m_SortedOffset.Add(offset); |
| 1123 } | 1119 } |
| 1124 } else { | 1120 } else { |
| 1125 if (offset < 0 || offset >= m_V5Type.GetSize()) { | 1121 if (offset < 0 || !IsValidObjectNumber(offset)) { |
| 1126 pStream->Release(); | 1122 pStream->Release(); |
| 1127 return FALSE; | 1123 return FALSE; |
| 1128 } | 1124 } |
| 1129 m_V5Type[offset] = 255; | 1125 m_ObjectInfo[offset].type = 255; |
| 1130 } | 1126 } |
| 1131 } | 1127 } |
| 1132 } | 1128 } |
| 1133 segindex += count; | 1129 segindex += count; |
| 1134 } | 1130 } |
| 1135 pStream->Release(); | 1131 pStream->Release(); |
| 1136 return TRUE; | 1132 return TRUE; |
| 1137 } | 1133 } |
| 1138 CPDF_Array* CPDF_Parser::GetIDArray() { | 1134 CPDF_Array* CPDF_Parser::GetIDArray() { |
| 1139 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement("ID") : NULL; | 1135 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement("ID") : NULL; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1153 } | 1149 } |
| 1154 FX_DWORD CPDF_Parser::GetInfoObjNum() { | 1150 FX_DWORD CPDF_Parser::GetInfoObjNum() { |
| 1155 CPDF_Reference* pRef = | 1151 CPDF_Reference* pRef = |
| 1156 ToReference(m_pTrailer ? m_pTrailer->GetElement("Info") : nullptr); | 1152 ToReference(m_pTrailer ? m_pTrailer->GetElement("Info") : nullptr); |
| 1157 return pRef ? pRef->GetRefObjNum() : 0; | 1153 return pRef ? pRef->GetRefObjNum() : 0; |
| 1158 } | 1154 } |
| 1159 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { | 1155 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { |
| 1160 bForm = FALSE; | 1156 bForm = FALSE; |
| 1161 if (!IsValidObjectNumber(objnum)) | 1157 if (!IsValidObjectNumber(objnum)) |
| 1162 return TRUE; | 1158 return TRUE; |
| 1163 if (m_V5Type[objnum] == 0) | 1159 if (GetObjectType(objnum) == 0) |
| 1164 return TRUE; | 1160 return TRUE; |
| 1165 if (m_V5Type[objnum] == 2) | 1161 if (GetObjectType(objnum) == 2) |
| 1166 return TRUE; | 1162 return TRUE; |
| 1167 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; | 1163 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1168 void* pResult = | 1164 void* pResult = |
| 1169 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 1165 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1170 sizeof(FX_FILESIZE), CompareFileSize); | 1166 sizeof(FX_FILESIZE), CompareFileSize); |
| 1171 if (!pResult) { | 1167 if (!pResult) { |
| 1172 return TRUE; | 1168 return TRUE; |
| 1173 } | 1169 } |
| 1174 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == | 1170 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == |
| 1175 m_SortedOffset.GetSize() - 1) { | 1171 m_SortedOffset.GetSize() - 1) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1189 CPDF_IndirectObjectHolder* pObjList, | 1185 CPDF_IndirectObjectHolder* pObjList, |
| 1190 FX_DWORD objnum) { | 1186 FX_DWORD objnum) { |
| 1191 if (!IsValidObjectNumber(objnum)) | 1187 if (!IsValidObjectNumber(objnum)) |
| 1192 return nullptr; | 1188 return nullptr; |
| 1193 | 1189 |
| 1194 // Prevent circular parsing the same object. | 1190 // Prevent circular parsing the same object. |
| 1195 if (pdfium::ContainsKey(m_ParsingObjNums, objnum)) | 1191 if (pdfium::ContainsKey(m_ParsingObjNums, objnum)) |
| 1196 return nullptr; | 1192 return nullptr; |
| 1197 ScopedSetInsertion<FX_DWORD> local_insert(&m_ParsingObjNums, objnum); | 1193 ScopedSetInsertion<FX_DWORD> local_insert(&m_ParsingObjNums, objnum); |
| 1198 | 1194 |
| 1199 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | 1195 if (GetObjectType(objnum) == 1 || GetObjectType(objnum) == 255) { |
| 1200 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; | 1196 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1201 if (pos <= 0) | 1197 if (pos <= 0) |
| 1202 return nullptr; | 1198 return nullptr; |
| 1203 return ParseIndirectObjectAt(pObjList, pos, objnum); | 1199 return ParseIndirectObjectAt(pObjList, pos, objnum); |
| 1204 } | 1200 } |
| 1205 if (m_V5Type[objnum] != 2) | 1201 if (GetObjectType(objnum) != 2) |
| 1206 return nullptr; | 1202 return nullptr; |
| 1207 | 1203 |
| 1208 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1204 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
| 1209 if (!pObjStream) | 1205 if (!pObjStream) |
| 1210 return nullptr; | 1206 return nullptr; |
| 1211 | 1207 |
| 1212 ScopedFileStream file(FX_CreateMemoryStream( | 1208 ScopedFileStream file(FX_CreateMemoryStream( |
| 1213 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); | 1209 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); |
| 1214 CPDF_SyntaxParser syntax; | 1210 CPDF_SyntaxParser syntax; |
| 1215 syntax.InitParser(file.get(), 0); | 1211 syntax.InitParser(file.get(), 0); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 CPDF_StreamAcc* pStreamAcc = new CPDF_StreamAcc; | 1243 CPDF_StreamAcc* pStreamAcc = new CPDF_StreamAcc; |
| 1248 pStreamAcc->LoadAllData(pStream); | 1244 pStreamAcc->LoadAllData(pStream); |
| 1249 m_ObjectStreamMap[objnum].reset(pStreamAcc); | 1245 m_ObjectStreamMap[objnum].reset(pStreamAcc); |
| 1250 return pStreamAcc; | 1246 return pStreamAcc; |
| 1251 } | 1247 } |
| 1252 | 1248 |
| 1253 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) const { | 1249 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) const { |
| 1254 if (!IsValidObjectNumber(objnum)) | 1250 if (!IsValidObjectNumber(objnum)) |
| 1255 return 0; | 1251 return 0; |
| 1256 | 1252 |
| 1257 if (m_V5Type[objnum] == 2) | 1253 if (GetObjectType(objnum) == 2) |
| 1258 objnum = GetObjectPositionOrZero(objnum); | 1254 objnum = GetObjectPositionOrZero(objnum); |
| 1259 | 1255 |
| 1260 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | 1256 if (GetObjectType(objnum) == 1 || GetObjectType(objnum) == 255) { |
| 1261 FX_FILESIZE offset = GetObjectPositionOrZero(objnum); | 1257 FX_FILESIZE offset = GetObjectPositionOrZero(objnum); |
| 1262 if (offset == 0) | 1258 if (offset == 0) |
| 1263 return 0; | 1259 return 0; |
| 1264 | 1260 |
| 1265 FX_FILESIZE* pResult = static_cast<FX_FILESIZE*>(FXSYS_bsearch( | 1261 FX_FILESIZE* pResult = static_cast<FX_FILESIZE*>(FXSYS_bsearch( |
| 1266 &offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 1262 &offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1267 sizeof(FX_FILESIZE), CompareFileSize)); | 1263 sizeof(FX_FILESIZE), CompareFileSize)); |
| 1268 if (!pResult) | 1264 if (!pResult) |
| 1269 return 0; | 1265 return 0; |
| 1270 | 1266 |
| 1271 if (pResult - m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) | 1267 if (pResult - m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) |
| 1272 return 0; | 1268 return 0; |
| 1273 | 1269 |
| 1274 return pResult[1] - offset; | 1270 return pResult[1] - offset; |
| 1275 } | 1271 } |
| 1276 return 0; | 1272 return 0; |
| 1277 } | 1273 } |
| 1278 | 1274 |
| 1279 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, | 1275 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, |
| 1280 uint8_t*& pBuffer, | 1276 uint8_t*& pBuffer, |
| 1281 FX_DWORD& size) { | 1277 FX_DWORD& size) { |
| 1282 pBuffer = NULL; | 1278 pBuffer = NULL; |
| 1283 size = 0; | 1279 size = 0; |
| 1284 if (!IsValidObjectNumber(objnum)) | 1280 if (!IsValidObjectNumber(objnum)) |
| 1285 return; | 1281 return; |
| 1286 | 1282 |
| 1287 if (m_V5Type[objnum] == 2) { | 1283 if (GetObjectType(objnum) == 2) { |
| 1288 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1284 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
| 1289 if (!pObjStream) | 1285 if (!pObjStream) |
| 1290 return; | 1286 return; |
| 1291 | 1287 |
| 1292 int32_t offset = GetStreamFirst(pObjStream); | 1288 int32_t offset = GetStreamFirst(pObjStream); |
| 1293 const uint8_t* pData = pObjStream->GetData(); | 1289 const uint8_t* pData = pObjStream->GetData(); |
| 1294 FX_DWORD totalsize = pObjStream->GetSize(); | 1290 FX_DWORD totalsize = pObjStream->GetSize(); |
| 1295 ScopedFileStream file( | 1291 ScopedFileStream file( |
| 1296 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); | 1292 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); |
| 1297 CPDF_SyntaxParser syntax; | 1293 CPDF_SyntaxParser syntax; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1309 FX_DWORD nextoff = syntax.GetDirectNum(); | 1305 FX_DWORD nextoff = syntax.GetDirectNum(); |
| 1310 size = nextoff - thisoff; | 1306 size = nextoff - thisoff; |
| 1311 } | 1307 } |
| 1312 pBuffer = FX_Alloc(uint8_t, size); | 1308 pBuffer = FX_Alloc(uint8_t, size); |
| 1313 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); | 1309 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); |
| 1314 return; | 1310 return; |
| 1315 } | 1311 } |
| 1316 return; | 1312 return; |
| 1317 } | 1313 } |
| 1318 | 1314 |
| 1319 if (m_V5Type[objnum] != 1) | 1315 if (GetObjectType(objnum) != 1) |
| 1320 return; | 1316 return; |
| 1321 | 1317 |
| 1322 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; | 1318 FX_FILESIZE pos = m_ObjectInfo[objnum].pos; |
| 1323 if (pos == 0) { | 1319 if (pos == 0) { |
| 1324 return; | 1320 return; |
| 1325 } | 1321 } |
| 1326 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1322 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1327 m_Syntax.RestorePos(pos); | 1323 m_Syntax.RestorePos(pos); |
| 1328 bool bIsNumber; | 1324 bool bIsNumber; |
| 1329 CFX_ByteString word = m_Syntax.GetNextWord(&bIsNumber); | 1325 CFX_ByteString word = m_Syntax.GetNextWord(&bIsNumber); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 bXRefRebuilt = TRUE; | 1562 bXRefRebuilt = TRUE; |
| 1567 m_LastXRefOffset = 0; | 1563 m_LastXRefOffset = 0; |
| 1568 } | 1564 } |
| 1569 if (bLoadV4) { | 1565 if (bLoadV4) { |
| 1570 m_pTrailer = LoadTrailerV4(); | 1566 m_pTrailer = LoadTrailerV4(); |
| 1571 if (!m_pTrailer) { | 1567 if (!m_pTrailer) { |
| 1572 return SUCCESS; | 1568 return SUCCESS; |
| 1573 } | 1569 } |
| 1574 | 1570 |
| 1575 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1571 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 1576 if (xrefsize > 0) { | 1572 if (xrefsize > 0) |
| 1577 ShrinkObjectMap(xrefsize); | 1573 ShrinkObjectMap(xrefsize); |
| 1578 m_V5Type.SetSize(xrefsize); | |
| 1579 } | |
| 1580 } | 1574 } |
| 1581 Error eRet = SetEncryptHandler(); | 1575 Error eRet = SetEncryptHandler(); |
| 1582 if (eRet != SUCCESS) { | 1576 if (eRet != SUCCESS) { |
| 1583 return eRet; | 1577 return eRet; |
| 1584 } | 1578 } |
| 1585 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); | 1579 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); |
| 1586 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { | 1580 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { |
| 1587 if (bXRefRebuilt) { | 1581 if (bXRefRebuilt) { |
| 1588 return FORMAT_ERROR; | 1582 return FORMAT_ERROR; |
| 1589 } | 1583 } |
| (...skipping 3268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4858 if (!m_pLinearizedDict) | 4852 if (!m_pLinearizedDict) |
| 4859 return -1; | 4853 return -1; |
| 4860 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); | 4854 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); |
| 4861 if (!pRange) | 4855 if (!pRange) |
| 4862 return -1; | 4856 return -1; |
| 4863 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4857 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4864 if (!pStreamLen) | 4858 if (!pStreamLen) |
| 4865 return -1; | 4859 return -1; |
| 4866 return pStreamLen->GetInteger(); | 4860 return pStreamLen->GetInteger(); |
| 4867 } | 4861 } |
| OLD | NEW |