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/parser/cpdf_parser.h" | 7 #include "core/fpdfapi/parser/cpdf_parser.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 | 137 |
138 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) | 138 if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1)) |
139 m_ObjectInfo[objnum - 1].pos = 0; | 139 m_ObjectInfo[objnum - 1].pos = 0; |
140 } | 140 } |
141 | 141 |
142 CPDF_Parser::Error CPDF_Parser::StartParse(IFX_SeekableReadStream* pFileAccess, | 142 CPDF_Parser::Error CPDF_Parser::StartParse(IFX_SeekableReadStream* pFileAccess, |
143 CPDF_Document* pDocument) { | 143 CPDF_Document* pDocument) { |
144 ASSERT(!m_bHasParsed); | 144 ASSERT(!m_bHasParsed); |
145 m_bHasParsed = true; | 145 m_bHasParsed = true; |
146 | 146 |
147 m_bXRefStream = FALSE; | 147 m_bXRefStream = false; |
148 m_LastXRefOffset = 0; | 148 m_LastXRefOffset = 0; |
149 m_bOwnFileRead = true; | 149 m_bOwnFileRead = true; |
150 | 150 |
151 int32_t offset = GetHeaderOffset(pFileAccess); | 151 int32_t offset = GetHeaderOffset(pFileAccess); |
152 if (offset == -1) { | 152 if (offset == -1) { |
153 if (pFileAccess) | 153 if (pFileAccess) |
154 pFileAccess->Release(); | 154 pFileAccess->Release(); |
155 return FORMAT_ERROR; | 155 return FORMAT_ERROR; |
156 } | 156 } |
157 m_pSyntax->InitParser(pFileAccess, offset); | 157 m_pSyntax->InitParser(pFileAccess, offset); |
158 | 158 |
159 uint8_t ch; | 159 uint8_t ch; |
160 if (!m_pSyntax->GetCharAt(5, ch)) | 160 if (!m_pSyntax->GetCharAt(5, ch)) |
161 return FORMAT_ERROR; | 161 return FORMAT_ERROR; |
162 if (std::isdigit(ch)) | 162 if (std::isdigit(ch)) |
163 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; | 163 m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10; |
164 | 164 |
165 if (!m_pSyntax->GetCharAt(7, ch)) | 165 if (!m_pSyntax->GetCharAt(7, ch)) |
166 return FORMAT_ERROR; | 166 return FORMAT_ERROR; |
167 if (std::isdigit(ch)) | 167 if (std::isdigit(ch)) |
168 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 168 m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
169 | 169 |
170 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) | 170 if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9) |
171 return FORMAT_ERROR; | 171 return FORMAT_ERROR; |
172 | 172 |
173 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); | 173 m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9); |
174 m_pDocument = pDocument; | 174 m_pDocument = pDocument; |
175 | 175 |
176 FX_BOOL bXRefRebuilt = FALSE; | 176 bool bXRefRebuilt = false; |
177 if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) { | 177 if (m_pSyntax->SearchWord("startxref", true, false, 4096)) { |
178 m_SortedOffset.insert(m_pSyntax->SavePos()); | 178 m_SortedOffset.insert(m_pSyntax->SavePos()); |
179 m_pSyntax->GetKeyword(); | 179 m_pSyntax->GetKeyword(); |
180 | 180 |
181 bool bNumber; | 181 bool bNumber; |
182 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); | 182 CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber); |
183 if (!bNumber) | 183 if (!bNumber) |
184 return FORMAT_ERROR; | 184 return FORMAT_ERROR; |
185 | 185 |
186 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str()); | 186 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str()); |
187 if (!LoadAllCrossRefV4(m_LastXRefOffset) && | 187 if (!LoadAllCrossRefV4(m_LastXRefOffset) && |
188 !LoadAllCrossRefV5(m_LastXRefOffset)) { | 188 !LoadAllCrossRefV5(m_LastXRefOffset)) { |
189 if (!RebuildCrossRef()) | 189 if (!RebuildCrossRef()) |
190 return FORMAT_ERROR; | 190 return FORMAT_ERROR; |
191 | 191 |
192 bXRefRebuilt = TRUE; | 192 bXRefRebuilt = true; |
193 m_LastXRefOffset = 0; | 193 m_LastXRefOffset = 0; |
194 } | 194 } |
195 } else { | 195 } else { |
196 if (!RebuildCrossRef()) | 196 if (!RebuildCrossRef()) |
197 return FORMAT_ERROR; | 197 return FORMAT_ERROR; |
198 | 198 |
199 bXRefRebuilt = TRUE; | 199 bXRefRebuilt = true; |
200 } | 200 } |
201 Error eRet = SetEncryptHandler(); | 201 Error eRet = SetEncryptHandler(); |
202 if (eRet != SUCCESS) | 202 if (eRet != SUCCESS) |
203 return eRet; | 203 return eRet; |
204 | 204 |
205 m_pDocument->LoadDoc(); | 205 m_pDocument->LoadDoc(); |
206 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { | 206 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { |
207 if (bXRefRebuilt) | 207 if (bXRefRebuilt) |
208 return FORMAT_ERROR; | 208 return FORMAT_ERROR; |
209 | 209 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // If the object number read doesn't match the one stored, | 316 // If the object number read doesn't match the one stored, |
317 // something is wrong with the cross reference table. | 317 // something is wrong with the cross reference table. |
318 return false; | 318 return false; |
319 } else { | 319 } else { |
320 return true; | 320 return true; |
321 } | 321 } |
322 } | 322 } |
323 return true; | 323 return true; |
324 } | 324 } |
325 | 325 |
326 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 326 bool CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
327 if (!LoadCrossRefV4(xrefpos, 0, TRUE)) | 327 if (!LoadCrossRefV4(xrefpos, 0, true)) |
328 return FALSE; | 328 return false; |
329 | 329 |
330 m_pTrailer = LoadTrailerV4(); | 330 m_pTrailer = LoadTrailerV4(); |
331 if (!m_pTrailer) | 331 if (!m_pTrailer) |
332 return FALSE; | 332 return false; |
333 | 333 |
334 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 334 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
335 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) | 335 if (xrefsize > 0 && xrefsize <= kMaxXRefSize) |
336 ShrinkObjectMap(xrefsize); | 336 ShrinkObjectMap(xrefsize); |
337 | 337 |
338 std::vector<FX_FILESIZE> CrossRefList; | 338 std::vector<FX_FILESIZE> CrossRefList; |
339 std::vector<FX_FILESIZE> XRefStreamList; | 339 std::vector<FX_FILESIZE> XRefStreamList; |
340 std::set<FX_FILESIZE> seen_xrefpos; | 340 std::set<FX_FILESIZE> seen_xrefpos; |
341 | 341 |
342 CrossRefList.push_back(xrefpos); | 342 CrossRefList.push_back(xrefpos); |
343 XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm")); | 343 XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm")); |
344 seen_xrefpos.insert(xrefpos); | 344 seen_xrefpos.insert(xrefpos); |
345 | 345 |
346 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not | 346 // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not |
347 // numerical, GetDirectInteger() returns 0. Loading will end. | 347 // numerical, GetDirectInteger() returns 0. Loading will end. |
348 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 348 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
349 while (xrefpos) { | 349 while (xrefpos) { |
350 // Check for circular references. | 350 // Check for circular references. |
351 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) | 351 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
352 return FALSE; | 352 return false; |
353 | 353 |
354 seen_xrefpos.insert(xrefpos); | 354 seen_xrefpos.insert(xrefpos); |
355 | 355 |
356 // SLOW ... | 356 // SLOW ... |
357 CrossRefList.insert(CrossRefList.begin(), xrefpos); | 357 CrossRefList.insert(CrossRefList.begin(), xrefpos); |
358 LoadCrossRefV4(xrefpos, 0, TRUE); | 358 LoadCrossRefV4(xrefpos, 0, true); |
359 | 359 |
360 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( | 360 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
361 LoadTrailerV4()); | 361 LoadTrailerV4()); |
362 if (!pDict) | 362 if (!pDict) |
363 return FALSE; | 363 return false; |
364 | 364 |
365 xrefpos = GetDirectInteger(pDict.get(), "Prev"); | 365 xrefpos = GetDirectInteger(pDict.get(), "Prev"); |
366 | 366 |
367 // SLOW ... | 367 // SLOW ... |
368 XRefStreamList.insert(XRefStreamList.begin(), | 368 XRefStreamList.insert(XRefStreamList.begin(), |
369 pDict->GetIntegerFor("XRefStm")); | 369 pDict->GetIntegerFor("XRefStm")); |
370 m_Trailers.push_back(pDict.release()); | 370 m_Trailers.push_back(pDict.release()); |
371 } | 371 } |
372 | 372 |
373 for (size_t i = 0; i < CrossRefList.size(); ++i) { | 373 for (size_t i = 0; i < CrossRefList.size(); ++i) { |
374 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) | 374 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], false)) |
375 return FALSE; | 375 return false; |
376 if (i == 0 && !VerifyCrossRefV4()) | 376 if (i == 0 && !VerifyCrossRefV4()) |
377 return FALSE; | 377 return false; |
378 } | 378 } |
379 return TRUE; | 379 return true; |
380 } | 380 } |
381 | 381 |
382 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, | 382 bool CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
383 uint32_t dwObjCount) { | 383 uint32_t dwObjCount) { |
384 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) | 384 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) |
385 return FALSE; | 385 return false; |
386 | 386 |
387 m_pTrailer = LoadTrailerV4(); | 387 m_pTrailer = LoadTrailerV4(); |
388 if (!m_pTrailer) | 388 if (!m_pTrailer) |
389 return FALSE; | 389 return false; |
390 | 390 |
391 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 391 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
392 if (xrefsize == 0) | 392 if (xrefsize == 0) |
393 return FALSE; | 393 return false; |
394 | 394 |
395 std::vector<FX_FILESIZE> CrossRefList; | 395 std::vector<FX_FILESIZE> CrossRefList; |
396 std::vector<FX_FILESIZE> XRefStreamList; | 396 std::vector<FX_FILESIZE> XRefStreamList; |
397 std::set<FX_FILESIZE> seen_xrefpos; | 397 std::set<FX_FILESIZE> seen_xrefpos; |
398 | 398 |
399 CrossRefList.push_back(xrefpos); | 399 CrossRefList.push_back(xrefpos); |
400 XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm")); | 400 XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm")); |
401 seen_xrefpos.insert(xrefpos); | 401 seen_xrefpos.insert(xrefpos); |
402 | 402 |
403 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); | 403 xrefpos = GetDirectInteger(m_pTrailer, "Prev"); |
404 while (xrefpos) { | 404 while (xrefpos) { |
405 // Check for circular references. | 405 // Check for circular references. |
406 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) | 406 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
407 return FALSE; | 407 return false; |
408 | 408 |
409 seen_xrefpos.insert(xrefpos); | 409 seen_xrefpos.insert(xrefpos); |
410 | 410 |
411 // SLOW ... | 411 // SLOW ... |
412 CrossRefList.insert(CrossRefList.begin(), xrefpos); | 412 CrossRefList.insert(CrossRefList.begin(), xrefpos); |
413 LoadCrossRefV4(xrefpos, 0, TRUE); | 413 LoadCrossRefV4(xrefpos, 0, true); |
414 | 414 |
415 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( | 415 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
416 LoadTrailerV4()); | 416 LoadTrailerV4()); |
417 if (!pDict) | 417 if (!pDict) |
418 return FALSE; | 418 return false; |
419 | 419 |
420 xrefpos = GetDirectInteger(pDict.get(), "Prev"); | 420 xrefpos = GetDirectInteger(pDict.get(), "Prev"); |
421 | 421 |
422 // SLOW ... | 422 // SLOW ... |
423 XRefStreamList.insert(XRefStreamList.begin(), | 423 XRefStreamList.insert(XRefStreamList.begin(), |
424 pDict->GetIntegerFor("XRefStm")); | 424 pDict->GetIntegerFor("XRefStm")); |
425 m_Trailers.push_back(pDict.release()); | 425 m_Trailers.push_back(pDict.release()); |
426 } | 426 } |
427 | 427 |
428 for (size_t i = 1; i < CrossRefList.size(); ++i) { | 428 for (size_t i = 1; i < CrossRefList.size(); ++i) { |
429 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE)) | 429 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], false)) |
430 return FALSE; | 430 return false; |
431 } | 431 } |
432 return TRUE; | 432 return true; |
433 } | 433 } |
434 | 434 |
435 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, | 435 bool CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, |
436 uint32_t dwObjCount) { | 436 uint32_t dwObjCount) { |
437 FX_FILESIZE dwStartPos = pos - m_pSyntax->m_HeaderOffset; | 437 FX_FILESIZE dwStartPos = pos - m_pSyntax->m_HeaderOffset; |
438 | 438 |
439 m_pSyntax->RestorePos(dwStartPos); | 439 m_pSyntax->RestorePos(dwStartPos); |
440 m_SortedOffset.insert(pos); | 440 m_SortedOffset.insert(pos); |
441 | 441 |
442 uint32_t start_objnum = 0; | 442 uint32_t start_objnum = 0; |
443 uint32_t count = dwObjCount; | 443 uint32_t count = dwObjCount; |
444 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 444 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
445 | 445 |
446 const int32_t recordsize = 20; | 446 const int32_t recordsize = 20; |
447 std::vector<char> buf(1024 * recordsize + 1); | 447 std::vector<char> buf(1024 * recordsize + 1); |
448 buf[1024 * recordsize] = '\0'; | 448 buf[1024 * recordsize] = '\0'; |
449 | 449 |
450 int32_t nBlocks = count / 1024 + 1; | 450 int32_t nBlocks = count / 1024 + 1; |
451 for (int32_t block = 0; block < nBlocks; block++) { | 451 for (int32_t block = 0; block < nBlocks; block++) { |
452 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | 452 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
453 uint32_t dwReadSize = block_size * recordsize; | 453 uint32_t dwReadSize = block_size * recordsize; |
454 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_pSyntax->m_FileLen) | 454 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_pSyntax->m_FileLen) |
455 return FALSE; | 455 return false; |
456 | 456 |
457 if (!m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), | 457 if (!m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()), |
458 dwReadSize)) { | 458 dwReadSize)) { |
459 return FALSE; | 459 return false; |
460 } | 460 } |
461 | 461 |
462 for (int32_t i = 0; i < block_size; i++) { | 462 for (int32_t i = 0; i < block_size; i++) { |
463 uint32_t objnum = start_objnum + block * 1024 + i; | 463 uint32_t objnum = start_objnum + block * 1024 + i; |
464 char* pEntry = &buf[i * recordsize]; | 464 char* pEntry = &buf[i * recordsize]; |
465 if (pEntry[17] == 'f') { | 465 if (pEntry[17] == 'f') { |
466 m_ObjectInfo[objnum].pos = 0; | 466 m_ObjectInfo[objnum].pos = 0; |
467 m_ObjectInfo[objnum].type = 0; | 467 m_ObjectInfo[objnum].type = 0; |
468 } else { | 468 } else { |
469 int32_t offset = FXSYS_atoi(pEntry); | 469 int32_t offset = FXSYS_atoi(pEntry); |
470 if (offset == 0) { | 470 if (offset == 0) { |
471 for (int32_t c = 0; c < 10; c++) { | 471 for (int32_t c = 0; c < 10; c++) { |
472 if (!std::isdigit(pEntry[c])) | 472 if (!std::isdigit(pEntry[c])) |
473 return FALSE; | 473 return false; |
474 } | 474 } |
475 } | 475 } |
476 | 476 |
477 m_ObjectInfo[objnum].pos = offset; | 477 m_ObjectInfo[objnum].pos = offset; |
478 int32_t version = FXSYS_atoi(pEntry + 11); | 478 int32_t version = FXSYS_atoi(pEntry + 11); |
479 if (version >= 1) | 479 if (version >= 1) |
480 m_bVersionUpdated = true; | 480 m_bVersionUpdated = true; |
481 | 481 |
482 m_ObjectInfo[objnum].gennum = version; | 482 m_ObjectInfo[objnum].gennum = version; |
483 if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen) | 483 if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen) |
484 m_SortedOffset.insert(m_ObjectInfo[objnum].pos); | 484 m_SortedOffset.insert(m_ObjectInfo[objnum].pos); |
485 | 485 |
486 m_ObjectInfo[objnum].type = 1; | 486 m_ObjectInfo[objnum].type = 1; |
487 } | 487 } |
488 } | 488 } |
489 } | 489 } |
490 m_pSyntax->RestorePos(SavedPos + count * recordsize); | 490 m_pSyntax->RestorePos(SavedPos + count * recordsize); |
491 return TRUE; | 491 return true; |
492 } | 492 } |
493 | 493 |
494 bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, | 494 bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, |
495 FX_FILESIZE streampos, | 495 FX_FILESIZE streampos, |
496 FX_BOOL bSkip) { | 496 bool bSkip) { |
497 m_pSyntax->RestorePos(pos); | 497 m_pSyntax->RestorePos(pos); |
498 if (m_pSyntax->GetKeyword() != "xref") | 498 if (m_pSyntax->GetKeyword() != "xref") |
499 return false; | 499 return false; |
500 | 500 |
501 m_SortedOffset.insert(pos); | 501 m_SortedOffset.insert(pos); |
502 if (streampos) | 502 if (streampos) |
503 m_SortedOffset.insert(streampos); | 503 m_SortedOffset.insert(streampos); |
504 | 504 |
505 while (1) { | 505 while (1) { |
506 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 506 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen) | 558 if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen) |
559 m_SortedOffset.insert(m_ObjectInfo[objnum].pos); | 559 m_SortedOffset.insert(m_ObjectInfo[objnum].pos); |
560 | 560 |
561 m_ObjectInfo[objnum].type = 1; | 561 m_ObjectInfo[objnum].type = 1; |
562 } | 562 } |
563 } | 563 } |
564 } | 564 } |
565 } | 565 } |
566 m_pSyntax->RestorePos(SavedPos + count * recordsize); | 566 m_pSyntax->RestorePos(SavedPos + count * recordsize); |
567 } | 567 } |
568 return !streampos || LoadCrossRefV5(&streampos, FALSE); | 568 return !streampos || LoadCrossRefV5(&streampos, false); |
569 } | 569 } |
570 | 570 |
571 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { | 571 bool CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { |
572 if (!LoadCrossRefV5(&xrefpos, TRUE)) | 572 if (!LoadCrossRefV5(&xrefpos, true)) |
573 return FALSE; | 573 return false; |
574 | 574 |
575 std::set<FX_FILESIZE> seen_xrefpos; | 575 std::set<FX_FILESIZE> seen_xrefpos; |
576 while (xrefpos) { | 576 while (xrefpos) { |
577 seen_xrefpos.insert(xrefpos); | 577 seen_xrefpos.insert(xrefpos); |
578 if (!LoadCrossRefV5(&xrefpos, FALSE)) | 578 if (!LoadCrossRefV5(&xrefpos, false)) |
579 return FALSE; | 579 return false; |
580 | 580 |
581 // Check for circular references. | 581 // Check for circular references. |
582 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) | 582 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
583 return FALSE; | 583 return false; |
584 } | 584 } |
585 m_ObjectStreamMap.clear(); | 585 m_ObjectStreamMap.clear(); |
586 m_bXRefStream = TRUE; | 586 m_bXRefStream = true; |
587 return TRUE; | 587 return true; |
588 } | 588 } |
589 | 589 |
590 FX_BOOL CPDF_Parser::RebuildCrossRef() { | 590 bool CPDF_Parser::RebuildCrossRef() { |
591 m_ObjectInfo.clear(); | 591 m_ObjectInfo.clear(); |
592 m_SortedOffset.clear(); | 592 m_SortedOffset.clear(); |
593 if (m_pTrailer) { | 593 if (m_pTrailer) { |
594 m_pTrailer->Release(); | 594 m_pTrailer->Release(); |
595 m_pTrailer = nullptr; | 595 m_pTrailer = nullptr; |
596 } | 596 } |
597 | 597 |
598 ParserState state = ParserState::kDefault; | 598 ParserState state = ParserState::kDefault; |
599 | 599 |
600 int32_t inside_index = 0; | 600 int32_t inside_index = 0; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 | 947 |
948 if (last_xref != -1 && last_xref > last_obj) | 948 if (last_xref != -1 && last_xref > last_obj) |
949 last_trailer = last_xref; | 949 last_trailer = last_xref; |
950 else if (last_trailer == -1 || last_xref < last_obj) | 950 else if (last_trailer == -1 || last_xref < last_obj) |
951 last_trailer = m_pSyntax->m_FileLen; | 951 last_trailer = m_pSyntax->m_FileLen; |
952 | 952 |
953 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); | 953 m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset); |
954 return m_pTrailer && !m_ObjectInfo.empty(); | 954 return m_pTrailer && !m_ObjectInfo.empty(); |
955 } | 955 } |
956 | 956 |
957 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 957 bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) { |
958 std::unique_ptr<CPDF_Object> pObject( | 958 std::unique_ptr<CPDF_Object> pObject( |
959 ParseIndirectObjectAt(m_pDocument, *pos, 0)); | 959 ParseIndirectObjectAt(m_pDocument, *pos, 0)); |
960 if (!pObject) | 960 if (!pObject) |
961 return FALSE; | 961 return false; |
962 | 962 |
963 CPDF_Object* pUnownedObject = pObject.get(); | 963 CPDF_Object* pUnownedObject = pObject.get(); |
964 | 964 |
965 if (m_pDocument) { | 965 if (m_pDocument) { |
966 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); | 966 CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); |
967 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) | 967 if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) |
968 return FALSE; | 968 return false; |
969 // Takes ownership of object (std::move someday). | 969 // Takes ownership of object (std::move someday). |
970 uint32_t objnum = pObject->m_ObjNum; | 970 uint32_t objnum = pObject->m_ObjNum; |
971 if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration( | 971 if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration( |
972 objnum, pObject.release())) { | 972 objnum, pObject.release())) { |
973 return FALSE; | 973 return false; |
974 } | 974 } |
975 } | 975 } |
976 | 976 |
977 CPDF_Stream* pStream = pUnownedObject->AsStream(); | 977 CPDF_Stream* pStream = pUnownedObject->AsStream(); |
978 if (!pStream) | 978 if (!pStream) |
979 return FALSE; | 979 return false; |
980 | 980 |
981 CPDF_Dictionary* pDict = pStream->GetDict(); | 981 CPDF_Dictionary* pDict = pStream->GetDict(); |
982 *pos = pDict->GetIntegerFor("Prev"); | 982 *pos = pDict->GetIntegerFor("Prev"); |
983 int32_t size = pDict->GetIntegerFor("Size"); | 983 int32_t size = pDict->GetIntegerFor("Size"); |
984 if (size < 0) | 984 if (size < 0) |
985 return FALSE; | 985 return false; |
986 | 986 |
987 CPDF_Dictionary* pNewTrailer = ToDictionary(pDict->Clone()); | 987 CPDF_Dictionary* pNewTrailer = ToDictionary(pDict->Clone()); |
988 if (bMainXRef) { | 988 if (bMainXRef) { |
989 m_pTrailer = pNewTrailer; | 989 m_pTrailer = pNewTrailer; |
990 ShrinkObjectMap(size); | 990 ShrinkObjectMap(size); |
991 for (auto& it : m_ObjectInfo) | 991 for (auto& it : m_ObjectInfo) |
992 it.second.type = 0; | 992 it.second.type = 0; |
993 } else { | 993 } else { |
994 m_Trailers.push_back(pNewTrailer); | 994 m_Trailers.push_back(pNewTrailer); |
995 } | 995 } |
(...skipping 12 matching lines...) Expand all Loading... |
1008 arrIndex.push_back(std::make_pair(nStartNum, nCount)); | 1008 arrIndex.push_back(std::make_pair(nStartNum, nCount)); |
1009 } | 1009 } |
1010 } | 1010 } |
1011 } | 1011 } |
1012 | 1012 |
1013 if (arrIndex.size() == 0) | 1013 if (arrIndex.size() == 0) |
1014 arrIndex.push_back(std::make_pair(0, size)); | 1014 arrIndex.push_back(std::make_pair(0, size)); |
1015 | 1015 |
1016 pArray = pDict->GetArrayFor("W"); | 1016 pArray = pDict->GetArrayFor("W"); |
1017 if (!pArray) | 1017 if (!pArray) |
1018 return FALSE; | 1018 return false; |
1019 | 1019 |
1020 CFX_ArrayTemplate<uint32_t> WidthArray; | 1020 CFX_ArrayTemplate<uint32_t> WidthArray; |
1021 FX_SAFE_UINT32 dwAccWidth = 0; | 1021 FX_SAFE_UINT32 dwAccWidth = 0; |
1022 for (size_t i = 0; i < pArray->GetCount(); ++i) { | 1022 for (size_t i = 0; i < pArray->GetCount(); ++i) { |
1023 WidthArray.Add(pArray->GetIntegerAt(i)); | 1023 WidthArray.Add(pArray->GetIntegerAt(i)); |
1024 dwAccWidth += WidthArray[i]; | 1024 dwAccWidth += WidthArray[i]; |
1025 } | 1025 } |
1026 | 1026 |
1027 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) | 1027 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) |
1028 return FALSE; | 1028 return false; |
1029 | 1029 |
1030 uint32_t totalWidth = dwAccWidth.ValueOrDie(); | 1030 uint32_t totalWidth = dwAccWidth.ValueOrDie(); |
1031 CPDF_StreamAcc acc; | 1031 CPDF_StreamAcc acc; |
1032 acc.LoadAllData(pStream); | 1032 acc.LoadAllData(pStream); |
1033 | 1033 |
1034 const uint8_t* pData = acc.GetData(); | 1034 const uint8_t* pData = acc.GetData(); |
1035 uint32_t dwTotalSize = acc.GetSize(); | 1035 uint32_t dwTotalSize = acc.GetSize(); |
1036 uint32_t segindex = 0; | 1036 uint32_t segindex = 0; |
1037 for (uint32_t i = 0; i < arrIndex.size(); i++) { | 1037 for (uint32_t i = 0; i < arrIndex.size(); i++) { |
1038 int32_t startnum = arrIndex[i].first; | 1038 int32_t startnum = arrIndex[i].first; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 if (type == 0) { | 1079 if (type == 0) { |
1080 m_ObjectInfo[startnum + j].pos = 0; | 1080 m_ObjectInfo[startnum + j].pos = 0; |
1081 } else { | 1081 } else { |
1082 FX_FILESIZE offset = | 1082 FX_FILESIZE offset = |
1083 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); | 1083 GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
1084 m_ObjectInfo[startnum + j].pos = offset; | 1084 m_ObjectInfo[startnum + j].pos = offset; |
1085 if (type == 1) { | 1085 if (type == 1) { |
1086 m_SortedOffset.insert(offset); | 1086 m_SortedOffset.insert(offset); |
1087 } else { | 1087 } else { |
1088 if (offset < 0 || !IsValidObjectNumber(offset)) | 1088 if (offset < 0 || !IsValidObjectNumber(offset)) |
1089 return FALSE; | 1089 return false; |
1090 m_ObjectInfo[offset].type = 255; | 1090 m_ObjectInfo[offset].type = 255; |
1091 } | 1091 } |
1092 } | 1092 } |
1093 } | 1093 } |
1094 segindex += count; | 1094 segindex += count; |
1095 } | 1095 } |
1096 return TRUE; | 1096 return true; |
1097 } | 1097 } |
1098 | 1098 |
1099 CPDF_Array* CPDF_Parser::GetIDArray() { | 1099 CPDF_Array* CPDF_Parser::GetIDArray() { |
1100 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr; | 1100 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr; |
1101 if (!pID) | 1101 if (!pID) |
1102 return nullptr; | 1102 return nullptr; |
1103 | 1103 |
1104 if (CPDF_Reference* pRef = pID->AsReference()) { | 1104 if (CPDF_Reference* pRef = pID->AsReference()) { |
1105 pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()); | 1105 pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()); |
1106 m_pTrailer->SetFor("ID", pID); | 1106 m_pTrailer->SetFor("ID", pID); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 return ParseIndirectObjectAt(pObjList, pos, objnum); | 1138 return ParseIndirectObjectAt(pObjList, pos, objnum); |
1139 } | 1139 } |
1140 if (GetObjectType(objnum) != 2) | 1140 if (GetObjectType(objnum) != 2) |
1141 return nullptr; | 1141 return nullptr; |
1142 | 1142 |
1143 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1143 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
1144 if (!pObjStream) | 1144 if (!pObjStream) |
1145 return nullptr; | 1145 return nullptr; |
1146 | 1146 |
1147 ScopedFileStream file(FX_CreateMemoryStream( | 1147 ScopedFileStream file(FX_CreateMemoryStream( |
1148 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); | 1148 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false)); |
1149 CPDF_SyntaxParser syntax; | 1149 CPDF_SyntaxParser syntax; |
1150 syntax.InitParser(file.get(), 0); | 1150 syntax.InitParser(file.get(), 0); |
1151 const int32_t offset = GetStreamFirst(pObjStream); | 1151 const int32_t offset = GetStreamFirst(pObjStream); |
1152 | 1152 |
1153 // Read object numbers from |pObjStream| into a cache. | 1153 // Read object numbers from |pObjStream| into a cache. |
1154 if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) { | 1154 if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) { |
1155 for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { | 1155 for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { |
1156 uint32_t thisnum = syntax.GetDirectNum(); | 1156 uint32_t thisnum = syntax.GetDirectNum(); |
1157 uint32_t thisoff = syntax.GetDirectNum(); | 1157 uint32_t thisoff = syntax.GetDirectNum(); |
1158 m_ObjCache[pObjStream][thisnum] = thisoff; | 1158 m_ObjCache[pObjStream][thisnum] = thisoff; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 | 1217 |
1218 if (GetObjectType(objnum) == 2) { | 1218 if (GetObjectType(objnum) == 2) { |
1219 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); | 1219 CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); |
1220 if (!pObjStream) | 1220 if (!pObjStream) |
1221 return; | 1221 return; |
1222 | 1222 |
1223 int32_t offset = GetStreamFirst(pObjStream); | 1223 int32_t offset = GetStreamFirst(pObjStream); |
1224 const uint8_t* pData = pObjStream->GetData(); | 1224 const uint8_t* pData = pObjStream->GetData(); |
1225 uint32_t totalsize = pObjStream->GetSize(); | 1225 uint32_t totalsize = pObjStream->GetSize(); |
1226 ScopedFileStream file( | 1226 ScopedFileStream file( |
1227 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); | 1227 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, false)); |
1228 | 1228 |
1229 CPDF_SyntaxParser syntax; | 1229 CPDF_SyntaxParser syntax; |
1230 syntax.InitParser(file.get(), 0); | 1230 syntax.InitParser(file.get(), 0); |
1231 for (int i = GetStreamNCount(pObjStream); i > 0; --i) { | 1231 for (int i = GetStreamNCount(pObjStream); i > 0; --i) { |
1232 uint32_t thisnum = syntax.GetDirectNum(); | 1232 uint32_t thisnum = syntax.GetDirectNum(); |
1233 uint32_t thisoff = syntax.GetDirectNum(); | 1233 uint32_t thisoff = syntax.GetDirectNum(); |
1234 if (thisnum != objnum) | 1234 if (thisnum != objnum) |
1235 continue; | 1235 continue; |
1236 | 1236 |
1237 if (i == 1) { | 1237 if (i == 1) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 return; | 1283 return; |
1284 } | 1284 } |
1285 | 1285 |
1286 auto it = m_SortedOffset.find(pos); | 1286 auto it = m_SortedOffset.find(pos); |
1287 if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end()) { | 1287 if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end()) { |
1288 m_pSyntax->RestorePos(SavedPos); | 1288 m_pSyntax->RestorePos(SavedPos); |
1289 return; | 1289 return; |
1290 } | 1290 } |
1291 | 1291 |
1292 FX_FILESIZE nextoff = *it; | 1292 FX_FILESIZE nextoff = *it; |
1293 FX_BOOL bNextOffValid = FALSE; | 1293 bool bNextOffValid = false; |
1294 if (nextoff != pos) { | 1294 if (nextoff != pos) { |
1295 m_pSyntax->RestorePos(nextoff); | 1295 m_pSyntax->RestorePos(nextoff); |
1296 word = m_pSyntax->GetNextWord(&bIsNumber); | 1296 word = m_pSyntax->GetNextWord(&bIsNumber); |
1297 if (word == "xref") { | 1297 if (word == "xref") { |
1298 bNextOffValid = TRUE; | 1298 bNextOffValid = true; |
1299 } else if (bIsNumber) { | 1299 } else if (bIsNumber) { |
1300 word = m_pSyntax->GetNextWord(&bIsNumber); | 1300 word = m_pSyntax->GetNextWord(&bIsNumber); |
1301 if (bIsNumber && m_pSyntax->GetKeyword() == "obj") { | 1301 if (bIsNumber && m_pSyntax->GetKeyword() == "obj") { |
1302 bNextOffValid = TRUE; | 1302 bNextOffValid = true; |
1303 } | 1303 } |
1304 } | 1304 } |
1305 } | 1305 } |
1306 | 1306 |
1307 if (!bNextOffValid) { | 1307 if (!bNextOffValid) { |
1308 m_pSyntax->RestorePos(pos); | 1308 m_pSyntax->RestorePos(pos); |
1309 while (1) { | 1309 while (1) { |
1310 if (m_pSyntax->GetKeyword() == "endobj") | 1310 if (m_pSyntax->GetKeyword() == "endobj") |
1311 break; | 1311 break; |
1312 | 1312 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 | 1431 |
1432 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); | 1432 uint32_t dwPermission = m_pSecurityHandler->GetPermissions(); |
1433 if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") { | 1433 if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") { |
1434 // See PDF Reference 1.7, page 123, table 3.20. | 1434 // See PDF Reference 1.7, page 123, table 3.20. |
1435 dwPermission &= 0xFFFFFFFC; | 1435 dwPermission &= 0xFFFFFFFC; |
1436 dwPermission |= 0xFFFFF0C0; | 1436 dwPermission |= 0xFFFFF0C0; |
1437 } | 1437 } |
1438 return dwPermission; | 1438 return dwPermission; |
1439 } | 1439 } |
1440 | 1440 |
1441 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_SeekableReadStream* pFileAccess, | 1441 bool CPDF_Parser::IsLinearizedFile(IFX_SeekableReadStream* pFileAccess, |
1442 uint32_t offset) { | 1442 uint32_t offset) { |
1443 m_pSyntax->InitParser(pFileAccess, offset); | 1443 m_pSyntax->InitParser(pFileAccess, offset); |
1444 m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9); | 1444 m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9); |
1445 | 1445 |
1446 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 1446 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
1447 bool bIsNumber; | 1447 bool bIsNumber; |
1448 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); | 1448 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); |
1449 if (!bIsNumber) | 1449 if (!bIsNumber) |
1450 return FALSE; | 1450 return false; |
1451 | 1451 |
1452 uint32_t objnum = FXSYS_atoui(word.c_str()); | 1452 uint32_t objnum = FXSYS_atoui(word.c_str()); |
1453 word = m_pSyntax->GetNextWord(&bIsNumber); | 1453 word = m_pSyntax->GetNextWord(&bIsNumber); |
1454 if (!bIsNumber) | 1454 if (!bIsNumber) |
1455 return FALSE; | 1455 return false; |
1456 | 1456 |
1457 uint32_t gennum = FXSYS_atoui(word.c_str()); | 1457 uint32_t gennum = FXSYS_atoui(word.c_str()); |
1458 if (m_pSyntax->GetKeyword() != "obj") { | 1458 if (m_pSyntax->GetKeyword() != "obj") { |
1459 m_pSyntax->RestorePos(SavedPos); | 1459 m_pSyntax->RestorePos(SavedPos); |
1460 return FALSE; | 1460 return false; |
1461 } | 1461 } |
1462 | 1462 |
1463 m_pLinearized = m_pSyntax->GetObject(nullptr, objnum, gennum, true); | 1463 m_pLinearized = m_pSyntax->GetObject(nullptr, objnum, gennum, true); |
1464 if (!m_pLinearized) | 1464 if (!m_pLinearized) |
1465 return FALSE; | 1465 return false; |
1466 | 1466 |
1467 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | 1467 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
1468 if (pDict && pDict->GetObjectFor("Linearized")) { | 1468 if (pDict && pDict->GetObjectFor("Linearized")) { |
1469 m_pSyntax->GetNextWord(nullptr); | 1469 m_pSyntax->GetNextWord(nullptr); |
1470 | 1470 |
1471 CPDF_Object* pLen = pDict->GetObjectFor("L"); | 1471 CPDF_Object* pLen = pDict->GetObjectFor("L"); |
1472 if (!pLen) { | 1472 if (!pLen) { |
1473 m_pLinearized->Release(); | 1473 m_pLinearized->Release(); |
1474 m_pLinearized = nullptr; | 1474 m_pLinearized = nullptr; |
1475 return FALSE; | 1475 return false; |
1476 } | 1476 } |
1477 | 1477 |
1478 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) | 1478 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) |
1479 return FALSE; | 1479 return false; |
1480 | 1480 |
1481 if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P"))) | 1481 if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P"))) |
1482 m_dwFirstPageNo = pNo->GetInteger(); | 1482 m_dwFirstPageNo = pNo->GetInteger(); |
1483 | 1483 |
1484 if (CPDF_Number* pTable = ToNumber(pDict->GetObjectFor("T"))) | 1484 if (CPDF_Number* pTable = ToNumber(pDict->GetObjectFor("T"))) |
1485 m_LastXRefOffset = pTable->GetInteger(); | 1485 m_LastXRefOffset = pTable->GetInteger(); |
1486 | 1486 |
1487 return TRUE; | 1487 return true; |
1488 } | 1488 } |
1489 m_pLinearized->Release(); | 1489 m_pLinearized->Release(); |
1490 m_pLinearized = nullptr; | 1490 m_pLinearized = nullptr; |
1491 return FALSE; | 1491 return false; |
1492 } | 1492 } |
1493 | 1493 |
1494 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1494 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( |
1495 IFX_SeekableReadStream* pFileAccess, | 1495 IFX_SeekableReadStream* pFileAccess, |
1496 CPDF_Document* pDocument) { | 1496 CPDF_Document* pDocument) { |
1497 ASSERT(!m_bHasParsed); | 1497 ASSERT(!m_bHasParsed); |
1498 | 1498 |
1499 m_bXRefStream = FALSE; | 1499 m_bXRefStream = false; |
1500 m_LastXRefOffset = 0; | 1500 m_LastXRefOffset = 0; |
1501 m_bOwnFileRead = true; | 1501 m_bOwnFileRead = true; |
1502 | 1502 |
1503 int32_t offset = GetHeaderOffset(pFileAccess); | 1503 int32_t offset = GetHeaderOffset(pFileAccess); |
1504 if (offset == -1) | 1504 if (offset == -1) |
1505 return FORMAT_ERROR; | 1505 return FORMAT_ERROR; |
1506 | 1506 |
1507 if (!IsLinearizedFile(pFileAccess, offset)) { | 1507 if (!IsLinearizedFile(pFileAccess, offset)) { |
1508 m_pSyntax->m_pFileAccess = nullptr; | 1508 m_pSyntax->m_pFileAccess = nullptr; |
1509 return StartParse(pFileAccess, std::move(pDocument)); | 1509 return StartParse(pFileAccess, std::move(pDocument)); |
1510 } | 1510 } |
1511 m_bHasParsed = true; | 1511 m_bHasParsed = true; |
1512 m_pDocument = pDocument; | 1512 m_pDocument = pDocument; |
1513 | 1513 |
1514 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1514 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
1515 | 1515 |
1516 FX_BOOL bXRefRebuilt = FALSE; | 1516 bool bXRefRebuilt = false; |
1517 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); | 1517 bool bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, false); |
1518 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1518 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, true)) { |
1519 if (!RebuildCrossRef()) | 1519 if (!RebuildCrossRef()) |
1520 return FORMAT_ERROR; | 1520 return FORMAT_ERROR; |
1521 | 1521 |
1522 bXRefRebuilt = TRUE; | 1522 bXRefRebuilt = true; |
1523 m_LastXRefOffset = 0; | 1523 m_LastXRefOffset = 0; |
1524 } | 1524 } |
1525 | 1525 |
1526 if (bLoadV4) { | 1526 if (bLoadV4) { |
1527 m_pTrailer = LoadTrailerV4(); | 1527 m_pTrailer = LoadTrailerV4(); |
1528 if (!m_pTrailer) | 1528 if (!m_pTrailer) |
1529 return SUCCESS; | 1529 return SUCCESS; |
1530 | 1530 |
1531 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1531 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
1532 if (xrefsize > 0) | 1532 if (xrefsize > 0) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 } | 1566 } |
1567 | 1567 |
1568 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { | 1568 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { |
1569 if (CPDF_Reference* pMetadata = | 1569 if (CPDF_Reference* pMetadata = |
1570 ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata"))) | 1570 ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata"))) |
1571 m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum(); | 1571 m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum(); |
1572 } | 1572 } |
1573 return SUCCESS; | 1573 return SUCCESS; |
1574 } | 1574 } |
1575 | 1575 |
1576 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { | 1576 bool CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { |
1577 if (!LoadCrossRefV5(&xrefpos, FALSE)) | 1577 if (!LoadCrossRefV5(&xrefpos, false)) |
1578 return FALSE; | 1578 return false; |
1579 | 1579 |
1580 std::set<FX_FILESIZE> seen_xrefpos; | 1580 std::set<FX_FILESIZE> seen_xrefpos; |
1581 while (xrefpos) { | 1581 while (xrefpos) { |
1582 seen_xrefpos.insert(xrefpos); | 1582 seen_xrefpos.insert(xrefpos); |
1583 if (!LoadCrossRefV5(&xrefpos, FALSE)) | 1583 if (!LoadCrossRefV5(&xrefpos, false)) |
1584 return FALSE; | 1584 return false; |
1585 | 1585 |
1586 // Check for circular references. | 1586 // Check for circular references. |
1587 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) | 1587 if (pdfium::ContainsKey(seen_xrefpos, xrefpos)) |
1588 return FALSE; | 1588 return false; |
1589 } | 1589 } |
1590 m_ObjectStreamMap.clear(); | 1590 m_ObjectStreamMap.clear(); |
1591 m_bXRefStream = TRUE; | 1591 m_bXRefStream = true; |
1592 return TRUE; | 1592 return true; |
1593 } | 1593 } |
1594 | 1594 |
1595 CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() { | 1595 CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() { |
1596 uint32_t dwSaveMetadataObjnum = m_pSyntax->m_MetadataObjnum; | 1596 uint32_t dwSaveMetadataObjnum = m_pSyntax->m_MetadataObjnum; |
1597 m_pSyntax->m_MetadataObjnum = 0; | 1597 m_pSyntax->m_MetadataObjnum = 0; |
1598 if (m_pTrailer) { | 1598 if (m_pTrailer) { |
1599 m_pTrailer->Release(); | 1599 m_pTrailer->Release(); |
1600 m_pTrailer = nullptr; | 1600 m_pTrailer = nullptr; |
1601 } | 1601 } |
1602 | 1602 |
(...skipping 16 matching lines...) Expand all Loading... |
1619 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1619 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
1620 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1620 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
1621 m_LastXRefOffset = 0; | 1621 m_LastXRefOffset = 0; |
1622 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1622 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1623 return FORMAT_ERROR; | 1623 return FORMAT_ERROR; |
1624 } | 1624 } |
1625 | 1625 |
1626 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1626 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1627 return SUCCESS; | 1627 return SUCCESS; |
1628 } | 1628 } |
OLD | NEW |