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

Side by Side Diff: core/fpdfapi/parser/cpdf_data_avail.cpp

Issue 2598473002: Use vector of unique_ptrs for page node children. (Closed)
Patch Set: Avoid appearance of infinite loop Created 3 years, 12 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
« no previous file with comments | « core/fpdfapi/parser/cpdf_data_avail.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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 }
OLDNEW
« no previous file with comments | « core/fpdfapi/parser/cpdf_data_avail.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698