| 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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } | 353 } |
| 354 | 354 |
| 355 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 355 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 356 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { | 356 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) { |
| 357 return FALSE; | 357 return FALSE; |
| 358 } | 358 } |
| 359 m_pTrailer = LoadTrailerV4(); | 359 m_pTrailer = LoadTrailerV4(); |
| 360 if (!m_pTrailer) { | 360 if (!m_pTrailer) { |
| 361 return FALSE; | 361 return FALSE; |
| 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 return FALSE; | 366 return FALSE; |
| 366 } | 367 } |
| 367 m_ObjectInfo[0].pos = 0; | 368 m_ObjectInfo[0].pos = 0; |
| 368 m_V5Type.SetSize(xrefsize); | 369 m_V5Type.SetSize(xrefsize); |
| 369 CFX_FileSizeArray CrossRefList, XRefStreamList; | 370 CFX_FileSizeArray CrossRefList; |
| 371 CFX_FileSizeArray XRefStreamList; |
| 370 CrossRefList.Add(xrefpos); | 372 CrossRefList.Add(xrefpos); |
| 371 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); | 373 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); |
| 372 | 374 |
| 373 std::set<FX_FILESIZE> seen_xrefpos; | 375 std::set<FX_FILESIZE> seen_xrefpos; |
| 374 seen_xrefpos.insert(xrefpos); | 376 seen_xrefpos.insert(xrefpos); |
| 375 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not | 377 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not |
| 376 // numerical, GetDirectInteger() returns 0. Loading will end. | 378 // numerical, GetDirectInteger() returns 0. Loading will end. |
| 377 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 379 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
| 378 while (xrefpos) { | 380 while (xrefpos) { |
| 379 // Check for circular references. | 381 // Check for circular references. |
| (...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 } | 1411 } |
| 1410 CPDF_Object* pObj = | 1412 CPDF_Object* pObj = |
| 1411 m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext, true); | 1413 m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext, true); |
| 1412 m_Syntax.SavePos(); | 1414 m_Syntax.SavePos(); |
| 1413 CFX_ByteString bsWord = m_Syntax.GetKeyword(); | 1415 CFX_ByteString bsWord = m_Syntax.GetKeyword(); |
| 1414 if (bsWord == "endobj") { | 1416 if (bsWord == "endobj") { |
| 1415 m_Syntax.SavePos(); | 1417 m_Syntax.SavePos(); |
| 1416 } | 1418 } |
| 1417 m_Syntax.RestorePos(SavedPos); | 1419 m_Syntax.RestorePos(SavedPos); |
| 1418 if (pObj) { | 1420 if (pObj) { |
| 1419 if (!objnum) { | 1421 if (!objnum) |
| 1420 pObj->m_ObjNum = parser_objnum; | 1422 pObj->m_ObjNum = parser_objnum; |
| 1421 } | |
| 1422 pObj->m_GenNum = parser_gennum; | 1423 pObj->m_GenNum = parser_gennum; |
| 1423 } | 1424 } |
| 1424 return pObj; | 1425 return pObj; |
| 1425 } | 1426 } |
| 1426 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( | 1427 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( |
| 1427 CPDF_IndirectObjects* pObjList, | 1428 CPDF_IndirectObjects* pObjList, |
| 1428 FX_FILESIZE pos, | 1429 FX_FILESIZE pos, |
| 1429 FX_DWORD objnum, | 1430 FX_DWORD objnum, |
| 1430 PARSE_CONTEXT* pContext, | 1431 PARSE_CONTEXT* pContext, |
| 1431 FX_FILESIZE* pResultPos) { | 1432 FX_FILESIZE* pResultPos) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1576 !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
| 1576 if (!RebuildCrossRef()) { | 1577 if (!RebuildCrossRef()) { |
| 1577 return PDFPARSE_ERROR_FORMAT; | 1578 return PDFPARSE_ERROR_FORMAT; |
| 1578 } | 1579 } |
| 1579 bXRefRebuilt = TRUE; | 1580 bXRefRebuilt = TRUE; |
| 1580 m_LastXRefOffset = 0; | 1581 m_LastXRefOffset = 0; |
| 1581 } | 1582 } |
| 1582 if (bLoadV4) { | 1583 if (bLoadV4) { |
| 1583 m_pTrailer = LoadTrailerV4(); | 1584 m_pTrailer = LoadTrailerV4(); |
| 1584 if (!m_pTrailer) { | 1585 if (!m_pTrailer) { |
| 1585 return FALSE; | 1586 return PDFPARSE_ERROR_SUCCESS; |
| 1586 } | 1587 } |
| 1588 |
| 1587 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1589 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 1588 if (xrefsize > 0) { | 1590 if (xrefsize > 0) { |
| 1589 m_ObjectInfo[0].pos = 0; | 1591 m_ObjectInfo[0].pos = 0; |
| 1590 m_V5Type.SetSize(xrefsize); | 1592 m_V5Type.SetSize(xrefsize); |
| 1591 } | 1593 } |
| 1592 } | 1594 } |
| 1593 FX_DWORD dwRet = SetEncryptHandler(); | 1595 FX_DWORD dwRet = SetEncryptHandler(); |
| 1594 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1596 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 1595 return dwRet; | 1597 return dwRet; |
| 1596 } | 1598 } |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2752 CPDF_IndirectObjects* pObjList = NULL); | 2754 CPDF_IndirectObjects* pObjList = NULL); |
| 2753 CPDF_Object* GetObject(FX_DWORD objnum, | 2755 CPDF_Object* GetObject(FX_DWORD objnum, |
| 2754 IFX_DownloadHints* pHints, | 2756 IFX_DownloadHints* pHints, |
| 2755 FX_BOOL* pExistInFile); | 2757 FX_BOOL* pExistInFile); |
| 2756 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); | 2758 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); |
| 2757 FX_BOOL PreparePageItem(); | 2759 FX_BOOL PreparePageItem(); |
| 2758 FX_BOOL LoadPages(IFX_DownloadHints* pHints); | 2760 FX_BOOL LoadPages(IFX_DownloadHints* pHints); |
| 2759 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); | 2761 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); |
| 2760 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); | 2762 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); |
| 2761 int32_t CheckLinearizedData(IFX_DownloadHints* pHints); | 2763 int32_t CheckLinearizedData(IFX_DownloadHints* pHints); |
| 2762 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); | |
| 2763 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); | 2764 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); |
| 2764 | 2765 |
| 2765 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); | 2766 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); |
| 2766 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); | 2767 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); |
| 2767 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); | 2768 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); |
| 2768 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); | 2769 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); |
| 2769 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); | 2770 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); |
| 2770 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, | 2771 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, |
| 2771 int32_t iPage, | 2772 int32_t iPage, |
| 2772 int32_t& iCount, | 2773 int32_t& iCount, |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4289 FX_SAFE_DWORD data_size = m_dwFileLen; | 4290 FX_SAFE_DWORD data_size = m_dwFileLen; |
| 4290 data_size -= m_dwLastXRefOffset; | 4291 data_size -= m_dwLastXRefOffset; |
| 4291 if (!data_size.IsValid()) { | 4292 if (!data_size.IsValid()) { |
| 4292 return DataError; | 4293 return DataError; |
| 4293 } | 4294 } |
| 4294 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, | 4295 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, |
| 4295 data_size.ValueOrDie())) { | 4296 data_size.ValueOrDie())) { |
| 4296 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); | 4297 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); |
| 4297 return DataNotAvailable; | 4298 return DataNotAvailable; |
| 4298 } | 4299 } |
| 4299 FX_DWORD dwRet = (m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); | 4300 FX_DWORD dwRet = m_pDocument->GetParser()->LoadLinearizedMainXRefTable(); |
| 4300 m_bMainXRefLoadTried = TRUE; | 4301 m_bMainXRefLoadTried = TRUE; |
| 4301 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 4302 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 4302 return DataError; | 4303 return DataError; |
| 4303 } | 4304 } |
| 4304 if (!PreparePageItem()) { | 4305 if (!PreparePageItem()) { |
| 4305 return DataNotAvailable; | 4306 return DataNotAvailable; |
| 4306 } | 4307 } |
| 4307 m_bMainXRefLoadedOK = TRUE; | 4308 m_bMainXRefLoadedOK = TRUE; |
| 4308 m_bLinearedDataOK = TRUE; | 4309 m_bLinearedDataOK = TRUE; |
| 4309 } | 4310 } |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4922 // If two objects have the same offset, it should be treated as an error. | 4923 // If two objects have the same offset, it should be treated as an error. |
| 4923 if (!dwLength) | 4924 if (!dwLength) |
| 4924 return IPDF_DataAvail::DataError; | 4925 return IPDF_DataAvail::DataError; |
| 4925 if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, | 4926 if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, |
| 4926 pHints)) { | 4927 pHints)) { |
| 4927 return IPDF_DataAvail::DataNotAvailable; | 4928 return IPDF_DataAvail::DataNotAvailable; |
| 4928 } | 4929 } |
| 4929 } | 4930 } |
| 4930 return IPDF_DataAvail::DataAvailable; | 4931 return IPDF_DataAvail::DataAvailable; |
| 4931 } | 4932 } |
| 4933 |
| 4932 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { | 4934 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
| 4933 if (!pHintStream || !m_pLinearizedDict) | 4935 if (!pHintStream || !m_pLinearizedDict) |
| 4934 return FALSE; | 4936 return FALSE; |
| 4935 CPDF_Dictionary* pDict = pHintStream->GetDict(); | 4937 CPDF_Dictionary* pDict = pHintStream->GetDict(); |
| 4936 CPDF_Object* pOffset = pDict ? pDict->GetElement("S") : nullptr; | 4938 CPDF_Object* pOffset = pDict ? pDict->GetElement("S") : nullptr; |
| 4937 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) | 4939 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) |
| 4938 return FALSE; | 4940 return FALSE; |
| 4939 int shared_hint_table_offset = pOffset->GetInteger(); | 4941 int shared_hint_table_offset = pOffset->GetInteger(); |
| 4940 CPDF_StreamAcc acc; | 4942 CPDF_StreamAcc acc; |
| 4941 acc.LoadAllData(pHintStream); | 4943 acc.LoadAllData(pHintStream); |
| 4942 FX_DWORD size = acc.GetSize(); | 4944 FX_DWORD size = acc.GetSize(); |
| 4943 // The header section of page offset hint table is 36 bytes. | 4945 // The header section of page offset hint table is 36 bytes. |
| 4944 // The header section of shared object hint table is 24 bytes. | 4946 // The header section of shared object hint table is 24 bytes. |
| 4945 // Hint table has at least 60 bytes. | 4947 // Hint table has at least 60 bytes. |
| 4946 const FX_DWORD MIN_STREAM_LEN = 60; | 4948 const FX_DWORD MIN_STREAM_LEN = 60; |
| 4947 if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || | 4949 if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || |
| 4948 size < shared_hint_table_offset) { | 4950 size < shared_hint_table_offset) { |
| 4949 return FALSE; | 4951 return FALSE; |
| 4950 } | 4952 } |
| 4951 CFX_BitStream bs; | 4953 CFX_BitStream bs; |
| 4952 bs.Init(acc.GetData(), size); | 4954 bs.Init(acc.GetData(), size); |
| 4953 return ReadPageHintTable(&bs) && | 4955 return ReadPageHintTable(&bs) && |
| 4954 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( | 4956 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( |
| 4955 shared_hint_table_offset)); | 4957 shared_hint_table_offset)); |
| 4956 } | 4958 } |
| 4959 |
| 4957 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { | 4960 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
| 4958 if (!m_pLinearizedDict) | 4961 if (!m_pLinearizedDict) |
| 4959 return -1; | 4962 return -1; |
| 4960 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4963 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4961 if (!pRange) | 4964 if (!pRange) |
| 4962 return -1; | 4965 return -1; |
| 4963 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); | 4966 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); |
| 4964 if (!pStreamOffset) | 4967 if (!pStreamOffset) |
| 4965 return -1; | 4968 return -1; |
| 4966 return pStreamOffset->GetInteger(); | 4969 return pStreamOffset->GetInteger(); |
| 4967 } | 4970 } |
| 4968 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { | 4971 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { |
| 4969 if (!m_pLinearizedDict) | 4972 if (!m_pLinearizedDict) |
| 4970 return -1; | 4973 return -1; |
| 4971 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4974 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4972 if (!pRange) | 4975 if (!pRange) |
| 4973 return -1; | 4976 return -1; |
| 4974 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4977 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4975 if (!pStreamLen) | 4978 if (!pStreamLen) |
| 4976 return -1; | 4979 return -1; |
| 4977 return pStreamLen->GetInteger(); | 4980 return pStreamLen->GetInteger(); |
| 4978 } | 4981 } |
| OLD | NEW |