| 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 |