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 |