| OLD | NEW |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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/fpdfapi/fpdf_parser/include/cpdf_parser.h" | 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 return pObjStream->GetDict()->GetIntegerBy("N"); | 44 return pObjStream->GetDict()->GetIntegerBy("N"); |
| 45 } | 45 } |
| 46 | 46 |
| 47 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { | 47 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { |
| 48 return pObjStream->GetDict()->GetIntegerBy("First"); | 48 return pObjStream->GetDict()->GetIntegerBy("First"); |
| 49 } | 49 } |
| 50 | 50 |
| 51 } // namespace | 51 } // namespace |
| 52 | 52 |
| 53 CPDF_Parser::CPDF_Parser() | 53 CPDF_Parser::CPDF_Parser() |
| 54 : m_pDocument(nullptr), | 54 : m_bOwnFileRead(true), |
| 55 m_bOwnFileRead(true), | |
| 56 m_FileVersion(0), | 55 m_FileVersion(0), |
| 57 m_pTrailer(nullptr), | 56 m_pTrailer(nullptr), |
| 58 m_pEncryptDict(nullptr), | 57 m_pEncryptDict(nullptr), |
| 59 m_bVersionUpdated(false), | 58 m_bVersionUpdated(false), |
| 60 m_pLinearized(nullptr), | 59 m_pLinearized(nullptr), |
| 61 m_dwFirstPageNo(0), | 60 m_dwFirstPageNo(0), |
| 62 m_dwXrefStartObjNum(0) { | 61 m_dwXrefStartObjNum(0) { |
| 63 m_pSyntax.reset(new CPDF_SyntaxParser); | 62 m_pSyntax.reset(new CPDF_SyntaxParser); |
| 64 } | 63 } |
| 65 | 64 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 auto saved_it = it++; | 119 auto saved_it = it++; |
| 121 m_ObjectInfo.erase(saved_it); | 120 m_ObjectInfo.erase(saved_it); |
| 122 } | 121 } |
| 123 | 122 |
| 124 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) | 123 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) |
| 125 m_ObjectInfo[objnum - 1].pos = 0; | 124 m_ObjectInfo[objnum - 1].pos = 0; |
| 126 } | 125 } |
| 127 | 126 |
| 128 void CPDF_Parser::CloseParser() { | 127 void CPDF_Parser::CloseParser() { |
| 129 m_bVersionUpdated = false; | 128 m_bVersionUpdated = false; |
| 130 delete m_pDocument; | 129 m_pDocument.reset(); |
| 131 m_pDocument = nullptr; | |
| 132 | 130 |
| 133 if (m_pTrailer) { | 131 if (m_pTrailer) { |
| 134 m_pTrailer->Release(); | 132 m_pTrailer->Release(); |
| 135 m_pTrailer = nullptr; | 133 m_pTrailer = nullptr; |
| 136 } | 134 } |
| 137 ReleaseEncryptHandler(); | 135 ReleaseEncryptHandler(); |
| 138 SetEncryptDictionary(nullptr); | 136 SetEncryptDictionary(nullptr); |
| 139 | 137 |
| 140 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { | 138 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { |
| 141 m_pSyntax->m_pFileAccess->Release(); | 139 m_pSyntax->m_pFileAccess->Release(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 181 |
| 184 if (!m_pSyntax->GetCharAt(7, ch)) | 182 if (!m_pSyntax->GetCharAt(7, ch)) |
| 185 return FORMAT_ERROR; | 183 return FORMAT_ERROR; |
| 186 if (std::isdigit(ch)) | 184 if (std::isdigit(ch)) |
| 187 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 185 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
| 188 | 186 |
| 189 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) | 187 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) |
| 190 return FORMAT_ERROR; | 188 return FORMAT_ERROR; |
| 191 | 189 |
| 192 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); | 190 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); |
| 193 m_pDocument = new CPDF_Document(this); | 191 m_pDocument.reset(new CPDF_Document(this)); |
| 194 | 192 |
| 195 FX_BOOL bXRefRebuilt = FALSE; | 193 FX_BOOL bXRefRebuilt = FALSE; |
| 196 if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) { | 194 if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) { |
| 197 m_SortedOffset.insert(m_pSyntax->SavePos()); | 195 m_SortedOffset.insert(m_pSyntax->SavePos()); |
| 198 m_pSyntax->GetKeyword(); | 196 m_pSyntax->GetKeyword(); |
| 199 | 197 |
| 200 bool bNumber; | 198 bool bNumber; |
| 201 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); | 199 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); |
| 202 if (!bNumber) | 200 if (!bNumber) |
| 203 return FORMAT_ERROR; | 201 return FORMAT_ERROR; |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 inside_index++; | 756 inside_index++; |
| 759 } | 757 } |
| 760 break; | 758 break; |
| 761 case 3: | 759 case 3: |
| 762 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 760 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
| 763 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; | 761 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; |
| 764 m_SortedOffset.insert(obj_pos); | 762 m_SortedOffset.insert(obj_pos); |
| 765 last_obj = start_pos; | 763 last_obj = start_pos; |
| 766 FX_FILESIZE obj_end = 0; | 764 FX_FILESIZE obj_end = 0; |
| 767 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( | 765 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( |
| 768 m_pDocument, obj_pos, objnum, &obj_end); | 766 m_pDocument.get(), obj_pos, objnum, &obj_end); |
| 769 if (CPDF_Stream* pStream = ToStream(pObject)) { | 767 if (CPDF_Stream* pStream = ToStream(pObject)) { |
| 770 if (CPDF_Dictionary* pDict = pStream->GetDict()) { | 768 if (CPDF_Dictionary* pDict = pStream->GetDict()) { |
| 771 if ((pDict->KeyExist("Type")) && | 769 if ((pDict->KeyExist("Type")) && |
| 772 (pDict->GetStringBy("Type") == "XRef" && | 770 (pDict->GetStringBy("Type") == "XRef" && |
| 773 pDict->KeyExist("Size"))) { | 771 pDict->KeyExist("Size"))) { |
| 774 CPDF_Object* pRoot = pDict->GetObjectBy("Root"); | 772 CPDF_Object* pRoot = pDict->GetObjectBy("Root"); |
| 775 if (pRoot && pRoot->GetDict() && | 773 if (pRoot && pRoot->GetDict() && |
| 776 pRoot->GetDict()->GetObjectBy("Pages")) { | 774 pRoot->GetDict()->GetObjectBy("Pages")) { |
| 777 if (m_pTrailer) | 775 if (m_pTrailer) |
| 778 m_pTrailer->Release(); | 776 m_pTrailer->Release(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 break; | 819 break; |
| 822 } | 820 } |
| 823 break; | 821 break; |
| 824 | 822 |
| 825 case ParserState::kTrailer: | 823 case ParserState::kTrailer: |
| 826 if (inside_index == 7) { | 824 if (inside_index == 7) { |
| 827 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 825 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
| 828 last_trailer = pos + i - 7; | 826 last_trailer = pos + i - 7; |
| 829 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); | 827 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); |
| 830 | 828 |
| 831 CPDF_Object* pObj = m_pSyntax->GetObject(m_pDocument, 0, 0, true); | 829 CPDF_Object* pObj = |
| 830 m_pSyntax->GetObject(m_pDocument.get(), 0, 0, true); |
| 832 if (pObj) { | 831 if (pObj) { |
| 833 if (!pObj->IsDictionary() && !pObj->AsStream()) { | 832 if (!pObj->IsDictionary() && !pObj->AsStream()) { |
| 834 pObj->Release(); | 833 pObj->Release(); |
| 835 } else { | 834 } else { |
| 836 CPDF_Stream* pStream = pObj->AsStream(); | 835 CPDF_Stream* pStream = pObj->AsStream(); |
| 837 if (CPDF_Dictionary* pTrailer = | 836 if (CPDF_Dictionary* pTrailer = |
| 838 pStream ? pStream->GetDict() : pObj->AsDictionary()) { | 837 pStream ? pStream->GetDict() : pObj->AsDictionary()) { |
| 839 if (m_pTrailer) { | 838 if (m_pTrailer) { |
| 840 CPDF_Object* pRoot = pTrailer->GetObjectBy("Root"); | 839 CPDF_Object* pRoot = pTrailer->GetObjectBy("Root"); |
| 841 CPDF_Reference* pRef = ToReference(pRoot); | 840 CPDF_Reference* pRef = ToReference(pRoot); |
| 842 if (!pRoot || | 841 if (!pRoot || |
| 843 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && | 842 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && |
| 844 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { | 843 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { |
| 845 auto it = pTrailer->begin(); | 844 auto it = pTrailer->begin(); |
| 846 while (it != pTrailer->end()) { | 845 while (it != pTrailer->end()) { |
| 847 const CFX_ByteString& key = it->first; | 846 const CFX_ByteString& key = it->first; |
| 848 CPDF_Object* pElement = it->second; | 847 CPDF_Object* pElement = it->second; |
| 849 ++it; | 848 ++it; |
| 850 uint32_t dwObjNum = | 849 uint32_t dwObjNum = |
| 851 pElement ? pElement->GetObjNum() : 0; | 850 pElement ? pElement->GetObjNum() : 0; |
| 852 if (dwObjNum) { | 851 if (dwObjNum) { |
| 853 m_pTrailer->SetAtReference(key, m_pDocument, | 852 m_pTrailer->SetAtReference(key, m_pDocument.get(), |
| 854 dwObjNum); | 853 dwObjNum); |
| 855 } else { | 854 } else { |
| 856 m_pTrailer->SetAt(key, pElement->Clone()); | 855 m_pTrailer->SetAt(key, pElement->Clone()); |
| 857 } | 856 } |
| 858 } | 857 } |
| 859 } | 858 } |
| 860 pObj->Release(); | 859 pObj->Release(); |
| 861 } else { | 860 } else { |
| 862 if (pObj->IsStream()) { | 861 if (pObj->IsStream()) { |
| 863 m_pTrailer = ToDictionary(pTrailer->Clone()); | 862 m_pTrailer = ToDictionary(pTrailer->Clone()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 if (last_xref != -1 && last_xref > last_obj) | 966 if (last_xref != -1 && last_xref > last_obj) |
| 968 last_trailer = last_xref; | 967 last_trailer = last_xref; |
| 969 else if (last_trailer == -1 || last_xref < last_obj) | 968 else if (last_trailer == -1 || last_xref < last_obj) |
| 970 last_trailer = m_pSyntax->m_FileLen; | 969 last_trailer = m_pSyntax->m_FileLen; |
| 971 | 970 |
| 972 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); | 971 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); |
| 973 return m_pTrailer && !m_ObjectInfo.empty(); | 972 return m_pTrailer && !m_ObjectInfo.empty(); |
| 974 } | 973 } |
| 975 | 974 |
| 976 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 975 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
| 977 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0); | 976 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument.get(), *pos, 0); |
| 978 if (!pObject) | 977 if (!pObject) |
| 979 return FALSE; | 978 return FALSE; |
| 980 | 979 |
| 981 if (m_pDocument) { | 980 if (m_pDocument) { |
| 982 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); | 981 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); |
| 983 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) { | 982 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) { |
| 984 if (pObject->IsStream()) | 983 if (pObject->IsStream()) |
| 985 pObject->Release(); | 984 pObject->Release(); |
| 986 return FALSE; | 985 return FALSE; |
| 987 } | 986 } |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 | 1464 |
| 1466 m_pSyntax->RestorePos(SavedPos); | 1465 m_pSyntax->RestorePos(SavedPos); |
| 1467 return pObj; | 1466 return pObj; |
| 1468 } | 1467 } |
| 1469 | 1468 |
| 1470 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { | 1469 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { |
| 1471 if (m_pSyntax->GetKeyword() != "trailer") | 1470 if (m_pSyntax->GetKeyword() != "trailer") |
| 1472 return nullptr; | 1471 return nullptr; |
| 1473 | 1472 |
| 1474 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( | 1473 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( |
| 1475 m_pSyntax->GetObject(m_pDocument, 0, 0, true)); | 1474 m_pSyntax->GetObject(m_pDocument.get(), 0, 0, true)); |
| 1476 if (!ToDictionary(pObj.get())) | 1475 if (!ToDictionary(pObj.get())) |
| 1477 return nullptr; | 1476 return nullptr; |
| 1478 return pObj.release()->AsDictionary(); | 1477 return pObj.release()->AsDictionary(); |
| 1479 } | 1478 } |
| 1480 | 1479 |
| 1481 uint32_t CPDF_Parser::GetPermissions() const { | 1480 uint32_t CPDF_Parser::GetPermissions() const { |
| 1482 if (!m_pSecurityHandler) | 1481 if (!m_pSecurityHandler) |
| 1483 return 0xFFFFFFFF; | 1482 return 0xFFFFFFFF; |
| 1484 | 1483 |
| 1485 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); | 1484 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 | 1551 |
| 1553 int32_t offset = GetHeaderOffset(pFileAccess); | 1552 int32_t offset = GetHeaderOffset(pFileAccess); |
| 1554 if (offset == -1) | 1553 if (offset == -1) |
| 1555 return FORMAT_ERROR; | 1554 return FORMAT_ERROR; |
| 1556 | 1555 |
| 1557 if (!IsLinearizedFile(pFileAccess, offset)) { | 1556 if (!IsLinearizedFile(pFileAccess, offset)) { |
| 1558 m_pSyntax->m_pFileAccess = nullptr; | 1557 m_pSyntax->m_pFileAccess = nullptr; |
| 1559 return StartParse(pFileAccess); | 1558 return StartParse(pFileAccess); |
| 1560 } | 1559 } |
| 1561 | 1560 |
| 1562 m_pDocument = new CPDF_Document(this); | 1561 m_pDocument.reset(new CPDF_Document(this)); |
| 1563 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1562 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
| 1564 | 1563 |
| 1565 FX_BOOL bXRefRebuilt = FALSE; | 1564 FX_BOOL bXRefRebuilt = FALSE; |
| 1566 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); | 1565 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); |
| 1567 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1566 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
| 1568 if (!RebuildCrossRef()) | 1567 if (!RebuildCrossRef()) |
| 1569 return FORMAT_ERROR; | 1568 return FORMAT_ERROR; |
| 1570 | 1569 |
| 1571 bXRefRebuilt = TRUE; | 1570 bXRefRebuilt = TRUE; |
| 1572 m_LastXRefOffset = 0; | 1571 m_LastXRefOffset = 0; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1667 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1669 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1668 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1670 m_LastXRefOffset = 0; | 1669 m_LastXRefOffset = 0; |
| 1671 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1670 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1672 return FORMAT_ERROR; | 1671 return FORMAT_ERROR; |
| 1673 } | 1672 } |
| 1674 | 1673 |
| 1675 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1674 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1676 return SUCCESS; | 1675 return SUCCESS; |
| 1677 } | 1676 } |
| OLD | NEW |