Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_parser.cpp

Issue 2275773003: Flip document and parser ownership (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@private_parser
Patch Set: Rebase to master Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_document.cpp ('k') | core/fpdfapi/fpdf_parser/include/cpdf_document.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698