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 |