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 |