Chromium Code Reviews| 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) { | |
|
dsinclair
2016/04/21 19:47:09
Is this going to cause a perf regression if you ha
Wei Li
2016/04/21 20:56:44
No since this only runs for one entry, not the who
| |
| 325 // Find the first non-zero position. | |
| 326 if (it.second.pos != 0) { | |
|
dsinclair
2016/04/21 19:47:09
nit: if (it.second_pos == 0)
continue;
Wei Li
2016/04/21 20:56:44
Done.
| |
| 327 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | |
| 328 m_pSyntax->RestorePos(it.second.pos); | |
| 329 bool is_num = false; | |
| 330 CFX_ByteString num_str = m_pSyntax->GetNextWord(&is_num); | |
| 331 m_pSyntax->RestorePos(SavedPos); | |
| 332 if (!is_num || num_str.IsEmpty() || | |
| 333 FXSYS_atoui(num_str.c_str()) != it.first) { | |
| 334 // If the object number read doesn't match the one stored, | |
| 335 // something wrong with the cross reference table. | |
|
dsinclair
2016/04/21 19:47:09
nit: something is wrong
Wei Li
2016/04/21 20:56:44
Done.
| |
| 336 return false; | |
| 337 } | |
| 338 } | |
| 339 } | |
| 340 return true; | |
| 341 } | |
| 342 | |
| 319 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 343 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 320 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) | 344 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) |
| 321 return FALSE; | 345 return FALSE; |
| 322 | 346 |
| 323 m_pTrailer = LoadTrailerV4(); | 347 m_pTrailer = LoadTrailerV4(); |
| 324 if (!m_pTrailer) | 348 if (!m_pTrailer) |
| 325 return FALSE; | 349 return FALSE; |
| 326 | 350 |
| 327 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 351 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 328 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) | 352 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 359 | 383 |
| 360 // SLOW ... | 384 // SLOW ... |
| 361 XRefStreamList.insert(XRefStreamList.begin(), | 385 XRefStreamList.insert(XRefStreamList.begin(), |
| 362 pDict->GetIntegerBy("XRefStm")); | 386 pDict->GetIntegerBy("XRefStm")); |
| 363 m_Trailers.Add(pDict.release()); | 387 m_Trailers.Add(pDict.release()); |
| 364 } | 388 } |
| 365 | 389 |
| 366 for (size_t i = 0; i < CrossRefList.size(); ++i) { | 390 for (size_t i = 0; i < CrossRefList.size(); ++i) { |
| 367 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) | 391 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) |
| 368 return FALSE; | 392 return FALSE; |
| 393 if (i == 0 && !VerifyCrossRefV4()) | |
|
dsinclair
2016/04/21 19:47:09
Why only verify the first one and not all of them?
Wei Li
2016/04/21 20:56:44
This is related to your perf regression question.
dsinclair
2016/04/21 21:02:54
Right, I guess my question is, is there the potent
| |
| 394 return FALSE; | |
| 369 } | 395 } |
| 370 return TRUE; | 396 return TRUE; |
| 371 } | 397 } |
| 372 | 398 |
| 373 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, | 399 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
| 374 uint32_t dwObjCount) { | 400 uint32_t dwObjCount) { |
| 375 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) | 401 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) |
| 376 return FALSE; | 402 return FALSE; |
| 377 | 403 |
| 378 m_pTrailer = LoadTrailerV4(); | 404 m_pTrailer = LoadTrailerV4(); |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1642 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1668 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1643 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1669 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1644 m_LastXRefOffset = 0; | 1670 m_LastXRefOffset = 0; |
| 1645 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1671 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1646 return FORMAT_ERROR; | 1672 return FORMAT_ERROR; |
| 1647 } | 1673 } |
| 1648 | 1674 |
| 1649 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1675 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1650 return SUCCESS; | 1676 return SUCCESS; |
| 1651 } | 1677 } |
| OLD | NEW |