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 |