Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp

Issue 1523523002: Fix hint table loading issues. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: im dumb Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/include/fxcrt/fx_basic.h ('k') | core/src/fpdfapi/fpdf_parser/parser_int.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 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 "parser_int.h" 7 #include "parser_int.h"
8 8
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
69 69
70 int32_t GetStreamNCount(CPDF_StreamAcc* pObjStream) { 70 int32_t GetStreamNCount(CPDF_StreamAcc* pObjStream) {
71 return pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); 71 return pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
72 } 72 }
73 73
74 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { 74 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) {
75 return pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); 75 return pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
76 } 76 }
77 77
78 bool CanReadFromBitStream(const CFX_BitStream* hStream,
jun_fang 2015/12/12 09:48:10 I don't think that we need to add an extra functio
79 const FX_SAFE_DWORD& num_bits) {
80 return (num_bits.IsValid() &&
81 hStream->BitsRemaining() >= num_bits.ValueOrDie());
82 }
83
78 } // namespace 84 } // namespace
79 85
80 // TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal. 86 // TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal.
81 // Come up or wait for something better. 87 // Come up or wait for something better.
82 using ScopedFileStream = 88 using ScopedFileStream =
83 nonstd::unique_ptr<IFX_FileStream, ReleaseDeleter<IFX_FileStream>>; 89 nonstd::unique_ptr<IFX_FileStream, ReleaseDeleter<IFX_FileStream>>;
84 90
85 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { 91 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) {
86 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); 92 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));
87 if (!pType) { 93 if (!pType) {
(...skipping 4549 matching lines...) Expand 10 before | Expand all | Expand 10 after
4637 m_szSharedObjOffsetArray.RemoveAll(); 4643 m_szSharedObjOffsetArray.RemoveAll();
4638 } 4644 }
4639 FX_DWORD CPDF_HintTables::GetItemLength(int index, 4645 FX_DWORD CPDF_HintTables::GetItemLength(int index,
4640 const CFX_FileSizeArray& szArray) { 4646 const CFX_FileSizeArray& szArray) {
4641 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 || 4647 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 ||
4642 szArray[index] > szArray[index + 1]) 4648 szArray[index] > szArray[index + 1])
4643 return 0; 4649 return 0;
4644 return szArray[index + 1] - szArray[index]; 4650 return szArray[index + 1] - szArray[index];
4645 } 4651 }
4646 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { 4652 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
4647 if (!hStream) 4653 if (!hStream || hStream->IsEOF())
4648 return FALSE; 4654 return FALSE;
4649 int nStreamOffset = ReadPrimaryHintStreamOffset(); 4655 int nStreamOffset = ReadPrimaryHintStreamOffset();
4650 int nStreamLen = ReadPrimaryHintStreamLength(); 4656 int nStreamLen = ReadPrimaryHintStreamLength();
4651 if (nStreamOffset < 0 || nStreamLen < 1) 4657 if (nStreamOffset < 0 || nStreamLen < 1)
4652 return FALSE; 4658 return FALSE;
4659
4660 const FX_DWORD kHeaderSize = 288;
4661 if (hStream->BitsRemaining() < kHeaderSize)
4662 return FALSE;
4653 // Item 1: The least number of objects in a page. 4663 // Item 1: The least number of objects in a page.
4654 FX_DWORD dwObjLeastNum = hStream->GetBits(32); 4664 FX_DWORD dwObjLeastNum = hStream->GetBits(32);
4655 // Item 2: The location of the first page's page object. 4665 // Item 2: The location of the first page's page object.
4656 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); 4666 FX_DWORD dwFirstObjLoc = hStream->GetBits(32);
4657 if (dwFirstObjLoc > nStreamOffset) { 4667 if (dwFirstObjLoc > nStreamOffset) {
4658 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); 4668 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen);
4659 safeLoc += dwFirstObjLoc; 4669 safeLoc += dwFirstObjLoc;
4660 if (!safeLoc.IsValid()) 4670 if (!safeLoc.IsValid())
4661 return FALSE; 4671 return FALSE;
4662 m_szFirstPageObjOffset = 4672 m_szFirstPageObjOffset =
(...skipping 22 matching lines...) Expand all
4685 // the fractional position for each shared object reference. For each 4695 // the fractional position for each shared object reference. For each
4686 // shared object referenced from a page, there is an indication of 4696 // shared object referenced from a page, there is an indication of
4687 // where in the page's content stream the object is first referenced. 4697 // where in the page's content stream the object is first referenced.
4688 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); 4698 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16);
4689 // Item 13: Skip Item 13 which has 16 bits. 4699 // Item 13: Skip Item 13 which has 16 bits.
4690 hStream->SkipBits(16); 4700 hStream->SkipBits(16);
4691 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); 4701 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N"));
4692 int nPages = pPageNum ? pPageNum->GetInteger() : 0; 4702 int nPages = pPageNum ? pPageNum->GetInteger() : 0;
4693 if (nPages < 1) 4703 if (nPages < 1)
4694 return FALSE; 4704 return FALSE;
4705
4706 FX_SAFE_DWORD required_bits = dwDeltaObjectsBits;
4707 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4708 if (!CanReadFromBitStream(hStream, required_bits))
jun_fang 2015/12/12 09:48:10 It means a failure if the return of CFX_BitStream:
Oliver Chang 2015/12/12 15:07:26 How do we distinguish between reading a value of 0
4709 return FALSE;
4695 for (int i = 0; i < nPages; ++i) { 4710 for (int i = 0; i < nPages; ++i) {
4696 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); 4711 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
4697 safeDeltaObj += dwObjLeastNum; 4712 safeDeltaObj += dwObjLeastNum;
4698 if (!safeDeltaObj.IsValid()) 4713 if (!safeDeltaObj.IsValid())
4699 return FALSE; 4714 return FALSE;
4700 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); 4715 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie());
4701 } 4716 }
4702 hStream->ByteAlign(); 4717 hStream->ByteAlign();
4718
4719 required_bits = dwDeltaPageLenBits;
4720 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4721 if (!CanReadFromBitStream(hStream, required_bits))
4722 return FALSE;
4703 CFX_DWordArray dwPageLenArray; 4723 CFX_DWordArray dwPageLenArray;
4704 for (int i = 0; i < nPages; ++i) { 4724 for (int i = 0; i < nPages; ++i) {
4705 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); 4725 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits);
4706 safePageLen += dwPageLeastLen; 4726 safePageLen += dwPageLeastLen;
4707 if (!safePageLen.IsValid()) 4727 if (!safePageLen.IsValid())
4708 return FALSE; 4728 return FALSE;
4709 dwPageLenArray.Add(safePageLen.ValueOrDie()); 4729 dwPageLenArray.Add(safePageLen.ValueOrDie());
4710 } 4730 }
4711 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); 4731 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E"));
4712 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; 4732 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1;
(...skipping 19 matching lines...) Expand all
4732 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + 4752 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] +
4733 dwPageLenArray[i - 1]); 4753 dwPageLenArray[i - 1]);
4734 } 4754 }
4735 } 4755 }
4736 } 4756 }
4737 if (nPages > 0) { 4757 if (nPages > 0) {
4738 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + 4758 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] +
4739 dwPageLenArray[nPages - 1]); 4759 dwPageLenArray[nPages - 1]);
4740 } 4760 }
4741 hStream->ByteAlign(); 4761 hStream->ByteAlign();
4762
4742 // number of shared objects 4763 // number of shared objects
4764 required_bits = dwSharedObjBits;
4765 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4766 if (!CanReadFromBitStream(hStream, required_bits))
4767 return FALSE;
4743 for (int i = 0; i < nPages; i++) { 4768 for (int i = 0; i < nPages; i++) {
4744 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); 4769 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits));
4745 } 4770 }
4746 hStream->ByteAlign(); 4771 hStream->ByteAlign();
4772
4747 // array of identifier, sizes = nshared_objects 4773 // array of identifier, sizes = nshared_objects
4748 for (int i = 0; i < nPages; i++) { 4774 for (int i = 0; i < nPages; i++) {
4775 required_bits = dwSharedIdBits;
4776 required_bits *= m_dwNSharedObjsArray[i];
4777 if (!CanReadFromBitStream(hStream, required_bits))
4778 return FALSE;
4749 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { 4779 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) {
4750 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); 4780 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits));
4751 } 4781 }
4752 } 4782 }
4753 hStream->ByteAlign(); 4783 hStream->ByteAlign();
4784
4754 for (int i = 0; i < nPages; i++) { 4785 for (int i = 0; i < nPages; i++) {
4755 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; 4786 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i];
4756 safeSize *= dwSharedNumeratorBits; 4787 safeSize *= dwSharedNumeratorBits;
4757 if (!safeSize.IsValid()) 4788 if (!CanReadFromBitStream(hStream, safeSize))
4758 return FALSE; 4789 return FALSE;
4759 hStream->SkipBits(safeSize.ValueOrDie()); 4790 hStream->SkipBits(safeSize.ValueOrDie());
4760 } 4791 }
4761 hStream->ByteAlign(); 4792 hStream->ByteAlign();
4793
4762 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); 4794 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages);
4763 safeTotalPageLen *= dwDeltaPageLenBits; 4795 safeTotalPageLen *= dwDeltaPageLenBits;
4764 if (!safeTotalPageLen.IsValid()) 4796 if (!CanReadFromBitStream(hStream, safeTotalPageLen))
4765 return FALSE; 4797 return FALSE;
4766 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); 4798 hStream->SkipBits(safeTotalPageLen.ValueOrDie());
jun_fang 2015/12/12 09:48:10 We should add a return value for SkipBits() like:
4767 hStream->ByteAlign(); 4799 hStream->ByteAlign();
4768 return TRUE; 4800 return TRUE;
4769 } 4801 }
4770 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { 4802 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
4771 if (!hStream) 4803 FX_DWORD offset) {
4804 if (!hStream || hStream->IsEOF())
4772 return FALSE; 4805 return FALSE;
4773 int nStreamOffset = ReadPrimaryHintStreamOffset(); 4806 int nStreamOffset = ReadPrimaryHintStreamOffset();
4774 int nStreamLen = ReadPrimaryHintStreamLength(); 4807 int nStreamLen = ReadPrimaryHintStreamLength();
4775 if (nStreamOffset < 0 || nStreamLen < 1) 4808 if (nStreamOffset < 0 || nStreamLen < 1)
4776 return FALSE; 4809 return FALSE;
4810
4811 FX_SAFE_DWORD bit_offset = offset;
4812 bit_offset *= 8;
4813 if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie())
4814 return FALSE;
4815 hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos());
4816
4817 const FX_DWORD kHeaderSize = 192;
4818 if (hStream->BitsRemaining() < kHeaderSize)
4819 return FALSE;
4777 // Item 1: The object number of the first object in the shared objects 4820 // Item 1: The object number of the first object in the shared objects
4778 // section. 4821 // section.
4779 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); 4822 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32);
4780 // Item 2: The location of the first object in the shared objects section. 4823 // Item 2: The location of the first object in the shared objects section.
4781 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); 4824 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32);
4782 if (dwFirstSharedObjLoc > nStreamOffset) 4825 if (dwFirstSharedObjLoc > nStreamOffset)
4783 dwFirstSharedObjLoc += nStreamLen; 4826 dwFirstSharedObjLoc += nStreamLen;
4784 // Item 3: The number of shared object entries for the first page. 4827 // Item 3: The number of shared object entries for the first page.
4785 m_nFirstPageSharedObjs = hStream->GetBits(32); 4828 m_nFirstPageSharedObjs = hStream->GetBits(32);
4786 // Item 4: The number of shared object entries for the shared objects 4829 // Item 4: The number of shared object entries for the shared objects
4787 // section, including the number of shared object entries for the first page. 4830 // section, including the number of shared object entries for the first page.
4788 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); 4831 FX_DWORD dwSharedObjTotal = hStream->GetBits(32);
4789 // Item 5: The number of bits needed to represent the greatest number of 4832 // Item 5: The number of bits needed to represent the greatest number of
4790 // objects in a shared object group. Skipped. 4833 // objects in a shared object group. Skipped.
4791 hStream->SkipBits(16); 4834 hStream->SkipBits(16);
4792 // Item 6: The least length of a shared object group in bytes. 4835 // Item 6: The least length of a shared object group in bytes.
4793 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); 4836 FX_DWORD dwGroupLeastLen = hStream->GetBits(32);
4794 // Item 7: The number of bits needed to represent the difference between the 4837 // Item 7: The number of bits needed to represent the difference between the
4795 // greatest and least length of a shared object group, in bytes. 4838 // greatest and least length of a shared object group, in bytes.
4796 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); 4839 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16);
4797 CPDF_Object* pFirstPageObj = 4840 CPDF_Object* pFirstPageObj =
4798 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); 4841 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4799 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; 4842 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
4800 if (nFirstPageObjNum < 0) 4843 if (nFirstPageObjNum < 0)
4801 return FALSE; 4844 return FALSE;
4802 FX_DWORD dwPrevObjLen = 0; 4845 FX_DWORD dwPrevObjLen = 0;
4803 FX_DWORD dwCurObjLen = 0; 4846 FX_DWORD dwCurObjLen = 0;
4847 FX_SAFE_DWORD required_bits = dwSharedObjTotal;
4848 required_bits *= dwDeltaGroupLen;
4849 if (!CanReadFromBitStream(hStream, required_bits))
jun_fang 2015/12/12 09:48:10 To check the return value of hStream->GetBits().
4850 return FALSE;
4851
4804 for (int i = 0; i < dwSharedObjTotal; ++i) { 4852 for (int i = 0; i < dwSharedObjTotal; ++i) {
4805 dwPrevObjLen = dwCurObjLen; 4853 dwPrevObjLen = dwCurObjLen;
4806 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); 4854 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen);
4807 safeObjLen += dwGroupLeastLen; 4855 safeObjLen += dwGroupLeastLen;
4808 if (!safeObjLen.IsValid()) 4856 if (!safeObjLen.IsValid())
4809 return FALSE; 4857 return FALSE;
4810 dwCurObjLen = safeObjLen.ValueOrDie(); 4858 dwCurObjLen = safeObjLen.ValueOrDie();
4811 if (i < m_nFirstPageSharedObjs) { 4859 if (i < m_nFirstPageSharedObjs) {
4812 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); 4860 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i);
4813 if (i == 0) 4861 if (i == 0)
(...skipping 17 matching lines...) Expand all
4831 } 4879 }
4832 } 4880 }
4833 if (dwSharedObjTotal > 0) { 4881 if (dwSharedObjTotal > 0) {
4834 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); 4882 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen);
4835 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; 4883 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
4836 if (!safeLoc.IsValid()) 4884 if (!safeLoc.IsValid())
4837 return FALSE; 4885 return FALSE;
4838 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); 4886 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie());
4839 } 4887 }
4840 hStream->ByteAlign(); 4888 hStream->ByteAlign();
4889 if (hStream->BitsRemaining() < dwSharedObjTotal)
4890 return FALSE;
4841 hStream->SkipBits(dwSharedObjTotal); 4891 hStream->SkipBits(dwSharedObjTotal);
jun_fang 2015/12/12 09:48:10 To check the return value of SkipBits() after we a
4842 hStream->ByteAlign(); 4892 hStream->ByteAlign();
4843 return TRUE; 4893 return TRUE;
4844 } 4894 }
4845 FX_BOOL CPDF_HintTables::GetPagePos(int index, 4895 FX_BOOL CPDF_HintTables::GetPagePos(int index,
4846 FX_FILESIZE& szPageStartPos, 4896 FX_FILESIZE& szPageStartPos,
4847 FX_FILESIZE& szPageLength, 4897 FX_FILESIZE& szPageLength,
4848 FX_DWORD& dwObjNum) { 4898 FX_DWORD& dwObjNum) {
4849 if (!m_pLinearizedDict) 4899 if (!m_pLinearizedDict)
4850 return FALSE; 4900 return FALSE;
4851 szPageStartPos = m_szPageOffsetArray[index]; 4901 szPageStartPos = m_szPageOffsetArray[index];
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4892 } 4942 }
4893 CPDF_Object* pFirstPageObj = 4943 CPDF_Object* pFirstPageObj =
4894 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); 4944 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4895 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; 4945 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
4896 if (nFirstPageObjNum < 0) 4946 if (nFirstPageObjNum < 0)
4897 return FALSE; // TODO(thestig): Fix this and the return type. 4947 return FALSE; // TODO(thestig): Fix this and the return type.
4898 FX_DWORD dwIndex = 0; 4948 FX_DWORD dwIndex = 0;
4899 FX_DWORD dwObjNum = 0; 4949 FX_DWORD dwObjNum = 0;
4900 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { 4950 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
4901 dwIndex = m_dwIdentifierArray[offset + j]; 4951 dwIndex = m_dwIdentifierArray[offset + j];
4952 if (dwIndex >= m_dwSharedObjNumArray.GetSize())
4953 return IPDF_DataAvail::DataNotAvailable;
4902 dwObjNum = m_dwSharedObjNumArray[dwIndex]; 4954 dwObjNum = m_dwSharedObjNumArray[dwIndex];
4903 if (dwObjNum >= nFirstPageObjNum && 4955 if (dwObjNum >= nFirstPageObjNum &&
4904 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { 4956 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) {
4905 continue; 4957 continue;
4906 } 4958 }
4907 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); 4959 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
4908 if (!dwLength || 4960 if (!dwLength ||
4909 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, 4961 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength,
4910 pHints)) { 4962 pHints)) {
4911 return IPDF_DataAvail::DataNotAvailable; 4963 return IPDF_DataAvail::DataNotAvailable;
4912 } 4964 }
4913 } 4965 }
4914 return IPDF_DataAvail::DataAvailable; 4966 return IPDF_DataAvail::DataAvailable;
4915 } 4967 }
4916 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { 4968 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
4917 if (!pHintStream || !m_pLinearizedDict) 4969 if (!pHintStream || !m_pLinearizedDict)
4918 return FALSE; 4970 return FALSE;
4919 CPDF_Dictionary* pDict = pHintStream->GetDict(); 4971 CPDF_Dictionary* pDict = pHintStream->GetDict();
4920 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; 4972 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr;
4921 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) 4973 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER)
4922 return FALSE; 4974 return FALSE;
4975 int shared_hint_table_offset = pOffset->GetInteger();
4923 CPDF_StreamAcc acc; 4976 CPDF_StreamAcc acc;
4924 acc.LoadAllData(pHintStream); 4977 acc.LoadAllData(pHintStream);
4925 FX_DWORD size = acc.GetSize(); 4978 FX_DWORD size = acc.GetSize();
4926 // The header section of page offset hint table is 36 bytes. 4979 // The header section of page offset hint table is 36 bytes.
4927 // The header section of shared object hint table is 24 bytes. 4980 // The header section of shared object hint table is 24 bytes.
4928 // Hint table has at least 60 bytes. 4981 // Hint table has at least 60 bytes.
4929 const FX_DWORD MIN_STREAM_LEN = 60; 4982 const FX_DWORD MIN_STREAM_LEN = 60;
4930 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() || 4983 if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 ||
4931 !pOffset->GetInteger()) { 4984 size < shared_hint_table_offset) {
4932 return FALSE; 4985 return FALSE;
4933 } 4986 }
4934 CFX_BitStream bs; 4987 CFX_BitStream bs;
4935 bs.Init(acc.GetData(), size); 4988 bs.Init(acc.GetData(), size);
4936 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs); 4989 return ReadPageHintTable(&bs) &&
4990 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>(
4991 shared_hint_table_offset));
4937 } 4992 }
4938 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { 4993 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
4939 if (!m_pLinearizedDict) 4994 if (!m_pLinearizedDict)
4940 return -1; 4995 return -1;
4941 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); 4996 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
4942 if (!pRange) 4997 if (!pRange)
4943 return -1; 4998 return -1;
4944 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); 4999 CPDF_Object* pStreamOffset = pRange->GetElementValue(0);
4945 if (!pStreamOffset) 5000 if (!pStreamOffset)
4946 return -1; 5001 return -1;
4947 return pStreamOffset->GetInteger(); 5002 return pStreamOffset->GetInteger();
4948 } 5003 }
4949 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { 5004 int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
4950 if (!m_pLinearizedDict) 5005 if (!m_pLinearizedDict)
4951 return -1; 5006 return -1;
4952 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); 5007 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
4953 if (!pRange) 5008 if (!pRange)
4954 return -1; 5009 return -1;
4955 CPDF_Object* pStreamLen = pRange->GetElementValue(1); 5010 CPDF_Object* pStreamLen = pRange->GetElementValue(1);
4956 if (!pStreamLen) 5011 if (!pStreamLen)
4957 return -1; 5012 return -1;
4958 return pStreamLen->GetInteger(); 5013 return pStreamLen->GetInteger();
4959 } 5014 }
OLDNEW
« no previous file with comments | « core/include/fxcrt/fx_basic.h ('k') | core/src/fpdfapi/fpdf_parser/parser_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698