| 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/fpdf_parser/include/cpdf_parser.h" | 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 if (GetObjectType(objnum) == 1) | 309 if (GetObjectType(objnum) == 1) |
| 310 return GetObjectPositionOrZero(objnum); | 310 return GetObjectPositionOrZero(objnum); |
| 311 | 311 |
| 312 if (GetObjectType(objnum) == 2) { | 312 if (GetObjectType(objnum) == 2) { |
| 313 FX_FILESIZE pos = GetObjectPositionOrZero(objnum); | 313 FX_FILESIZE pos = GetObjectPositionOrZero(objnum); |
| 314 return GetObjectPositionOrZero(pos); | 314 return GetObjectPositionOrZero(pos); |
| 315 } | 315 } |
| 316 return 0; | 316 return 0; |
| 317 } | 317 } |
| 318 | 318 |
| 319 // Ideally, all the cross reference entries should be verified. |
| 320 // In reality, we rarely see well-formed cross references don't match |
| 321 // with the objects. crbug/602650 showed a case where object numbers |
| 322 // in the cross reference table are all off by one. |
| 323 bool CPDF_Parser::VerifyCrossRefV4() { |
| 324 for (const auto& it : m_ObjectInfo) { |
| 325 if (it.second.pos == 0) |
| 326 continue; |
| 327 // Find the first non-zero position. |
| 328 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
| 329 m_pSyntax->RestorePos(it.second.pos); |
| 330 bool is_num = false; |
| 331 CFX_ByteString num_str = m_pSyntax->GetNextWord(&is_num); |
| 332 m_pSyntax->RestorePos(SavedPos); |
| 333 if (!is_num || num_str.IsEmpty() || |
| 334 FXSYS_atoui(num_str.c_str()) != it.first) { |
| 335 // If the object number read doesn't match the one stored, |
| 336 // something is wrong with the cross reference table. |
| 337 return false; |
| 338 } else { |
| 339 return true; |
| 340 } |
| 341 } |
| 342 return true; |
| 343 } |
| 344 |
| 319 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 345 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 320 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) | 346 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) |
| 321 return FALSE; | 347 return FALSE; |
| 322 | 348 |
| 323 m_pTrailer = LoadTrailerV4(); | 349 m_pTrailer = LoadTrailerV4(); |
| 324 if (!m_pTrailer) | 350 if (!m_pTrailer) |
| 325 return FALSE; | 351 return FALSE; |
| 326 | 352 |
| 327 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 353 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 328 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) | 354 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 359 | 385 |
| 360 // SLOW ... | 386 // SLOW ... |
| 361 XRefStreamList.insert(XRefStreamList.begin(), | 387 XRefStreamList.insert(XRefStreamList.begin(), |
| 362 pDict->GetIntegerBy("XRefStm")); | 388 pDict->GetIntegerBy("XRefStm")); |
| 363 m_Trailers.Add(pDict.release()); | 389 m_Trailers.Add(pDict.release()); |
| 364 } | 390 } |
| 365 | 391 |
| 366 for (size_t i = 0; i < CrossRefList.size(); ++i) { | 392 for (size_t i = 0; i < CrossRefList.size(); ++i) { |
| 367 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) | 393 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) |
| 368 return FALSE; | 394 return FALSE; |
| 395 if (i == 0 && !VerifyCrossRefV4()) |
| 396 return FALSE; |
| 369 } | 397 } |
| 370 return TRUE; | 398 return TRUE; |
| 371 } | 399 } |
| 372 | 400 |
| 373 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, | 401 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
| 374 uint32_t dwObjCount) { | 402 uint32_t dwObjCount) { |
| 375 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) | 403 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) |
| 376 return FALSE; | 404 return FALSE; |
| 377 | 405 |
| 378 m_pTrailer = LoadTrailerV4(); | 406 m_pTrailer = LoadTrailerV4(); |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1670 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1643 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1671 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1644 m_LastXRefOffset = 0; | 1672 m_LastXRefOffset = 0; |
| 1645 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1673 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1646 return FORMAT_ERROR; | 1674 return FORMAT_ERROR; |
| 1647 } | 1675 } |
| 1648 | 1676 |
| 1649 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1677 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1650 return SUCCESS; | 1678 return SUCCESS; |
| 1651 } | 1679 } |
| OLD | NEW |