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/parser/cpdf_parser.h" | 7 #include "core/fpdfapi/parser/cpdf_parser.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { | 46 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { |
47 return pObjStream->GetDict()->GetIntegerFor("First"); | 47 return pObjStream->GetDict()->GetIntegerFor("First"); |
48 } | 48 } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 CPDF_Parser::CPDF_Parser() | 52 CPDF_Parser::CPDF_Parser() |
53 : m_pDocument(nullptr), | 53 : m_pDocument(nullptr), |
54 m_bHasParsed(false), | 54 m_bHasParsed(false), |
55 m_bOwnFileRead(true), | |
56 m_bXRefStream(false), | 55 m_bXRefStream(false), |
57 m_bVersionUpdated(false), | 56 m_bVersionUpdated(false), |
58 m_FileVersion(0), | 57 m_FileVersion(0), |
59 m_pEncryptDict(nullptr), | 58 m_pEncryptDict(nullptr), |
60 m_dwXrefStartObjNum(0) { | 59 m_dwXrefStartObjNum(0) { |
61 m_pSyntax.reset(new CPDF_SyntaxParser); | 60 m_pSyntax.reset(new CPDF_SyntaxParser); |
62 } | 61 } |
63 | 62 |
64 CPDF_Parser::~CPDF_Parser() { | 63 CPDF_Parser::~CPDF_Parser() { |
65 ReleaseEncryptHandler(); | 64 ReleaseEncryptHandler(); |
66 SetEncryptDictionary(nullptr); | 65 SetEncryptDictionary(nullptr); |
67 | |
68 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { | |
69 m_pSyntax->m_pFileAccess->Release(); | |
70 m_pSyntax->m_pFileAccess = nullptr; | |
71 } | |
72 } | 66 } |
73 | 67 |
74 uint32_t CPDF_Parser::GetLastObjNum() const { | 68 uint32_t CPDF_Parser::GetLastObjNum() const { |
75 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; | 69 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; |
76 } | 70 } |
77 | 71 |
78 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { | 72 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { |
79 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; | 73 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; |
80 } | 74 } |
81 | 75 |
(...skipping 20 matching lines...) Expand all Loading... |
102 } | 96 } |
103 | 97 |
104 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { | 98 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { |
105 m_pEncryptDict = pDict; | 99 m_pEncryptDict = pDict; |
106 } | 100 } |
107 | 101 |
108 CPDF_CryptoHandler* CPDF_Parser::GetCryptoHandler() { | 102 CPDF_CryptoHandler* CPDF_Parser::GetCryptoHandler() { |
109 return m_pSyntax->m_pCryptoHandler.get(); | 103 return m_pSyntax->m_pCryptoHandler.get(); |
110 } | 104 } |
111 | 105 |
112 IFX_SeekableReadStream* CPDF_Parser::GetFileAccess() const { | 106 CFX_RetainPtr<IFX_SeekableReadStream> CPDF_Parser::GetFileAccess() const { |
113 return m_pSyntax->m_pFileAccess; | 107 return m_pSyntax->m_pFileAccess; |
114 } | 108 } |
115 | 109 |
116 void CPDF_Parser::ShrinkObjectMap(uint32_t objnum) { | 110 void CPDF_Parser::ShrinkObjectMap(uint32_t objnum) { |
117 if (objnum == 0) { | 111 if (objnum == 0) { |
118 m_ObjectInfo.clear(); | 112 m_ObjectInfo.clear(); |
119 return; | 113 return; |
120 } | 114 } |
121 | 115 |
122 auto it = m_ObjectInfo.lower_bound(objnum); | 116 auto it = m_ObjectInfo.lower_bound(objnum); |
123 while (it != m_ObjectInfo.end()) { | 117 while (it != m_ObjectInfo.end()) { |
124 auto saved_it = it++; | 118 auto saved_it = it++; |
125 m_ObjectInfo.erase(saved_it); | 119 m_ObjectInfo.erase(saved_it); |
126 } | 120 } |
127 | 121 |
128 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) | 122 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) |
129 m_ObjectInfo[objnum - 1].pos = 0; | 123 m_ObjectInfo[objnum - 1].pos = 0; |
130 } | 124 } |
131 | 125 |
132 CPDF_Parser::Error CPDF_Parser::StartParse(IFX_SeekableReadStream* pFileAccess, | 126 CPDF_Parser::Error CPDF_Parser::StartParse( |
133 CPDF_Document* pDocument) { | 127 const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess, |
| 128 CPDF_Document* pDocument) { |
134 ASSERT(!m_bHasParsed); | 129 ASSERT(!m_bHasParsed); |
135 m_bHasParsed = true; | 130 m_bHasParsed = true; |
136 | |
137 m_bXRefStream = false; | 131 m_bXRefStream = false; |
138 m_LastXRefOffset = 0; | 132 m_LastXRefOffset = 0; |
139 m_bOwnFileRead = true; | |
140 | 133 |
141 int32_t offset = GetHeaderOffset(pFileAccess); | 134 int32_t offset = GetHeaderOffset(pFileAccess); |
142 if (offset == -1) { | 135 if (offset == -1) |
143 if (pFileAccess) | |
144 pFileAccess->Release(); | |
145 return FORMAT_ERROR; | 136 return FORMAT_ERROR; |
146 } | 137 |
147 m_pSyntax->InitParser(pFileAccess, offset); | 138 m_pSyntax->InitParser(pFileAccess, offset); |
148 | 139 |
149 uint8_t ch; | 140 uint8_t ch; |
150 if (!m_pSyntax->GetCharAt(5, ch)) | 141 if (!m_pSyntax->GetCharAt(5, ch)) |
151 return FORMAT_ERROR; | 142 return FORMAT_ERROR; |
| 143 |
152 if (std::isdigit(ch)) | 144 if (std::isdigit(ch)) |
153 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; | 145 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; |
154 | 146 |
155 if (!m_pSyntax->GetCharAt(7, ch)) | 147 if (!m_pSyntax->GetCharAt(7, ch)) |
156 return FORMAT_ERROR; | 148 return FORMAT_ERROR; |
| 149 |
157 if (std::isdigit(ch)) | 150 if (std::isdigit(ch)) |
158 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 151 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
159 | 152 |
160 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) | 153 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) |
161 return FORMAT_ERROR; | 154 return FORMAT_ERROR; |
162 | 155 |
163 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); | 156 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); |
164 m_pDocument = pDocument; | 157 m_pDocument = pDocument; |
165 | 158 |
166 bool bXRefRebuilt = false; | 159 bool bXRefRebuilt = false; |
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 return nullptr; | 1110 return nullptr; |
1118 return ParseIndirectObjectAt(pObjList, pos, objnum); | 1111 return ParseIndirectObjectAt(pObjList, pos, objnum); |
1119 } | 1112 } |
1120 if (GetObjectType(objnum) != 2) | 1113 if (GetObjectType(objnum) != 2) |
1121 return nullptr; | 1114 return nullptr; |
1122 | 1115 |
1123 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1116 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
1124 if (!pObjStream) | 1117 if (!pObjStream) |
1125 return nullptr; | 1118 return nullptr; |
1126 | 1119 |
1127 ScopedFileStream file(IFX_MemoryStream::Create( | 1120 CFX_RetainPtr<IFX_MemoryStream> file = IFX_MemoryStream::Create( |
1128 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false)); | 1121 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false); |
1129 CPDF_SyntaxParser syntax; | 1122 CPDF_SyntaxParser syntax; |
1130 syntax.InitParser(file.get(), 0); | 1123 syntax.InitParser(file, 0); |
1131 const int32_t offset = GetStreamFirst(pObjStream); | 1124 const int32_t offset = GetStreamFirst(pObjStream); |
1132 | 1125 |
1133 // Read object numbers from |pObjStream| into a cache. | 1126 // Read object numbers from |pObjStream| into a cache. |
1134 if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) { | 1127 if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) { |
1135 for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { | 1128 for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { |
1136 uint32_t thisnum = syntax.GetDirectNum(); | 1129 uint32_t thisnum = syntax.GetDirectNum(); |
1137 uint32_t thisoff = syntax.GetDirectNum(); | 1130 uint32_t thisoff = syntax.GetDirectNum(); |
1138 m_ObjCache[pObjStream][thisnum] = thisoff; | 1131 m_ObjCache[pObjStream][thisnum] = thisoff; |
1139 } | 1132 } |
1140 } | 1133 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 return; | 1189 return; |
1197 | 1190 |
1198 if (GetObjectType(objnum) == 2) { | 1191 if (GetObjectType(objnum) == 2) { |
1199 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1192 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
1200 if (!pObjStream) | 1193 if (!pObjStream) |
1201 return; | 1194 return; |
1202 | 1195 |
1203 int32_t offset = GetStreamFirst(pObjStream); | 1196 int32_t offset = GetStreamFirst(pObjStream); |
1204 const uint8_t* pData = pObjStream->GetData(); | 1197 const uint8_t* pData = pObjStream->GetData(); |
1205 uint32_t totalsize = pObjStream->GetSize(); | 1198 uint32_t totalsize = pObjStream->GetSize(); |
1206 ScopedFileStream file( | 1199 CFX_RetainPtr<IFX_MemoryStream> file = |
1207 IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false)); | 1200 IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false); |
| 1201 CPDF_SyntaxParser syntax; |
| 1202 syntax.InitParser(file, 0); |
1208 | 1203 |
1209 CPDF_SyntaxParser syntax; | |
1210 syntax.InitParser(file.get(), 0); | |
1211 for (int i = GetStreamNCount(pObjStream); i > 0; --i) { | 1204 for (int i = GetStreamNCount(pObjStream); i > 0; --i) { |
1212 uint32_t thisnum = syntax.GetDirectNum(); | 1205 uint32_t thisnum = syntax.GetDirectNum(); |
1213 uint32_t thisoff = syntax.GetDirectNum(); | 1206 uint32_t thisoff = syntax.GetDirectNum(); |
1214 if (thisnum != objnum) | 1207 if (thisnum != objnum) |
1215 continue; | 1208 continue; |
1216 | 1209 |
1217 if (i == 1) { | 1210 if (i == 1) { |
1218 size = totalsize - (thisoff + offset); | 1211 size = totalsize - (thisoff + offset); |
1219 } else { | 1212 } else { |
1220 syntax.GetDirectNum(); // Skip nextnum. | 1213 syntax.GetDirectNum(); // Skip nextnum. |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 | 1406 |
1414 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); | 1407 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); |
1415 if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") { | 1408 if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") { |
1416 // See PDF Reference 1.7, page 123, table 3.20. | 1409 // See PDF Reference 1.7, page 123, table 3.20. |
1417 dwPermission &= 0xFFFFFFFC; | 1410 dwPermission &= 0xFFFFFFFC; |
1418 dwPermission |= 0xFFFFF0C0; | 1411 dwPermission |= 0xFFFFF0C0; |
1419 } | 1412 } |
1420 return dwPermission; | 1413 return dwPermission; |
1421 } | 1414 } |
1422 | 1415 |
1423 bool CPDF_Parser::IsLinearizedFile(IFX_SeekableReadStream* pFileAccess, | 1416 bool CPDF_Parser::IsLinearizedFile( |
1424 uint32_t offset) { | 1417 const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess, |
| 1418 uint32_t offset) { |
1425 m_pSyntax->InitParser(pFileAccess, offset); | 1419 m_pSyntax->InitParser(pFileAccess, offset); |
1426 m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9); | 1420 m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9); |
1427 | 1421 |
1428 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 1422 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
1429 bool bIsNumber; | 1423 bool bIsNumber; |
1430 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); | 1424 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); |
1431 if (!bIsNumber) | 1425 if (!bIsNumber) |
1432 return false; | 1426 return false; |
1433 | 1427 |
1434 uint32_t objnum = FXSYS_atoui(word.c_str()); | 1428 uint32_t objnum = FXSYS_atoui(word.c_str()); |
(...skipping 12 matching lines...) Expand all Loading... |
1447 if (!m_pLinearized) | 1441 if (!m_pLinearized) |
1448 return false; | 1442 return false; |
1449 | 1443 |
1450 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); | 1444 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); |
1451 // Move parser onto first page xref table start. | 1445 // Move parser onto first page xref table start. |
1452 m_pSyntax->GetNextWord(nullptr); | 1446 m_pSyntax->GetNextWord(nullptr); |
1453 return true; | 1447 return true; |
1454 } | 1448 } |
1455 | 1449 |
1456 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1450 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( |
1457 IFX_SeekableReadStream* pFileAccess, | 1451 const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess, |
1458 CPDF_Document* pDocument) { | 1452 CPDF_Document* pDocument) { |
1459 ASSERT(!m_bHasParsed); | 1453 ASSERT(!m_bHasParsed); |
1460 | |
1461 m_bXRefStream = false; | 1454 m_bXRefStream = false; |
1462 m_LastXRefOffset = 0; | 1455 m_LastXRefOffset = 0; |
1463 m_bOwnFileRead = true; | |
1464 | 1456 |
1465 int32_t offset = GetHeaderOffset(pFileAccess); | 1457 int32_t offset = GetHeaderOffset(pFileAccess); |
1466 if (offset == -1) | 1458 if (offset == -1) |
1467 return FORMAT_ERROR; | 1459 return FORMAT_ERROR; |
1468 | 1460 |
1469 if (!IsLinearizedFile(pFileAccess, offset)) { | 1461 if (!IsLinearizedFile(pFileAccess, offset)) { |
1470 m_pSyntax->m_pFileAccess = nullptr; | 1462 m_pSyntax->m_pFileAccess = nullptr; |
1471 return StartParse(pFileAccess, std::move(pDocument)); | 1463 return StartParse(pFileAccess, std::move(pDocument)); |
1472 } | 1464 } |
1473 m_bHasParsed = true; | 1465 m_bHasParsed = true; |
1474 m_pDocument = pDocument; | 1466 m_pDocument = pDocument; |
1475 | 1467 |
1476 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1468 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
1477 | |
1478 bool bXRefRebuilt = false; | 1469 bool bXRefRebuilt = false; |
1479 bool bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, false); | 1470 bool bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, false); |
1480 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, true)) { | 1471 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, true)) { |
1481 if (!RebuildCrossRef()) | 1472 if (!RebuildCrossRef()) |
1482 return FORMAT_ERROR; | 1473 return FORMAT_ERROR; |
1483 | 1474 |
1484 bXRefRebuilt = true; | 1475 bXRefRebuilt = true; |
1485 m_LastXRefOffset = 0; | 1476 m_LastXRefOffset = 0; |
1486 } | 1477 } |
1487 | 1478 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1569 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
1579 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1570 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
1580 m_LastXRefOffset = 0; | 1571 m_LastXRefOffset = 0; |
1581 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1572 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1582 return FORMAT_ERROR; | 1573 return FORMAT_ERROR; |
1583 } | 1574 } |
1584 | 1575 |
1585 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1576 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1586 return SUCCESS; | 1577 return SUCCESS; |
1587 } | 1578 } |
OLD | NEW |