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_data_avail.h" | 7 #include "core/fpdfapi/parser/cpdf_data_avail.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "core/fpdfapi/cpdf_modulemgr.h" | 13 #include "core/fpdfapi/cpdf_modulemgr.h" |
14 #include "core/fpdfapi/parser/cpdf_array.h" | 14 #include "core/fpdfapi/parser/cpdf_array.h" |
15 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 15 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
16 #include "core/fpdfapi/parser/cpdf_document.h" | 16 #include "core/fpdfapi/parser/cpdf_document.h" |
17 #include "core/fpdfapi/parser/cpdf_hint_tables.h" | 17 #include "core/fpdfapi/parser/cpdf_hint_tables.h" |
18 #include "core/fpdfapi/parser/cpdf_linearized_header.h" | 18 #include "core/fpdfapi/parser/cpdf_linearized_header.h" |
19 #include "core/fpdfapi/parser/cpdf_name.h" | 19 #include "core/fpdfapi/parser/cpdf_name.h" |
20 #include "core/fpdfapi/parser/cpdf_number.h" | 20 #include "core/fpdfapi/parser/cpdf_number.h" |
21 #include "core/fpdfapi/parser/cpdf_reference.h" | 21 #include "core/fpdfapi/parser/cpdf_reference.h" |
22 #include "core/fpdfapi/parser/cpdf_stream.h" | 22 #include "core/fpdfapi/parser/cpdf_stream.h" |
23 #include "core/fpdfapi/parser/fpdf_parser_utility.h" | 23 #include "core/fpdfapi/parser/fpdf_parser_utility.h" |
24 #include "core/fxcrt/fx_ext.h" | 24 #include "core/fxcrt/fx_ext.h" |
25 #include "core/fxcrt/fx_safe_types.h" | 25 #include "core/fxcrt/fx_safe_types.h" |
26 #include "third_party/base/numerics/safe_conversions.h" | 26 #include "third_party/base/numerics/safe_conversions.h" |
| 27 #include "third_party/base/ptr_util.h" |
27 #include "third_party/base/stl_util.h" | 28 #include "third_party/base/stl_util.h" |
28 | 29 |
29 CPDF_DataAvail::FileAvail::~FileAvail() {} | 30 CPDF_DataAvail::FileAvail::~FileAvail() {} |
30 | 31 |
31 CPDF_DataAvail::DownloadHints::~DownloadHints() {} | 32 CPDF_DataAvail::DownloadHints::~DownloadHints() {} |
32 | 33 |
33 // static | 34 // static |
34 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; | 35 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; |
35 | 36 |
36 CPDF_DataAvail::CPDF_DataAvail( | 37 CPDF_DataAvail::CPDF_DataAvail( |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 m_docStatus = PDF_DATAAVAIL_ERROR; | 1141 m_docStatus = PDF_DATAAVAIL_ERROR; |
1141 return false; | 1142 return false; |
1142 } | 1143 } |
1143 | 1144 |
1144 pPageNode->m_type = PDF_PAGENODE_PAGES; | 1145 pPageNode->m_type = PDF_PAGENODE_PAGES; |
1145 for (size_t i = 0; i < pArray->GetCount(); ++i) { | 1146 for (size_t i = 0; i < pArray->GetCount(); ++i) { |
1146 CPDF_Reference* pKid = ToReference(pArray->GetObjectAt(i)); | 1147 CPDF_Reference* pKid = ToReference(pArray->GetObjectAt(i)); |
1147 if (!pKid) | 1148 if (!pKid) |
1148 continue; | 1149 continue; |
1149 | 1150 |
1150 PageNode* pNode = new PageNode(); | 1151 auto pNode = pdfium::MakeUnique<PageNode>(); |
1151 pPageNode->m_childNode.Add(pNode); | |
1152 pNode->m_dwPageNo = pKid->GetRefObjNum(); | 1152 pNode->m_dwPageNo = pKid->GetRefObjNum(); |
| 1153 pPageNode->m_ChildNodes.push_back(std::move(pNode)); |
1153 } | 1154 } |
1154 return true; | 1155 return true; |
1155 } | 1156 } |
1156 | 1157 |
1157 bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo, | 1158 bool CPDF_DataAvail::CheckUnknownPageNode(uint32_t dwPageNo, |
1158 PageNode* pPageNode, | 1159 PageNode* pPageNode, |
1159 DownloadHints* pHints) { | 1160 DownloadHints* pHints) { |
1160 bool bExist = false; | 1161 bool bExist = false; |
1161 std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist); | 1162 std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist); |
1162 if (!bExist) { | 1163 if (!bExist) { |
1163 m_docStatus = PDF_DATAAVAIL_ERROR; | 1164 m_docStatus = PDF_DATAAVAIL_ERROR; |
1164 return false; | 1165 return false; |
1165 } | 1166 } |
1166 | 1167 |
1167 if (!pPage) { | 1168 if (!pPage) { |
1168 if (m_docStatus == PDF_DATAAVAIL_ERROR) | 1169 if (m_docStatus == PDF_DATAAVAIL_ERROR) |
1169 m_docStatus = PDF_DATAAVAIL_ERROR; | 1170 m_docStatus = PDF_DATAAVAIL_ERROR; |
(...skipping 18 matching lines...) Expand all Loading... |
1188 pPageNode->m_type = PDF_PAGENODE_PAGES; | 1189 pPageNode->m_type = PDF_PAGENODE_PAGES; |
1189 CPDF_Object* pKids = pDict->GetObjectFor("Kids"); | 1190 CPDF_Object* pKids = pDict->GetObjectFor("Kids"); |
1190 if (!pKids) { | 1191 if (!pKids) { |
1191 m_docStatus = PDF_DATAAVAIL_PAGE; | 1192 m_docStatus = PDF_DATAAVAIL_PAGE; |
1192 return true; | 1193 return true; |
1193 } | 1194 } |
1194 | 1195 |
1195 switch (pKids->GetType()) { | 1196 switch (pKids->GetType()) { |
1196 case CPDF_Object::REFERENCE: { | 1197 case CPDF_Object::REFERENCE: { |
1197 CPDF_Reference* pKid = pKids->AsReference(); | 1198 CPDF_Reference* pKid = pKids->AsReference(); |
1198 PageNode* pNode = new PageNode(); | 1199 auto pNode = pdfium::MakeUnique<PageNode>(); |
1199 pPageNode->m_childNode.Add(pNode); | |
1200 pNode->m_dwPageNo = pKid->GetRefObjNum(); | 1200 pNode->m_dwPageNo = pKid->GetRefObjNum(); |
| 1201 pPageNode->m_ChildNodes.push_back(std::move(pNode)); |
1201 } break; | 1202 } break; |
1202 case CPDF_Object::ARRAY: { | 1203 case CPDF_Object::ARRAY: { |
1203 CPDF_Array* pKidsArray = pKids->AsArray(); | 1204 CPDF_Array* pKidsArray = pKids->AsArray(); |
1204 for (size_t i = 0; i < pKidsArray->GetCount(); ++i) { | 1205 for (size_t i = 0; i < pKidsArray->GetCount(); ++i) { |
1205 CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i)); | 1206 CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i)); |
1206 if (!pKid) | 1207 if (!pKid) |
1207 continue; | 1208 continue; |
1208 | 1209 |
1209 PageNode* pNode = new PageNode(); | 1210 auto pNode = pdfium::MakeUnique<PageNode>(); |
1210 pPageNode->m_childNode.Add(pNode); | |
1211 pNode->m_dwPageNo = pKid->GetRefObjNum(); | 1211 pNode->m_dwPageNo = pKid->GetRefObjNum(); |
| 1212 pPageNode->m_ChildNodes.push_back(std::move(pNode)); |
1212 } | 1213 } |
1213 } break; | 1214 } break; |
1214 default: | 1215 default: |
1215 break; | 1216 break; |
1216 } | 1217 } |
1217 } else if (type == "Page") { | 1218 } else if (type == "Page") { |
1218 pPageNode->m_type = PDF_PAGENODE_PAGE; | 1219 pPageNode->m_type = PDF_PAGENODE_PAGE; |
1219 } else { | 1220 } else { |
1220 m_docStatus = PDF_DATAAVAIL_ERROR; | 1221 m_docStatus = PDF_DATAAVAIL_ERROR; |
1221 return false; | 1222 return false; |
1222 } | 1223 } |
1223 return true; | 1224 return true; |
1224 } | 1225 } |
1225 | 1226 |
1226 bool CPDF_DataAvail::CheckPageNode(CPDF_DataAvail::PageNode& pageNodes, | 1227 bool CPDF_DataAvail::CheckPageNode(const CPDF_DataAvail::PageNode& pageNode, |
1227 int32_t iPage, | 1228 int32_t iPage, |
1228 int32_t& iCount, | 1229 int32_t& iCount, |
1229 DownloadHints* pHints, | 1230 DownloadHints* pHints, |
1230 int level) { | 1231 int level) { |
1231 if (level >= kMaxPageRecursionDepth) | 1232 if (level >= kMaxPageRecursionDepth) |
1232 return false; | 1233 return false; |
1233 | 1234 |
1234 int32_t iSize = pageNodes.m_childNode.GetSize(); | 1235 int32_t iSize = pdfium::CollectionSize<int32_t>(pageNode.m_ChildNodes); |
1235 if (iSize <= 0 || iPage >= iSize) { | 1236 if (iSize <= 0 || iPage >= iSize) { |
1236 m_docStatus = PDF_DATAAVAIL_ERROR; | 1237 m_docStatus = PDF_DATAAVAIL_ERROR; |
1237 return false; | 1238 return false; |
1238 } | 1239 } |
1239 | |
1240 for (int32_t i = 0; i < iSize; ++i) { | 1240 for (int32_t i = 0; i < iSize; ++i) { |
1241 PageNode* pNode = pageNodes.m_childNode.GetAt(i); | 1241 PageNode* pNode = pageNode.m_ChildNodes[i].get(); |
1242 if (!pNode) | 1242 if (!pNode) |
1243 continue; | 1243 continue; |
1244 | 1244 |
| 1245 if (pNode->m_type == PDF_PAGENODE_UNKNOWN) { |
| 1246 // Updates the type for the unknown page node. |
| 1247 if (!CheckUnknownPageNode(pNode->m_dwPageNo, pNode, pHints)) |
| 1248 return false; |
| 1249 } |
| 1250 if (pNode->m_type == PDF_PAGENODE_ARRAY) { |
| 1251 // Updates a more specific type for the array page node. |
| 1252 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) |
| 1253 return false; |
| 1254 } |
1245 switch (pNode->m_type) { | 1255 switch (pNode->m_type) { |
1246 case PDF_PAGENODE_UNKNOWN: | |
1247 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) { | |
1248 return false; | |
1249 } | |
1250 --i; | |
1251 break; | |
1252 case PDF_PAGENODE_PAGE: | 1256 case PDF_PAGENODE_PAGE: |
1253 iCount++; | 1257 iCount++; |
1254 if (iPage == iCount && m_pDocument) | 1258 if (iPage == iCount && m_pDocument) |
1255 m_pDocument->SetPageObjNum(iPage, pNode->m_dwPageNo); | 1259 m_pDocument->SetPageObjNum(iPage, pNode->m_dwPageNo); |
1256 break; | 1260 break; |
1257 case PDF_PAGENODE_PAGES: | 1261 case PDF_PAGENODE_PAGES: |
1258 if (!CheckPageNode(*pNode, iPage, iCount, pHints, level + 1)) | 1262 if (!CheckPageNode(*pNode, iPage, iCount, pHints, level + 1)) |
1259 return false; | 1263 return false; |
1260 break; | 1264 break; |
| 1265 case PDF_PAGENODE_UNKNOWN: |
1261 case PDF_PAGENODE_ARRAY: | 1266 case PDF_PAGENODE_ARRAY: |
1262 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) | 1267 // Already converted above, error if we get here. |
1263 return false; | 1268 return false; |
1264 --i; | |
1265 break; | |
1266 } | 1269 } |
1267 | |
1268 if (iPage == iCount) { | 1270 if (iPage == iCount) { |
1269 m_docStatus = PDF_DATAAVAIL_DONE; | 1271 m_docStatus = PDF_DATAAVAIL_DONE; |
1270 return true; | 1272 return true; |
1271 } | 1273 } |
1272 } | 1274 } |
1273 return true; | 1275 return true; |
1274 } | 1276 } |
1275 | 1277 |
1276 bool CPDF_DataAvail::LoadDocPage(uint32_t dwPage, DownloadHints* pHints) { | 1278 bool CPDF_DataAvail::LoadDocPage(uint32_t dwPage, DownloadHints* pHints) { |
1277 FX_SAFE_INT32 safePage = pdfium::base::checked_cast<int32_t>(dwPage); | 1279 FX_SAFE_INT32 safePage = pdfium::base::checked_cast<int32_t>(dwPage); |
1278 int32_t iPage = safePage.ValueOrDie(); | 1280 int32_t iPage = safePage.ValueOrDie(); |
1279 if (m_pDocument->GetPageCount() <= iPage || | 1281 if (m_pDocument->GetPageCount() <= iPage || |
1280 m_pDocument->IsPageLoaded(iPage)) { | 1282 m_pDocument->IsPageLoaded(iPage)) { |
1281 m_docStatus = PDF_DATAAVAIL_DONE; | 1283 m_docStatus = PDF_DATAAVAIL_DONE; |
1282 return true; | 1284 return true; |
1283 } | 1285 } |
1284 | 1286 if (m_PageNode.m_type == PDF_PAGENODE_PAGE) { |
1285 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { | 1287 m_docStatus = iPage == 0 ? PDF_DATAAVAIL_DONE : PDF_DATAAVAIL_ERROR; |
1286 if (iPage == 0) { | |
1287 m_docStatus = PDF_DATAAVAIL_DONE; | |
1288 return true; | |
1289 } | |
1290 m_docStatus = PDF_DATAAVAIL_ERROR; | |
1291 return true; | 1288 return true; |
1292 } | 1289 } |
1293 int32_t iCount = -1; | 1290 int32_t iCount = -1; |
1294 return CheckPageNode(m_pageNodes, iPage, iCount, pHints, 0); | 1291 return CheckPageNode(m_PageNode, iPage, iCount, pHints, 0); |
1295 } | 1292 } |
1296 | 1293 |
1297 bool CPDF_DataAvail::CheckPageCount(DownloadHints* pHints) { | 1294 bool CPDF_DataAvail::CheckPageCount(DownloadHints* pHints) { |
1298 bool bExist = false; | 1295 bool bExist = false; |
1299 std::unique_ptr<CPDF_Object> pPages = | 1296 std::unique_ptr<CPDF_Object> pPages = |
1300 GetObject(m_PagesObjNum, pHints, &bExist); | 1297 GetObject(m_PagesObjNum, pHints, &bExist); |
1301 if (!bExist) { | 1298 if (!bExist) { |
1302 m_docStatus = PDF_DATAAVAIL_ERROR; | 1299 m_docStatus = PDF_DATAAVAIL_ERROR; |
1303 return false; | 1300 return false; |
1304 } | 1301 } |
1305 | 1302 |
1306 if (!pPages) | 1303 if (!pPages) |
1307 return false; | 1304 return false; |
1308 | 1305 |
1309 CPDF_Dictionary* pPagesDict = pPages->GetDict(); | 1306 CPDF_Dictionary* pPagesDict = pPages->GetDict(); |
1310 if (!pPagesDict) { | 1307 if (!pPagesDict) { |
1311 m_docStatus = PDF_DATAAVAIL_ERROR; | 1308 m_docStatus = PDF_DATAAVAIL_ERROR; |
1312 return false; | 1309 return false; |
1313 } | 1310 } |
1314 | 1311 |
1315 if (!pPagesDict->KeyExist("Kids")) | 1312 if (!pPagesDict->KeyExist("Kids")) |
1316 return true; | 1313 return true; |
1317 | 1314 |
1318 return pPagesDict->GetIntegerFor("Count") > 0; | 1315 return pPagesDict->GetIntegerFor("Count") > 0; |
1319 } | 1316 } |
1320 | 1317 |
1321 bool CPDF_DataAvail::LoadDocPages(DownloadHints* pHints) { | 1318 bool CPDF_DataAvail::LoadDocPages(DownloadHints* pHints) { |
1322 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) | 1319 if (!CheckUnknownPageNode(m_PagesObjNum, &m_PageNode, pHints)) |
1323 return false; | 1320 return false; |
1324 | 1321 |
1325 if (CheckPageCount(pHints)) { | 1322 if (CheckPageCount(pHints)) { |
1326 m_docStatus = PDF_DATAAVAIL_PAGE; | 1323 m_docStatus = PDF_DATAAVAIL_PAGE; |
1327 return true; | 1324 return true; |
1328 } | 1325 } |
1329 | 1326 |
1330 m_bTotalLoadPageTree = true; | 1327 m_bTotalLoadPageTree = true; |
1331 return false; | 1328 return false; |
1332 } | 1329 } |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 if (!pAcroForm) | 1693 if (!pAcroForm) |
1697 return false; | 1694 return false; |
1698 std::vector<CPDF_Object*> obj_array; | 1695 std::vector<CPDF_Object*> obj_array; |
1699 obj_array.push_back(pAcroForm); | 1696 obj_array.push_back(pAcroForm); |
1700 std::vector<CPDF_Object*> dummy; | 1697 std::vector<CPDF_Object*> dummy; |
1701 return AreObjectsAvailable(obj_array, true, nullptr, dummy); | 1698 return AreObjectsAvailable(obj_array, true, nullptr, dummy); |
1702 } | 1699 } |
1703 | 1700 |
1704 CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {} | 1701 CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {} |
1705 | 1702 |
1706 CPDF_DataAvail::PageNode::~PageNode() { | 1703 CPDF_DataAvail::PageNode::~PageNode() {} |
1707 for (int32_t i = 0; i < m_childNode.GetSize(); ++i) | |
1708 delete m_childNode[i]; | |
1709 m_childNode.RemoveAll(); | |
1710 } | |
OLD | NEW |