| 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/cpdf_hint_tables.h" | 7 #include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h" |
| 8 | 8 |
| 9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" | 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" |
| 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
| 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
| 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
| 15 #include "core/fxcrt/include/fx_safe_types.h" | 15 #include "core/fxcrt/include/fx_safe_types.h" |
| 16 #include "third_party/base/numerics/safe_conversions.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 bool CanReadFromBitStream(const CFX_BitStream* hStream, | 20 bool CanReadFromBitStream(const CFX_BitStream* hStream, |
| 20 const FX_SAFE_UINT32& bits) { | 21 const FX_SAFE_UINT32& bits) { |
| 21 return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie(); | 22 return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie(); |
| 22 } | 23 } |
| 23 | 24 |
| 24 // Sanity check values from the page table header. The note in the PDF 1.7 | 25 // Sanity check values from the page table header. The note in the PDF 1.7 |
| 25 // reference for Table F.3 says the valid range is only 0 through 32. Though 0 | 26 // reference for Table F.3 says the valid range is only 0 through 32. Though 0 |
| 26 // is not useful either. | 27 // is not useful either. |
| 27 bool IsValidPageOffsetHintTableBitCount(uint32_t bits) { | 28 bool IsValidPageOffsetHintTableBitCount(uint32_t bits) { |
| 28 return bits > 0 && bits <= 32; | 29 return bits > 0 && bits <= 32; |
| 29 } | 30 } |
| 30 | 31 |
| 31 } // namespace | 32 } // namespace |
| 32 | 33 |
| 33 CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail, | 34 CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail, |
| 34 CPDF_Dictionary* pLinearized) | 35 CPDF_Dictionary* pLinearized) |
| 35 : m_pDataAvail(pDataAvail), | 36 : m_pDataAvail(pDataAvail), |
| 36 m_pLinearizedDict(pLinearized), | 37 m_pLinearizedDict(pLinearized), |
| 37 m_nFirstPageSharedObjs(0), | 38 m_nFirstPageSharedObjs(0), |
| 38 m_szFirstPageObjOffset(0) { | 39 m_szFirstPageObjOffset(0) { |
| 39 ASSERT(m_pLinearizedDict); | 40 ASSERT(m_pLinearizedDict); |
| 40 } | 41 } |
| 41 | 42 |
| 42 CPDF_HintTables::~CPDF_HintTables() {} | 43 CPDF_HintTables::~CPDF_HintTables() {} |
| 43 | 44 |
| 44 uint32_t CPDF_HintTables::GetItemLength( | 45 uint32_t CPDF_HintTables::GetItemLength( |
| 45 int index, | 46 uint32_t index, |
| 46 const std::vector<FX_FILESIZE>& szArray) { | 47 const std::vector<FX_FILESIZE>& szArray) { |
| 47 if (index < 0 || szArray.size() < 2 || | 48 if (szArray.size() < 2 || index > szArray.size() - 2 || |
| 48 static_cast<size_t>(index) > szArray.size() - 2 || | |
| 49 szArray[index] > szArray[index + 1]) { | 49 szArray[index] > szArray[index + 1]) { |
| 50 return 0; | 50 return 0; |
| 51 } | 51 } |
| 52 return szArray[index + 1] - szArray[index]; | 52 return szArray[index + 1] - szArray[index]; |
| 53 } | 53 } |
| 54 | 54 |
| 55 bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { | 55 bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
| 56 if (!hStream || hStream->IsEOF()) | 56 if (!hStream || hStream->IsEOF()) |
| 57 return false; | 57 return false; |
| 58 | 58 |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 | 348 |
| 349 hStream->ByteAlign(); | 349 hStream->ByteAlign(); |
| 350 if (hStream->BitsRemaining() < dwSharedObjTotal) | 350 if (hStream->BitsRemaining() < dwSharedObjTotal) |
| 351 return false; | 351 return false; |
| 352 | 352 |
| 353 hStream->SkipBits(dwSharedObjTotal); | 353 hStream->SkipBits(dwSharedObjTotal); |
| 354 hStream->ByteAlign(); | 354 hStream->ByteAlign(); |
| 355 return true; | 355 return true; |
| 356 } | 356 } |
| 357 | 357 |
| 358 bool CPDF_HintTables::GetPagePos(int index, | 358 bool CPDF_HintTables::GetPagePos(uint32_t index, |
| 359 FX_FILESIZE* szPageStartPos, | 359 FX_FILESIZE* szPageStartPos, |
| 360 FX_FILESIZE* szPageLength, | 360 FX_FILESIZE* szPageLength, |
| 361 uint32_t* dwObjNum) { | 361 uint32_t* dwObjNum) { |
| 362 if (index < 0) | |
| 363 return false; | |
| 364 | |
| 365 *szPageStartPos = m_szPageOffsetArray[index]; | 362 *szPageStartPos = m_szPageOffsetArray[index]; |
| 366 *szPageLength = GetItemLength(index, m_szPageOffsetArray); | 363 *szPageLength = GetItemLength(index, m_szPageOffsetArray); |
| 367 | 364 |
| 368 int nFirstPageObjNum = GetFirstPageObjectNumber(); | 365 int nFirstPageObjNum = GetFirstPageObjectNumber(); |
| 369 if (nFirstPageObjNum < 0) | 366 if (nFirstPageObjNum < 0) |
| 370 return false; | 367 return false; |
| 371 | 368 |
| 372 int nFirstPageNum = GetFirstPageNumber(); | 369 int nFirstPageNum = GetFirstPageNumber(); |
| 373 if (nFirstPageNum < 0) | 370 if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum)) |
| 374 return false; | 371 return false; |
| 375 | 372 |
| 376 if (index == nFirstPageNum) { | 373 uint32_t dwFirstPageNum = static_cast<uint32_t>(nFirstPageNum); |
| 374 if (index == dwFirstPageNum) { |
| 377 *dwObjNum = nFirstPageObjNum; | 375 *dwObjNum = nFirstPageObjNum; |
| 378 return true; | 376 return true; |
| 379 } | 377 } |
| 380 | 378 |
| 381 // The object number of remaining pages starts from 1. | 379 // The object number of remaining pages starts from 1. |
| 382 *dwObjNum = 1; | 380 *dwObjNum = 1; |
| 383 for (int i = 0; i < index; ++i) { | 381 for (uint32_t i = 0; i < index; ++i) { |
| 384 if (i == nFirstPageNum) | 382 if (i == dwFirstPageNum) |
| 385 continue; | 383 continue; |
| 386 *dwObjNum += m_dwDeltaNObjsArray[i]; | 384 *dwObjNum += m_dwDeltaNObjsArray[i]; |
| 387 } | 385 } |
| 388 return true; | 386 return true; |
| 389 } | 387 } |
| 390 | 388 |
| 391 CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( | 389 CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( |
| 392 int index, | 390 uint32_t index, |
| 393 CPDF_DataAvail::DownloadHints* pHints) { | 391 CPDF_DataAvail::DownloadHints* pHints) { |
| 394 if (!pHints || index < 0) | 392 if (!pHints) |
| 395 return CPDF_DataAvail::DataError; | 393 return CPDF_DataAvail::DataError; |
| 396 | 394 |
| 397 if (index == GetFirstPageNumber()) | 395 int nFirstPageNum = GetFirstPageNumber(); |
| 396 if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum)) |
| 397 return CPDF_DataAvail::DataError; |
| 398 |
| 399 if (index == static_cast<uint32_t>(nFirstPageNum)) |
| 398 return CPDF_DataAvail::DataAvailable; | 400 return CPDF_DataAvail::DataAvailable; |
| 399 | 401 |
| 400 uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray); | 402 uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray); |
| 401 // If two pages have the same offset, it should be treated as an error. | 403 // If two pages have the same offset, it should be treated as an error. |
| 402 if (!dwLength) | 404 if (!dwLength) |
| 403 return CPDF_DataAvail::DataError; | 405 return CPDF_DataAvail::DataError; |
| 404 | 406 |
| 405 if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints)) | 407 if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints)) |
| 406 return CPDF_DataAvail::DataNotAvailable; | 408 return CPDF_DataAvail::DataNotAvailable; |
| 407 | 409 |
| 408 // Download data of shared objects in the page. | 410 // Download data of shared objects in the page. |
| 409 uint32_t offset = 0; | 411 uint32_t offset = 0; |
| 410 for (int i = 0; i < index; ++i) | 412 for (uint32_t i = 0; i < index; ++i) |
| 411 offset += m_dwNSharedObjsArray[i]; | 413 offset += m_dwNSharedObjsArray[i]; |
| 412 | 414 |
| 413 int nFirstPageObjNum = GetFirstPageObjectNumber(); | 415 int nFirstPageObjNum = GetFirstPageObjectNumber(); |
| 414 if (nFirstPageObjNum < 0) | 416 if (nFirstPageObjNum < 0) |
| 415 return CPDF_DataAvail::DataError; | 417 return CPDF_DataAvail::DataError; |
| 416 | 418 |
| 417 uint32_t dwIndex = 0; | 419 uint32_t dwIndex = 0; |
| 418 uint32_t dwObjNum = 0; | 420 uint32_t dwObjNum = 0; |
| 419 for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) { | 421 for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) { |
| 420 dwIndex = m_dwIdentifierArray[offset + j]; | 422 dwIndex = m_dwIdentifierArray[offset + j]; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 } | 508 } |
| 507 | 509 |
| 508 int CPDF_HintTables::ReadPrimaryHintStream(int index) const { | 510 int CPDF_HintTables::ReadPrimaryHintStream(int index) const { |
| 509 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); | 511 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); |
| 510 if (!pRange) | 512 if (!pRange) |
| 511 return -1; | 513 return -1; |
| 512 | 514 |
| 513 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index); | 515 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index); |
| 514 return pStreamLen ? pStreamLen->GetInteger() : -1; | 516 return pStreamLen ? pStreamLen->GetInteger() : -1; |
| 515 } | 517 } |
| OLD | NEW |