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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |