| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 auto saved_it = it++; | 119 auto saved_it = it++; |
| 120 m_ObjectInfo.erase(saved_it); | 120 m_ObjectInfo.erase(saved_it); |
| 121 } | 121 } |
| 122 | 122 |
| 123 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) | 123 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) |
| 124 m_ObjectInfo[objnum - 1].pos = 0; | 124 m_ObjectInfo[objnum - 1].pos = 0; |
| 125 } | 125 } |
| 126 | 126 |
| 127 void CPDF_Parser::CloseParser() { | 127 void CPDF_Parser::CloseParser() { |
| 128 m_bVersionUpdated = false; | 128 m_bVersionUpdated = false; |
| 129 m_pDocument.reset(); | 129 m_pDocument = nullptr; |
| 130 | 130 |
| 131 if (m_pTrailer) { | 131 if (m_pTrailer) { |
| 132 m_pTrailer->Release(); | 132 m_pTrailer->Release(); |
| 133 m_pTrailer = nullptr; | 133 m_pTrailer = nullptr; |
| 134 } | 134 } |
| 135 ReleaseEncryptHandler(); | 135 ReleaseEncryptHandler(); |
| 136 SetEncryptDictionary(nullptr); | 136 SetEncryptDictionary(nullptr); |
| 137 | 137 |
| 138 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { | 138 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { |
| 139 m_pSyntax->m_pFileAccess->Release(); | 139 m_pSyntax->m_pFileAccess->Release(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 151 trailer->Release(); | 151 trailer->Release(); |
| 152 } | 152 } |
| 153 m_Trailers.RemoveAll(); | 153 m_Trailers.RemoveAll(); |
| 154 | 154 |
| 155 if (m_pLinearized) { | 155 if (m_pLinearized) { |
| 156 m_pLinearized->Release(); | 156 m_pLinearized->Release(); |
| 157 m_pLinearized = nullptr; | 157 m_pLinearized = nullptr; |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 CPDF_Parser::Error CPDF_Parser::StartParse( | 161 CPDF_Parser::Error CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, |
| 162 IFX_FileRead* pFileAccess, | 162 CPDF_Document* pDocument) { |
| 163 std::unique_ptr<CPDF_Document> pDocument) { | |
| 164 CloseParser(); | 163 CloseParser(); |
| 165 | 164 |
| 166 m_bXRefStream = FALSE; | 165 m_bXRefStream = FALSE; |
| 167 m_LastXRefOffset = 0; | 166 m_LastXRefOffset = 0; |
| 168 m_bOwnFileRead = true; | 167 m_bOwnFileRead = true; |
| 169 | 168 |
| 170 int32_t offset = GetHeaderOffset(pFileAccess); | 169 int32_t offset = GetHeaderOffset(pFileAccess); |
| 171 if (offset == -1) { | 170 if (offset == -1) { |
| 172 if (pFileAccess) | 171 if (pFileAccess) |
| 173 pFileAccess->Release(); | 172 pFileAccess->Release(); |
| 174 return FORMAT_ERROR; | 173 return FORMAT_ERROR; |
| 175 } | 174 } |
| 176 m_pSyntax->InitParser(pFileAccess, offset); | 175 m_pSyntax->InitParser(pFileAccess, offset); |
| 177 | 176 |
| 178 uint8_t ch; | 177 uint8_t ch; |
| 179 if (!m_pSyntax->GetCharAt(5, ch)) | 178 if (!m_pSyntax->GetCharAt(5, ch)) |
| 180 return FORMAT_ERROR; | 179 return FORMAT_ERROR; |
| 181 if (std::isdigit(ch)) | 180 if (std::isdigit(ch)) |
| 182 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; | 181 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; |
| 183 | 182 |
| 184 if (!m_pSyntax->GetCharAt(7, ch)) | 183 if (!m_pSyntax->GetCharAt(7, ch)) |
| 185 return FORMAT_ERROR; | 184 return FORMAT_ERROR; |
| 186 if (std::isdigit(ch)) | 185 if (std::isdigit(ch)) |
| 187 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 186 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
| 188 | 187 |
| 189 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) | 188 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) |
| 190 return FORMAT_ERROR; | 189 return FORMAT_ERROR; |
| 191 | 190 |
| 192 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); | 191 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); |
| 193 m_pDocument = std::move(pDocument); | 192 m_pDocument = pDocument; |
| 194 | 193 |
| 195 FX_BOOL bXRefRebuilt = FALSE; | 194 FX_BOOL bXRefRebuilt = FALSE; |
| 196 if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) { | 195 if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) { |
| 197 m_SortedOffset.insert(m_pSyntax->SavePos()); | 196 m_SortedOffset.insert(m_pSyntax->SavePos()); |
| 198 m_pSyntax->GetKeyword(); | 197 m_pSyntax->GetKeyword(); |
| 199 | 198 |
| 200 bool bNumber; | 199 bool bNumber; |
| 201 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); | 200 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); |
| 202 if (!bNumber) | 201 if (!bNumber) |
| 203 return FORMAT_ERROR; | 202 return FORMAT_ERROR; |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 inside_index++; | 757 inside_index++; |
| 759 } | 758 } |
| 760 break; | 759 break; |
| 761 case 3: | 760 case 3: |
| 762 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 761 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
| 763 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; | 762 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; |
| 764 m_SortedOffset.insert(obj_pos); | 763 m_SortedOffset.insert(obj_pos); |
| 765 last_obj = start_pos; | 764 last_obj = start_pos; |
| 766 FX_FILESIZE obj_end = 0; | 765 FX_FILESIZE obj_end = 0; |
| 767 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( | 766 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( |
| 768 m_pDocument.get(), obj_pos, objnum, &obj_end); | 767 m_pDocument, obj_pos, objnum, &obj_end); |
| 769 if (CPDF_Stream* pStream = ToStream(pObject)) { | 768 if (CPDF_Stream* pStream = ToStream(pObject)) { |
| 770 if (CPDF_Dictionary* pDict = pStream->GetDict()) { | 769 if (CPDF_Dictionary* pDict = pStream->GetDict()) { |
| 771 if ((pDict->KeyExist("Type")) && | 770 if ((pDict->KeyExist("Type")) && |
| 772 (pDict->GetStringBy("Type") == "XRef" && | 771 (pDict->GetStringBy("Type") == "XRef" && |
| 773 pDict->KeyExist("Size"))) { | 772 pDict->KeyExist("Size"))) { |
| 774 CPDF_Object* pRoot = pDict->GetObjectBy("Root"); | 773 CPDF_Object* pRoot = pDict->GetObjectBy("Root"); |
| 775 if (pRoot && pRoot->GetDict() && | 774 if (pRoot && pRoot->GetDict() && |
| 776 pRoot->GetDict()->GetObjectBy("Pages")) { | 775 pRoot->GetDict()->GetObjectBy("Pages")) { |
| 777 if (m_pTrailer) | 776 if (m_pTrailer) |
| 778 m_pTrailer->Release(); | 777 m_pTrailer->Release(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 break; | 820 break; |
| 822 } | 821 } |
| 823 break; | 822 break; |
| 824 | 823 |
| 825 case ParserState::kTrailer: | 824 case ParserState::kTrailer: |
| 826 if (inside_index == 7) { | 825 if (inside_index == 7) { |
| 827 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 826 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
| 828 last_trailer = pos + i - 7; | 827 last_trailer = pos + i - 7; |
| 829 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); | 828 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); |
| 830 | 829 |
| 831 CPDF_Object* pObj = | 830 CPDF_Object* pObj = m_pSyntax->GetObject(m_pDocument, 0, 0, true); |
| 832 m_pSyntax->GetObject(m_pDocument.get(), 0, 0, true); | |
| 833 if (pObj) { | 831 if (pObj) { |
| 834 if (!pObj->IsDictionary() && !pObj->AsStream()) { | 832 if (!pObj->IsDictionary() && !pObj->AsStream()) { |
| 835 pObj->Release(); | 833 pObj->Release(); |
| 836 } else { | 834 } else { |
| 837 CPDF_Stream* pStream = pObj->AsStream(); | 835 CPDF_Stream* pStream = pObj->AsStream(); |
| 838 if (CPDF_Dictionary* pTrailer = | 836 if (CPDF_Dictionary* pTrailer = |
| 839 pStream ? pStream->GetDict() : pObj->AsDictionary()) { | 837 pStream ? pStream->GetDict() : pObj->AsDictionary()) { |
| 840 if (m_pTrailer) { | 838 if (m_pTrailer) { |
| 841 CPDF_Object* pRoot = pTrailer->GetObjectBy("Root"); | 839 CPDF_Object* pRoot = pTrailer->GetObjectBy("Root"); |
| 842 CPDF_Reference* pRef = ToReference(pRoot); | 840 CPDF_Reference* pRef = ToReference(pRoot); |
| 843 if (!pRoot || | 841 if (!pRoot || |
| 844 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && | 842 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && |
| 845 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { | 843 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { |
| 846 auto it = pTrailer->begin(); | 844 auto it = pTrailer->begin(); |
| 847 while (it != pTrailer->end()) { | 845 while (it != pTrailer->end()) { |
| 848 const CFX_ByteString& key = it->first; | 846 const CFX_ByteString& key = it->first; |
| 849 CPDF_Object* pElement = it->second; | 847 CPDF_Object* pElement = it->second; |
| 850 ++it; | 848 ++it; |
| 851 uint32_t dwObjNum = | 849 uint32_t dwObjNum = |
| 852 pElement ? pElement->GetObjNum() : 0; | 850 pElement ? pElement->GetObjNum() : 0; |
| 853 if (dwObjNum) { | 851 if (dwObjNum) { |
| 854 m_pTrailer->SetAtReference(key, m_pDocument.get(), | 852 m_pTrailer->SetAtReference(key, m_pDocument, |
| 855 dwObjNum); | 853 dwObjNum); |
| 856 } else { | 854 } else { |
| 857 m_pTrailer->SetAt(key, pElement->Clone()); | 855 m_pTrailer->SetAt(key, pElement->Clone()); |
| 858 } | 856 } |
| 859 } | 857 } |
| 860 } | 858 } |
| 861 pObj->Release(); | 859 pObj->Release(); |
| 862 } else { | 860 } else { |
| 863 if (pObj->IsStream()) { | 861 if (pObj->IsStream()) { |
| 864 m_pTrailer = ToDictionary(pTrailer->Clone()); | 862 m_pTrailer = ToDictionary(pTrailer->Clone()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 if (last_xref != -1 && last_xref > last_obj) | 966 if (last_xref != -1 && last_xref > last_obj) |
| 969 last_trailer = last_xref; | 967 last_trailer = last_xref; |
| 970 else if (last_trailer == -1 || last_xref < last_obj) | 968 else if (last_trailer == -1 || last_xref < last_obj) |
| 971 last_trailer = m_pSyntax->m_FileLen; | 969 last_trailer = m_pSyntax->m_FileLen; |
| 972 | 970 |
| 973 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); | 971 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); |
| 974 return m_pTrailer && !m_ObjectInfo.empty(); | 972 return m_pTrailer && !m_ObjectInfo.empty(); |
| 975 } | 973 } |
| 976 | 974 |
| 977 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 975 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
| 978 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument.get(), *pos, 0); | 976 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0); |
| 979 if (!pObject) | 977 if (!pObject) |
| 980 return FALSE; | 978 return FALSE; |
| 981 | 979 |
| 982 if (m_pDocument) { | 980 if (m_pDocument) { |
| 983 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); | 981 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); |
| 984 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) { | 982 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) { |
| 985 // If |pObject| has an objnum assigned then this will leak as Release() | 983 // If |pObject| has an objnum assigned then this will leak as Release() |
| 986 // will early exit. | 984 // will early exit. |
| 987 if (pObject->IsStream()) | 985 if (pObject->IsStream()) |
| 988 pObject->Release(); | 986 pObject->Release(); |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 | 1469 |
| 1472 m_pSyntax->RestorePos(SavedPos); | 1470 m_pSyntax->RestorePos(SavedPos); |
| 1473 return pObj; | 1471 return pObj; |
| 1474 } | 1472 } |
| 1475 | 1473 |
| 1476 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { | 1474 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { |
| 1477 if (m_pSyntax->GetKeyword() != "trailer") | 1475 if (m_pSyntax->GetKeyword() != "trailer") |
| 1478 return nullptr; | 1476 return nullptr; |
| 1479 | 1477 |
| 1480 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( | 1478 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( |
| 1481 m_pSyntax->GetObject(m_pDocument.get(), 0, 0, true)); | 1479 m_pSyntax->GetObject(m_pDocument, 0, 0, true)); |
| 1482 if (!ToDictionary(pObj.get())) | 1480 if (!ToDictionary(pObj.get())) |
| 1483 return nullptr; | 1481 return nullptr; |
| 1484 return pObj.release()->AsDictionary(); | 1482 return pObj.release()->AsDictionary(); |
| 1485 } | 1483 } |
| 1486 | 1484 |
| 1487 uint32_t CPDF_Parser::GetPermissions() const { | 1485 uint32_t CPDF_Parser::GetPermissions() const { |
| 1488 if (!m_pSecurityHandler) | 1486 if (!m_pSecurityHandler) |
| 1489 return 0xFFFFFFFF; | 1487 return 0xFFFFFFFF; |
| 1490 | 1488 |
| 1491 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); | 1489 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 if (CPDF_Number* pTable = ToNumber(pDict->GetObjectBy("T"))) | 1541 if (CPDF_Number* pTable = ToNumber(pDict->GetObjectBy("T"))) |
| 1544 m_LastXRefOffset = pTable->GetInteger(); | 1542 m_LastXRefOffset = pTable->GetInteger(); |
| 1545 | 1543 |
| 1546 return TRUE; | 1544 return TRUE; |
| 1547 } | 1545 } |
| 1548 m_pLinearized->Release(); | 1546 m_pLinearized->Release(); |
| 1549 m_pLinearized = nullptr; | 1547 m_pLinearized = nullptr; |
| 1550 return FALSE; | 1548 return FALSE; |
| 1551 } | 1549 } |
| 1552 | 1550 |
| 1553 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1551 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse(IFX_FileRead* pFileAccess, |
| 1554 IFX_FileRead* pFileAccess, | 1552 CPDF_Document* pDocument) { |
| 1555 std::unique_ptr<CPDF_Document> pDocument) { | |
| 1556 CloseParser(); | 1553 CloseParser(); |
| 1557 m_bXRefStream = FALSE; | 1554 m_bXRefStream = FALSE; |
| 1558 m_LastXRefOffset = 0; | 1555 m_LastXRefOffset = 0; |
| 1559 m_bOwnFileRead = true; | 1556 m_bOwnFileRead = true; |
| 1560 | 1557 |
| 1561 int32_t offset = GetHeaderOffset(pFileAccess); | 1558 int32_t offset = GetHeaderOffset(pFileAccess); |
| 1562 if (offset == -1) | 1559 if (offset == -1) |
| 1563 return FORMAT_ERROR; | 1560 return FORMAT_ERROR; |
| 1564 | 1561 |
| 1565 if (!IsLinearizedFile(pFileAccess, offset)) { | 1562 if (!IsLinearizedFile(pFileAccess, offset)) { |
| 1566 m_pSyntax->m_pFileAccess = nullptr; | 1563 m_pSyntax->m_pFileAccess = nullptr; |
| 1567 return StartParse(pFileAccess, std::move(pDocument)); | 1564 return StartParse(pFileAccess, std::move(pDocument)); |
| 1568 } | 1565 } |
| 1569 | 1566 |
| 1570 m_pDocument = std::move(pDocument); | 1567 m_pDocument = pDocument; |
| 1571 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1568 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
| 1572 | 1569 |
| 1573 FX_BOOL bXRefRebuilt = FALSE; | 1570 FX_BOOL bXRefRebuilt = FALSE; |
| 1574 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); | 1571 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); |
| 1575 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1572 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
| 1576 if (!RebuildCrossRef()) | 1573 if (!RebuildCrossRef()) |
| 1577 return FORMAT_ERROR; | 1574 return FORMAT_ERROR; |
| 1578 | 1575 |
| 1579 bXRefRebuilt = TRUE; | 1576 bXRefRebuilt = TRUE; |
| 1580 m_LastXRefOffset = 0; | 1577 m_LastXRefOffset = 0; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1673 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1677 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1674 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1678 m_LastXRefOffset = 0; | 1675 m_LastXRefOffset = 0; |
| 1679 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1676 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1680 return FORMAT_ERROR; | 1677 return FORMAT_ERROR; |
| 1681 } | 1678 } |
| 1682 | 1679 |
| 1683 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1680 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1684 return SUCCESS; | 1681 return SUCCESS; |
| 1685 } | 1682 } |
| OLD | NEW |