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> |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 m_V5Type.SetAtGrow(objnum, 1); | 575 m_V5Type.SetAtGrow(objnum, 1); |
576 } | 576 } |
577 if (bFirstBlock) { | 577 if (bFirstBlock) { |
578 bFirstBlock = FALSE; | 578 bFirstBlock = FALSE; |
579 } | 579 } |
580 } | 580 } |
581 } | 581 } |
582 } | 582 } |
583 m_Syntax.RestorePos(SavedPos + count * recordsize); | 583 m_Syntax.RestorePos(SavedPos + count * recordsize); |
584 } | 584 } |
585 return !streampos || LoadCrossRefV5(streampos, streampos, FALSE); | 585 return !streampos || LoadCrossRefV5(&streampos, FALSE); |
586 } | 586 } |
587 | 587 |
588 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { | 588 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { |
589 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { | 589 if (!LoadCrossRefV5(&xrefpos, TRUE)) { |
590 return FALSE; | 590 return FALSE; |
591 } | 591 } |
592 while (xrefpos) | 592 std::set<FX_FILESIZE> seen_xrefpos; |
593 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 593 while (xrefpos) { |
| 594 seen_xrefpos.insert(xrefpos); |
| 595 if (!LoadCrossRefV5(&xrefpos, FALSE)) { |
594 return FALSE; | 596 return FALSE; |
595 } | 597 } |
| 598 // Check for circular references. |
| 599 if (seen_xrefpos.find(xrefpos) != seen_xrefpos.end()) { |
| 600 return FALSE; |
| 601 } |
| 602 } |
596 m_ObjectStreamMap.InitHashTable(101, FALSE); | 603 m_ObjectStreamMap.InitHashTable(101, FALSE); |
597 m_bXRefStream = TRUE; | 604 m_bXRefStream = TRUE; |
598 return TRUE; | 605 return TRUE; |
599 } | 606 } |
| 607 |
600 FX_BOOL CPDF_Parser::RebuildCrossRef() { | 608 FX_BOOL CPDF_Parser::RebuildCrossRef() { |
601 m_CrossRef.RemoveAll(); | 609 m_CrossRef.RemoveAll(); |
602 m_V5Type.RemoveAll(); | 610 m_V5Type.RemoveAll(); |
603 m_SortedOffset.RemoveAll(); | 611 m_SortedOffset.RemoveAll(); |
604 m_ObjVersion.RemoveAll(); | 612 m_ObjVersion.RemoveAll(); |
605 if (m_pTrailer) { | 613 if (m_pTrailer) { |
606 m_pTrailer->Release(); | 614 m_pTrailer->Release(); |
607 m_pTrailer = NULL; | 615 m_pTrailer = NULL; |
608 } | 616 } |
609 int32_t status = 0; | 617 int32_t status = 0; |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 void* pResult = | 976 void* pResult = |
969 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 977 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
970 sizeof(FX_FILESIZE), CompareFileSize); | 978 sizeof(FX_FILESIZE), CompareFileSize); |
971 if (pResult == NULL) { | 979 if (pResult == NULL) { |
972 m_SortedOffset.Add(offset); | 980 m_SortedOffset.Add(offset); |
973 } | 981 } |
974 FX_Free(buffer); | 982 FX_Free(buffer); |
975 return m_pTrailer && m_CrossRef.GetSize() > 0; | 983 return m_pTrailer && m_CrossRef.GetSize() > 0; |
976 } | 984 } |
977 | 985 |
978 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, | 986 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
979 FX_FILESIZE& prev, | 987 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); |
980 FX_BOOL bMainXRef) { | |
981 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, pos, 0, nullptr); | |
982 if (!pObject) | 988 if (!pObject) |
983 return FALSE; | 989 return FALSE; |
984 | 990 |
985 if (m_pDocument) { | 991 if (m_pDocument) { |
986 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 992 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
987 if (!pDict || pDict->GetObjNum() != pObject->m_ObjNum) { | 993 if (!pDict || pDict->GetObjNum() != pObject->m_ObjNum) { |
988 m_pDocument->InsertIndirectObject(pObject->m_ObjNum, pObject); | 994 m_pDocument->InsertIndirectObject(pObject->m_ObjNum, pObject); |
989 } else { | 995 } else { |
990 if (pObject->IsStream()) | 996 if (pObject->IsStream()) |
991 pObject->Release(); | 997 pObject->Release(); |
992 return FALSE; | 998 return FALSE; |
993 } | 999 } |
994 } | 1000 } |
995 | 1001 |
996 CPDF_Stream* pStream = pObject->AsStream(); | 1002 CPDF_Stream* pStream = pObject->AsStream(); |
997 if (!pStream) | 1003 if (!pStream) |
998 return FALSE; | 1004 return FALSE; |
999 | 1005 |
1000 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); | 1006 *pos = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); |
1001 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); | 1007 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); |
1002 if (size < 0) { | 1008 if (size < 0) { |
1003 pStream->Release(); | 1009 pStream->Release(); |
1004 return FALSE; | 1010 return FALSE; |
1005 } | 1011 } |
1006 if (bMainXRef) { | 1012 if (bMainXRef) { |
1007 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); | 1013 m_pTrailer = ToDictionary(pStream->GetDict()->Clone()); |
1008 m_CrossRef.SetSize(size); | 1014 m_CrossRef.SetSize(size); |
1009 if (m_V5Type.SetSize(size)) { | 1015 if (m_V5Type.SetSize(size)) { |
1010 FXSYS_memset(m_V5Type.GetData(), 0, size); | 1016 FXSYS_memset(m_V5Type.GetData(), 0, size); |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 m_Syntax.m_pFileAccess = NULL; | 1562 m_Syntax.m_pFileAccess = NULL; |
1557 return StartParse(pFileAccess, bReParse, bOwnFileRead); | 1563 return StartParse(pFileAccess, bReParse, bOwnFileRead); |
1558 } | 1564 } |
1559 if (!bReParse) { | 1565 if (!bReParse) { |
1560 m_pDocument = new CPDF_Document(this); | 1566 m_pDocument = new CPDF_Document(this); |
1561 } | 1567 } |
1562 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); | 1568 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); |
1563 FX_BOOL bXRefRebuilt = FALSE; | 1569 FX_BOOL bXRefRebuilt = FALSE; |
1564 FX_BOOL bLoadV4 = FALSE; | 1570 FX_BOOL bLoadV4 = FALSE; |
1565 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && | 1571 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && |
1566 !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { | 1572 !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
1567 if (!RebuildCrossRef()) { | 1573 if (!RebuildCrossRef()) { |
1568 return PDFPARSE_ERROR_FORMAT; | 1574 return PDFPARSE_ERROR_FORMAT; |
1569 } | 1575 } |
1570 bXRefRebuilt = TRUE; | 1576 bXRefRebuilt = TRUE; |
1571 m_LastXRefOffset = 0; | 1577 m_LastXRefOffset = 0; |
1572 } | 1578 } |
1573 if (bLoadV4) { | 1579 if (bLoadV4) { |
1574 m_pTrailer = LoadTrailerV4(); | 1580 m_pTrailer = LoadTrailerV4(); |
1575 if (m_pTrailer == NULL) { | 1581 if (m_pTrailer == NULL) { |
1576 return FALSE; | 1582 return FALSE; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 } | 1622 } |
1617 } | 1623 } |
1618 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { | 1624 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { |
1619 if (CPDF_Reference* pMetadata = ToReference( | 1625 if (CPDF_Reference* pMetadata = ToReference( |
1620 m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")))) | 1626 m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")))) |
1621 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); | 1627 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); |
1622 } | 1628 } |
1623 return PDFPARSE_ERROR_SUCCESS; | 1629 return PDFPARSE_ERROR_SUCCESS; |
1624 } | 1630 } |
1625 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { | 1631 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { |
1626 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 1632 if (!LoadCrossRefV5(&xrefpos, FALSE)) { |
1627 return FALSE; | 1633 return FALSE; |
1628 } | 1634 } |
1629 while (xrefpos) | 1635 std::set<FX_FILESIZE> seen_xrefpos; |
1630 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 1636 while (xrefpos) { |
| 1637 seen_xrefpos.insert(xrefpos); |
| 1638 if (!LoadCrossRefV5(&xrefpos, FALSE)) { |
1631 return FALSE; | 1639 return FALSE; |
1632 } | 1640 } |
| 1641 // Check for circular references. |
| 1642 if (seen_xrefpos.find(xrefpos) != seen_xrefpos.end()) { |
| 1643 return FALSE; |
| 1644 } |
| 1645 } |
1633 m_ObjectStreamMap.InitHashTable(101, FALSE); | 1646 m_ObjectStreamMap.InitHashTable(101, FALSE); |
1634 m_bXRefStream = TRUE; | 1647 m_bXRefStream = TRUE; |
1635 return TRUE; | 1648 return TRUE; |
1636 } | 1649 } |
1637 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() { | 1650 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() { |
1638 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; | 1651 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; |
1639 m_Syntax.m_MetadataObjnum = 0; | 1652 m_Syntax.m_MetadataObjnum = 0; |
1640 if (m_pTrailer) { | 1653 if (m_pTrailer) { |
1641 m_pTrailer->Release(); | 1654 m_pTrailer->Release(); |
1642 m_pTrailer = NULL; | 1655 m_pTrailer = NULL; |
(...skipping 3294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4937 if (!m_pLinearizedDict) | 4950 if (!m_pLinearizedDict) |
4938 return -1; | 4951 return -1; |
4939 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | 4952 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
4940 if (!pRange) | 4953 if (!pRange) |
4941 return -1; | 4954 return -1; |
4942 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4955 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
4943 if (!pStreamLen) | 4956 if (!pStreamLen) |
4944 return -1; | 4957 return -1; |
4945 return pStreamLen->GetInteger(); | 4958 return pStreamLen->GetInteger(); |
4946 } | 4959 } |
OLD | NEW |