OLD | NEW |
---|---|
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 4626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4637 m_szSharedObjOffsetArray.RemoveAll(); | 4637 m_szSharedObjOffsetArray.RemoveAll(); |
4638 } | 4638 } |
4639 FX_DWORD CPDF_HintTables::GetItemLength(int index, | 4639 FX_DWORD CPDF_HintTables::GetItemLength(int index, |
4640 const CFX_FileSizeArray& szArray) { | 4640 const CFX_FileSizeArray& szArray) { |
4641 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 || | 4641 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 || |
4642 szArray[index] > szArray[index + 1]) | 4642 szArray[index] > szArray[index + 1]) |
4643 return 0; | 4643 return 0; |
4644 return szArray[index + 1] - szArray[index]; | 4644 return szArray[index + 1] - szArray[index]; |
4645 } | 4645 } |
4646 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { | 4646 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
4647 if (!hStream) | 4647 if (!hStream || hStream->IsEOF()) |
4648 return FALSE; | 4648 return FALSE; |
4649 int nStreamOffset = ReadPrimaryHintStreamOffset(); | 4649 int nStreamOffset = ReadPrimaryHintStreamOffset(); |
4650 int nStreamLen = ReadPrimaryHintStreamLength(); | 4650 int nStreamLen = ReadPrimaryHintStreamLength(); |
4651 if (nStreamOffset < 0 || nStreamLen < 1) | 4651 if (nStreamOffset < 0 || nStreamLen < 1) |
4652 return FALSE; | 4652 return FALSE; |
4653 | |
4654 const FX_DWORD kHeaderSize = 288; | |
4655 if (hStream->BitsRemaining() < kHeaderSize) | |
4656 return FALSE; | |
4653 // Item 1: The least number of objects in a page. | 4657 // Item 1: The least number of objects in a page. |
4654 FX_DWORD dwObjLeastNum = hStream->GetBits(32); | 4658 FX_DWORD dwObjLeastNum = hStream->GetBits(32); |
4655 // Item 2: The location of the first page's page object. | 4659 // Item 2: The location of the first page's page object. |
4656 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); | 4660 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); |
4657 if (dwFirstObjLoc > nStreamOffset) { | 4661 if (dwFirstObjLoc > nStreamOffset) { |
4658 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); | 4662 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); |
4659 safeLoc += dwFirstObjLoc; | 4663 safeLoc += dwFirstObjLoc; |
4660 if (!safeLoc.IsValid()) | 4664 if (!safeLoc.IsValid()) |
4661 return FALSE; | 4665 return FALSE; |
4662 m_szFirstPageObjOffset = | 4666 m_szFirstPageObjOffset = |
(...skipping 22 matching lines...) Expand all Loading... | |
4685 // the fractional position for each shared object reference. For each | 4689 // the fractional position for each shared object reference. For each |
4686 // shared object referenced from a page, there is an indication of | 4690 // shared object referenced from a page, there is an indication of |
4687 // where in the page's content stream the object is first referenced. | 4691 // where in the page's content stream the object is first referenced. |
4688 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); | 4692 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); |
4689 // Item 13: Skip Item 13 which has 16 bits. | 4693 // Item 13: Skip Item 13 which has 16 bits. |
4690 hStream->SkipBits(16); | 4694 hStream->SkipBits(16); |
4691 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); | 4695 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); |
4692 int nPages = pPageNum ? pPageNum->GetInteger() : 0; | 4696 int nPages = pPageNum ? pPageNum->GetInteger() : 0; |
4693 if (nPages < 1) | 4697 if (nPages < 1) |
4694 return FALSE; | 4698 return FALSE; |
4699 FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; | |
4700 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | |
4701 if (!required_bits.IsValid() || | |
4702 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
Lei Zhang
2015/12/12 01:38:12
braces, ditto below. Maybe make a helper function?
Oliver Chang
2015/12/12 02:37:14
Made a helper. A lot cleaner now.
| |
4703 return FALSE; | |
4695 for (int i = 0; i < nPages; ++i) { | 4704 for (int i = 0; i < nPages; ++i) { |
4696 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); | 4705 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); |
4697 safeDeltaObj += dwObjLeastNum; | 4706 safeDeltaObj += dwObjLeastNum; |
4698 if (!safeDeltaObj.IsValid()) | 4707 if (!safeDeltaObj.IsValid()) |
4699 return FALSE; | 4708 return FALSE; |
4700 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); | 4709 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); |
4701 } | 4710 } |
4702 hStream->ByteAlign(); | 4711 hStream->ByteAlign(); |
4712 required_bits = dwDeltaPageLenBits; | |
4713 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | |
4714 if (!required_bits.IsValid() || | |
4715 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4716 return FALSE; | |
4703 CFX_DWordArray dwPageLenArray; | 4717 CFX_DWordArray dwPageLenArray; |
4704 for (int i = 0; i < nPages; ++i) { | 4718 for (int i = 0; i < nPages; ++i) { |
4705 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); | 4719 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); |
4706 safePageLen += dwPageLeastLen; | 4720 safePageLen += dwPageLeastLen; |
4707 if (!safePageLen.IsValid()) | 4721 if (!safePageLen.IsValid()) |
4708 return FALSE; | 4722 return FALSE; |
4709 dwPageLenArray.Add(safePageLen.ValueOrDie()); | 4723 dwPageLenArray.Add(safePageLen.ValueOrDie()); |
4710 } | 4724 } |
4711 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); | 4725 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); |
4712 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; | 4726 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; |
(...skipping 20 matching lines...) Expand all Loading... | |
4733 dwPageLenArray[i - 1]); | 4747 dwPageLenArray[i - 1]); |
4734 } | 4748 } |
4735 } | 4749 } |
4736 } | 4750 } |
4737 if (nPages > 0) { | 4751 if (nPages > 0) { |
4738 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + | 4752 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + |
4739 dwPageLenArray[nPages - 1]); | 4753 dwPageLenArray[nPages - 1]); |
4740 } | 4754 } |
4741 hStream->ByteAlign(); | 4755 hStream->ByteAlign(); |
4742 // number of shared objects | 4756 // number of shared objects |
4757 required_bits = dwSharedObjBits; | |
4758 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | |
4759 if (!required_bits.IsValid() || | |
4760 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4761 return FALSE; | |
4743 for (int i = 0; i < nPages; i++) { | 4762 for (int i = 0; i < nPages; i++) { |
4744 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); | 4763 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); |
4745 } | 4764 } |
4746 hStream->ByteAlign(); | 4765 hStream->ByteAlign(); |
4747 // array of identifier, sizes = nshared_objects | 4766 // array of identifier, sizes = nshared_objects |
4748 for (int i = 0; i < nPages; i++) { | 4767 for (int i = 0; i < nPages; i++) { |
4768 required_bits = dwSharedIdBits; | |
4769 required_bits *= m_dwNSharedObjsArray[i]; | |
4770 if (!required_bits.IsValid() || | |
4771 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4772 return FALSE; | |
4749 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { | 4773 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { |
4750 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); | 4774 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); |
4751 } | 4775 } |
4752 } | 4776 } |
4753 hStream->ByteAlign(); | 4777 hStream->ByteAlign(); |
4754 for (int i = 0; i < nPages; i++) { | 4778 for (int i = 0; i < nPages; i++) { |
4755 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; | 4779 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; |
4756 safeSize *= dwSharedNumeratorBits; | 4780 safeSize *= dwSharedNumeratorBits; |
4757 if (!safeSize.IsValid()) | 4781 if (!safeSize.IsValid() || hStream->BitsRemaining() < safeSize.ValueOrDie()) |
4758 return FALSE; | 4782 return FALSE; |
4759 hStream->SkipBits(safeSize.ValueOrDie()); | 4783 hStream->SkipBits(safeSize.ValueOrDie()); |
4760 } | 4784 } |
4761 hStream->ByteAlign(); | 4785 hStream->ByteAlign(); |
4762 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); | 4786 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); |
4763 safeTotalPageLen *= dwDeltaPageLenBits; | 4787 safeTotalPageLen *= dwDeltaPageLenBits; |
4764 if (!safeTotalPageLen.IsValid()) | 4788 if (!safeTotalPageLen.IsValid() || |
4789 hStream->BitsRemaining() < safeTotalPageLen.ValueOrDie()) | |
4765 return FALSE; | 4790 return FALSE; |
4766 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); | 4791 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); |
4767 hStream->ByteAlign(); | 4792 hStream->ByteAlign(); |
4768 return TRUE; | 4793 return TRUE; |
4769 } | 4794 } |
4770 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { | 4795 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
4771 if (!hStream) | 4796 FX_DWORD offset) { |
4797 if (!hStream || hStream->IsEOF()) | |
4772 return FALSE; | 4798 return FALSE; |
4773 int nStreamOffset = ReadPrimaryHintStreamOffset(); | 4799 int nStreamOffset = ReadPrimaryHintStreamOffset(); |
4774 int nStreamLen = ReadPrimaryHintStreamLength(); | 4800 int nStreamLen = ReadPrimaryHintStreamLength(); |
4775 if (nStreamOffset < 0 || nStreamLen < 1) | 4801 if (nStreamOffset < 0 || nStreamLen < 1) |
4776 return FALSE; | 4802 return FALSE; |
4803 | |
4804 FX_SAFE_DWORD bit_offset = offset; | |
4805 bit_offset *= 8; | |
4806 if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) | |
4807 return FALSE; | |
4808 hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); | |
4809 | |
4810 const FX_DWORD kHeaderSize = 192; | |
4811 if (hStream->BitsRemaining() < kHeaderSize) | |
4812 return FALSE; | |
4777 // Item 1: The object number of the first object in the shared objects | 4813 // Item 1: The object number of the first object in the shared objects |
4778 // section. | 4814 // section. |
4779 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); | 4815 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); |
4780 // Item 2: The location of the first object in the shared objects section. | 4816 // Item 2: The location of the first object in the shared objects section. |
4781 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); | 4817 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); |
4782 if (dwFirstSharedObjLoc > nStreamOffset) | 4818 if (dwFirstSharedObjLoc > nStreamOffset) |
4783 dwFirstSharedObjLoc += nStreamLen; | 4819 dwFirstSharedObjLoc += nStreamLen; |
4784 // Item 3: The number of shared object entries for the first page. | 4820 // Item 3: The number of shared object entries for the first page. |
4785 m_nFirstPageSharedObjs = hStream->GetBits(32); | 4821 m_nFirstPageSharedObjs = hStream->GetBits(32); |
4786 // Item 4: The number of shared object entries for the shared objects | 4822 // 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. | 4823 // section, including the number of shared object entries for the first page. |
4788 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); | 4824 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); |
4789 // Item 5: The number of bits needed to represent the greatest number of | 4825 // Item 5: The number of bits needed to represent the greatest number of |
4790 // objects in a shared object group. Skipped. | 4826 // objects in a shared object group. Skipped. |
4791 hStream->SkipBits(16); | 4827 hStream->SkipBits(16); |
4792 // Item 6: The least length of a shared object group in bytes. | 4828 // Item 6: The least length of a shared object group in bytes. |
4793 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); | 4829 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); |
4794 // Item 7: The number of bits needed to represent the difference between the | 4830 // 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. | 4831 // greatest and least length of a shared object group, in bytes. |
4796 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); | 4832 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); |
4797 CPDF_Object* pFirstPageObj = | 4833 CPDF_Object* pFirstPageObj = |
4798 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | 4834 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
4799 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | 4835 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
4800 if (nFirstPageObjNum < 0) | 4836 if (nFirstPageObjNum < 0) |
4801 return FALSE; | 4837 return FALSE; |
4802 FX_DWORD dwPrevObjLen = 0; | 4838 FX_DWORD dwPrevObjLen = 0; |
4803 FX_DWORD dwCurObjLen = 0; | 4839 FX_DWORD dwCurObjLen = 0; |
4840 FX_SAFE_DWORD required_bits = dwSharedObjTotal; | |
4841 required_bits *= dwDeltaGroupLen; | |
4842 if (!required_bits.IsValid() || | |
4843 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4844 return FALSE; | |
4845 | |
4804 for (int i = 0; i < dwSharedObjTotal; ++i) { | 4846 for (int i = 0; i < dwSharedObjTotal; ++i) { |
4805 dwPrevObjLen = dwCurObjLen; | 4847 dwPrevObjLen = dwCurObjLen; |
4806 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); | 4848 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); |
4807 safeObjLen += dwGroupLeastLen; | 4849 safeObjLen += dwGroupLeastLen; |
4808 if (!safeObjLen.IsValid()) | 4850 if (!safeObjLen.IsValid()) |
4809 return FALSE; | 4851 return FALSE; |
4810 dwCurObjLen = safeObjLen.ValueOrDie(); | 4852 dwCurObjLen = safeObjLen.ValueOrDie(); |
4811 if (i < m_nFirstPageSharedObjs) { | 4853 if (i < m_nFirstPageSharedObjs) { |
4812 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); | 4854 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); |
4813 if (i == 0) | 4855 if (i == 0) |
(...skipping 17 matching lines...) Expand all Loading... | |
4831 } | 4873 } |
4832 } | 4874 } |
4833 if (dwSharedObjTotal > 0) { | 4875 if (dwSharedObjTotal > 0) { |
4834 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); | 4876 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); |
4835 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; | 4877 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; |
4836 if (!safeLoc.IsValid()) | 4878 if (!safeLoc.IsValid()) |
4837 return FALSE; | 4879 return FALSE; |
4838 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); | 4880 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); |
4839 } | 4881 } |
4840 hStream->ByteAlign(); | 4882 hStream->ByteAlign(); |
4883 if (hStream->BitsRemaining() < dwSharedObjTotal) | |
4884 return FALSE; | |
4841 hStream->SkipBits(dwSharedObjTotal); | 4885 hStream->SkipBits(dwSharedObjTotal); |
4842 hStream->ByteAlign(); | 4886 hStream->ByteAlign(); |
4843 return TRUE; | 4887 return TRUE; |
4844 } | 4888 } |
4845 FX_BOOL CPDF_HintTables::GetPagePos(int index, | 4889 FX_BOOL CPDF_HintTables::GetPagePos(int index, |
4846 FX_FILESIZE& szPageStartPos, | 4890 FX_FILESIZE& szPageStartPos, |
4847 FX_FILESIZE& szPageLength, | 4891 FX_FILESIZE& szPageLength, |
4848 FX_DWORD& dwObjNum) { | 4892 FX_DWORD& dwObjNum) { |
4849 if (!m_pLinearizedDict) | 4893 if (!m_pLinearizedDict) |
4850 return FALSE; | 4894 return FALSE; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4892 } | 4936 } |
4893 CPDF_Object* pFirstPageObj = | 4937 CPDF_Object* pFirstPageObj = |
4894 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | 4938 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
4895 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | 4939 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
4896 if (nFirstPageObjNum < 0) | 4940 if (nFirstPageObjNum < 0) |
4897 return FALSE; // TODO(thestig): Fix this and the return type. | 4941 return FALSE; // TODO(thestig): Fix this and the return type. |
4898 FX_DWORD dwIndex = 0; | 4942 FX_DWORD dwIndex = 0; |
4899 FX_DWORD dwObjNum = 0; | 4943 FX_DWORD dwObjNum = 0; |
4900 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { | 4944 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { |
4901 dwIndex = m_dwIdentifierArray[offset + j]; | 4945 dwIndex = m_dwIdentifierArray[offset + j]; |
4946 if (dwIndex >= m_dwSharedObjNumArray.GetSize()) | |
4947 return IPDF_DataAvail::DataNotAvailable; | |
4902 dwObjNum = m_dwSharedObjNumArray[dwIndex]; | 4948 dwObjNum = m_dwSharedObjNumArray[dwIndex]; |
4903 if (dwObjNum >= nFirstPageObjNum && | 4949 if (dwObjNum >= nFirstPageObjNum && |
4904 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { | 4950 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { |
4905 continue; | 4951 continue; |
4906 } | 4952 } |
4907 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); | 4953 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); |
4908 if (!dwLength || | 4954 if (!dwLength || |
4909 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, | 4955 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, |
4910 pHints)) { | 4956 pHints)) { |
4911 return IPDF_DataAvail::DataNotAvailable; | 4957 return IPDF_DataAvail::DataNotAvailable; |
4912 } | 4958 } |
4913 } | 4959 } |
4914 return IPDF_DataAvail::DataAvailable; | 4960 return IPDF_DataAvail::DataAvailable; |
4915 } | 4961 } |
4916 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { | 4962 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
4917 if (!pHintStream || !m_pLinearizedDict) | 4963 if (!pHintStream || !m_pLinearizedDict) |
4918 return FALSE; | 4964 return FALSE; |
4919 CPDF_Dictionary* pDict = pHintStream->GetDict(); | 4965 CPDF_Dictionary* pDict = pHintStream->GetDict(); |
4920 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; | 4966 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; |
4921 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) | 4967 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) |
4922 return FALSE; | 4968 return FALSE; |
4969 int shared_hint_table_offset = pOffset->GetInteger(); | |
4923 CPDF_StreamAcc acc; | 4970 CPDF_StreamAcc acc; |
4924 acc.LoadAllData(pHintStream); | 4971 acc.LoadAllData(pHintStream); |
4925 FX_DWORD size = acc.GetSize(); | 4972 FX_DWORD size = acc.GetSize(); |
4926 // The header section of page offset hint table is 36 bytes. | 4973 // The header section of page offset hint table is 36 bytes. |
4927 // The header section of shared object hint table is 24 bytes. | 4974 // The header section of shared object hint table is 24 bytes. |
4928 // Hint table has at least 60 bytes. | 4975 // Hint table has at least 60 bytes. |
4929 const FX_DWORD MIN_STREAM_LEN = 60; | 4976 const FX_DWORD MIN_STREAM_LEN = 60; |
4930 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() || | 4977 if (size < MIN_STREAM_LEN || shared_hint_table_offset < 0 || |
4931 !pOffset->GetInteger()) { | 4978 size < shared_hint_table_offset || !shared_hint_table_offset) { |
4932 return FALSE; | 4979 return FALSE; |
4933 } | 4980 } |
4934 CFX_BitStream bs; | 4981 CFX_BitStream bs; |
4935 bs.Init(acc.GetData(), size); | 4982 bs.Init(acc.GetData(), size); |
4936 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs); | 4983 return ReadPageHintTable(&bs) && |
4984 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( | |
4985 shared_hint_table_offset)); | |
4937 } | 4986 } |
4938 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { | 4987 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
4939 if (!m_pLinearizedDict) | 4988 if (!m_pLinearizedDict) |
4940 return -1; | 4989 return -1; |
4941 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | 4990 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
4942 if (!pRange) | 4991 if (!pRange) |
4943 return -1; | 4992 return -1; |
4944 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); | 4993 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); |
4945 if (!pStreamOffset) | 4994 if (!pStreamOffset) |
4946 return -1; | 4995 return -1; |
4947 return pStreamOffset->GetInteger(); | 4996 return pStreamOffset->GetInteger(); |
4948 } | 4997 } |
4949 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { | 4998 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { |
4950 if (!m_pLinearizedDict) | 4999 if (!m_pLinearizedDict) |
4951 return -1; | 5000 return -1; |
4952 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | 5001 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
4953 if (!pRange) | 5002 if (!pRange) |
4954 return -1; | 5003 return -1; |
4955 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 5004 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
4956 if (!pStreamLen) | 5005 if (!pStreamLen) |
4957 return -1; | 5006 return -1; |
4958 return pStreamLen->GetInteger(); | 5007 return pStreamLen->GetInteger(); |
4959 } | 5008 } |
OLD | NEW |