| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 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 "parser_int.h" | 7 #include "parser_int.h" |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 } | 367 } |
| 368 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 368 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 369 if (xrefsize <= 0 || xrefsize > kMaxXRefSize) { | 369 if (xrefsize <= 0 || xrefsize > kMaxXRefSize) { |
| 370 return FALSE; | 370 return FALSE; |
| 371 } | 371 } |
| 372 m_ObjectInfo[0].pos = 0; | 372 m_ObjectInfo[0].pos = 0; |
| 373 m_V5Type.SetSize(xrefsize); | 373 m_V5Type.SetSize(xrefsize); |
| 374 CFX_FileSizeArray CrossRefList, XRefStreamList; | 374 CFX_FileSizeArray CrossRefList, XRefStreamList; |
| 375 CrossRefList.Add(xrefpos); | 375 CrossRefList.Add(xrefpos); |
| 376 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); | 376 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); |
| 377 if (!CheckDirectType(m_pTrailer, "Prev", PDFOBJ_NUMBER)) { | 377 |
| 378 return FALSE; | 378 std::set<FX_FILESIZE> seen_xrefpos; |
| 379 } | 379 seen_xrefpos.insert(xrefpos); |
| 380 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 380 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not |
| 381 if (newxrefpos == xrefpos) { | 381 // numerical, GetDirectInteger() returns 0. Loading will end. |
| 382 return FALSE; | 382 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
| 383 } | |
| 384 xrefpos = newxrefpos; | |
| 385 while (xrefpos) { | 383 while (xrefpos) { |
| 384 // Check for circular references. |
| 385 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
| 386 return FALSE; |
| 387 seen_xrefpos.insert(xrefpos); |
| 386 CrossRefList.InsertAt(0, xrefpos); | 388 CrossRefList.InsertAt(0, xrefpos); |
| 387 LoadCrossRefV4(xrefpos, 0, TRUE); | 389 LoadCrossRefV4(xrefpos, 0, TRUE); |
| 388 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( | 390 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 389 LoadTrailerV4()); | 391 LoadTrailerV4()); |
| 390 if (!pDict) | 392 if (!pDict) |
| 391 return FALSE; | 393 return FALSE; |
| 394 xrefpos = GetDirectInteger(pDict.get(), "Prev"); |
| 392 | 395 |
| 393 if (!CheckDirectType(pDict.get(), "Prev", PDFOBJ_NUMBER)) | |
| 394 return FALSE; | |
| 395 | |
| 396 newxrefpos = GetDirectInteger(pDict.get(), "Prev"); | |
| 397 if (newxrefpos == xrefpos) | |
| 398 return FALSE; | |
| 399 | |
| 400 xrefpos = newxrefpos; | |
| 401 XRefStreamList.InsertAt(0, pDict->GetInteger("XRefStm")); | 396 XRefStreamList.InsertAt(0, pDict->GetInteger("XRefStm")); |
| 402 m_Trailers.Add(pDict.release()); | 397 m_Trailers.Add(pDict.release()); |
| 403 } | 398 } |
| 404 for (int32_t i = 0; i < CrossRefList.GetSize(); i++) { | 399 for (int32_t i = 0; i < CrossRefList.GetSize(); i++) { |
| 405 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) | 400 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) |
| 406 return FALSE; | 401 return FALSE; |
| 407 } | 402 } |
| 408 return TRUE; | 403 return TRUE; |
| 409 } | 404 } |
| 410 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, | 405 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
| 411 FX_DWORD dwObjCount) { | 406 FX_DWORD dwObjCount) { |
| 412 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { | 407 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { |
| 413 return FALSE; | 408 return FALSE; |
| 414 } | 409 } |
| 415 m_pTrailer = LoadTrailerV4(); | 410 m_pTrailer = LoadTrailerV4(); |
| 416 if (!m_pTrailer) { | 411 if (!m_pTrailer) { |
| 417 return FALSE; | 412 return FALSE; |
| 418 } | 413 } |
| 419 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 414 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 420 if (xrefsize == 0) { | 415 if (xrefsize == 0) { |
| 421 return FALSE; | 416 return FALSE; |
| 422 } | 417 } |
| 423 CFX_FileSizeArray CrossRefList, XRefStreamList; | 418 CFX_FileSizeArray CrossRefList, XRefStreamList; |
| 424 CrossRefList.Add(xrefpos); | 419 CrossRefList.Add(xrefpos); |
| 425 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); | 420 XRefStreamList.Add(GetDirectInteger(m_pTrailer, "XRefStm")); |
| 421 |
| 422 std::set<FX_FILESIZE> seen_xrefpos; |
| 423 seen_xrefpos.insert(xrefpos); |
| 426 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 424 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
| 427 while (xrefpos) { | 425 while (xrefpos) { |
| 426 // Check for circular references. |
| 427 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
| 428 return FALSE; |
| 429 seen_xrefpos.insert(xrefpos); |
| 428 CrossRefList.InsertAt(0, xrefpos); | 430 CrossRefList.InsertAt(0, xrefpos); |
| 429 LoadCrossRefV4(xrefpos, 0, TRUE); | 431 LoadCrossRefV4(xrefpos, 0, TRUE); |
| 430 CPDF_Dictionary* pDict = LoadTrailerV4(); | 432 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 433 LoadTrailerV4()); |
| 431 if (!pDict) { | 434 if (!pDict) { |
| 432 return FALSE; | 435 return FALSE; |
| 433 } | 436 } |
| 434 xrefpos = GetDirectInteger(pDict, "Prev"); | 437 xrefpos = GetDirectInteger(pDict.get(), "Prev"); |
| 438 |
| 435 XRefStreamList.InsertAt(0, pDict->GetInteger("XRefStm")); | 439 XRefStreamList.InsertAt(0, pDict->GetInteger("XRefStm")); |
| 436 m_Trailers.Add(pDict); | 440 m_Trailers.Add(pDict.release()); |
| 437 } | 441 } |
| 438 for (int32_t i = 1; i < CrossRefList.GetSize(); i++) | 442 for (int32_t i = 1; i < CrossRefList.GetSize(); i++) |
| 439 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) { | 443 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) { |
| 440 return FALSE; | 444 return FALSE; |
| 441 } | 445 } |
| 442 return TRUE; | 446 return TRUE; |
| 443 } | 447 } |
| 444 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, | 448 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, |
| 445 FX_DWORD dwObjCount) { | 449 FX_DWORD dwObjCount) { |
| 446 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; | 450 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; |
| (...skipping 4540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4987 if (!m_pLinearizedDict) | 4991 if (!m_pLinearizedDict) |
| 4988 return -1; | 4992 return -1; |
| 4989 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4993 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4990 if (!pRange) | 4994 if (!pRange) |
| 4991 return -1; | 4995 return -1; |
| 4992 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4996 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4993 if (!pStreamLen) | 4997 if (!pStreamLen) |
| 4994 return -1; | 4998 return -1; |
| 4995 return pStreamLen->GetInteger(); | 4999 return pStreamLen->GetInteger(); |
| 4996 } | 5000 } |
| OLD | NEW |