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, |
| 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 4600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4688 // the fractional position for each shared object reference. For each | 4694 // the fractional position for each shared object reference. For each |
4689 // shared object referenced from a page, there is an indication of | 4695 // shared object referenced from a page, there is an indication of |
4690 // where in the page's content stream the object is first referenced. | 4696 // where in the page's content stream the object is first referenced. |
4691 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); | 4697 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); |
4692 // Item 13: Skip Item 13 which has 16 bits. | 4698 // Item 13: Skip Item 13 which has 16 bits. |
4693 hStream->SkipBits(16); | 4699 hStream->SkipBits(16); |
4694 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); | 4700 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); |
4695 int nPages = pPageNum ? pPageNum->GetInteger() : 0; | 4701 int nPages = pPageNum ? pPageNum->GetInteger() : 0; |
4696 if (nPages < 1) | 4702 if (nPages < 1) |
4697 return FALSE; | 4703 return FALSE; |
| 4704 |
4698 FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; | 4705 FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; |
4699 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | 4706 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
4700 if (!required_bits.IsValid() || | 4707 if (!CanReadFromBitStream(hStream, required_bits)) |
4701 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4702 return FALSE; | 4708 return FALSE; |
4703 for (int i = 0; i < nPages; ++i) { | 4709 for (int i = 0; i < nPages; ++i) { |
4704 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); | 4710 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); |
4705 safeDeltaObj += dwObjLeastNum; | 4711 safeDeltaObj += dwObjLeastNum; |
4706 if (!safeDeltaObj.IsValid()) | 4712 if (!safeDeltaObj.IsValid()) |
4707 return FALSE; | 4713 return FALSE; |
4708 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); | 4714 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); |
4709 } | 4715 } |
4710 hStream->ByteAlign(); | 4716 hStream->ByteAlign(); |
| 4717 |
4711 required_bits = dwDeltaPageLenBits; | 4718 required_bits = dwDeltaPageLenBits; |
4712 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | 4719 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
4713 if (!required_bits.IsValid() || | 4720 if (!CanReadFromBitStream(hStream, required_bits)) |
4714 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4715 return FALSE; | 4721 return FALSE; |
4716 CFX_DWordArray dwPageLenArray; | 4722 CFX_DWordArray dwPageLenArray; |
4717 for (int i = 0; i < nPages; ++i) { | 4723 for (int i = 0; i < nPages; ++i) { |
4718 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); | 4724 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); |
4719 safePageLen += dwPageLeastLen; | 4725 safePageLen += dwPageLeastLen; |
4720 if (!safePageLen.IsValid()) | 4726 if (!safePageLen.IsValid()) |
4721 return FALSE; | 4727 return FALSE; |
4722 dwPageLenArray.Add(safePageLen.ValueOrDie()); | 4728 dwPageLenArray.Add(safePageLen.ValueOrDie()); |
4723 } | 4729 } |
4724 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); | 4730 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); |
(...skipping 20 matching lines...) Expand all Loading... |
4745 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + | 4751 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + |
4746 dwPageLenArray[i - 1]); | 4752 dwPageLenArray[i - 1]); |
4747 } | 4753 } |
4748 } | 4754 } |
4749 } | 4755 } |
4750 if (nPages > 0) { | 4756 if (nPages > 0) { |
4751 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + | 4757 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + |
4752 dwPageLenArray[nPages - 1]); | 4758 dwPageLenArray[nPages - 1]); |
4753 } | 4759 } |
4754 hStream->ByteAlign(); | 4760 hStream->ByteAlign(); |
| 4761 |
4755 // number of shared objects | 4762 // number of shared objects |
4756 required_bits = dwSharedObjBits; | 4763 required_bits = dwSharedObjBits; |
4757 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); | 4764 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
4758 if (!required_bits.IsValid() || | 4765 if (!CanReadFromBitStream(hStream, required_bits)) |
4759 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4760 return FALSE; | 4766 return FALSE; |
4761 for (int i = 0; i < nPages; i++) { | 4767 for (int i = 0; i < nPages; i++) { |
4762 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); | 4768 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); |
4763 } | 4769 } |
4764 hStream->ByteAlign(); | 4770 hStream->ByteAlign(); |
| 4771 |
4765 // array of identifier, sizes = nshared_objects | 4772 // array of identifier, sizes = nshared_objects |
4766 for (int i = 0; i < nPages; i++) { | 4773 for (int i = 0; i < nPages; i++) { |
4767 required_bits = dwSharedIdBits; | 4774 required_bits = dwSharedIdBits; |
4768 required_bits *= m_dwNSharedObjsArray[i]; | 4775 required_bits *= m_dwNSharedObjsArray[i]; |
4769 if (!required_bits.IsValid() || | 4776 if (!CanReadFromBitStream(hStream, required_bits)) |
4770 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4771 return FALSE; | 4777 return FALSE; |
4772 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { | 4778 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { |
4773 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); | 4779 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); |
4774 } | 4780 } |
4775 } | 4781 } |
4776 hStream->ByteAlign(); | 4782 hStream->ByteAlign(); |
| 4783 |
4777 for (int i = 0; i < nPages; i++) { | 4784 for (int i = 0; i < nPages; i++) { |
4778 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; | 4785 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; |
4779 safeSize *= dwSharedNumeratorBits; | 4786 safeSize *= dwSharedNumeratorBits; |
4780 if (!safeSize.IsValid() || hStream->BitsRemaining() < safeSize.ValueOrDie()) | 4787 if (!CanReadFromBitStream(hStream, safeSize)) |
4781 return FALSE; | 4788 return FALSE; |
4782 hStream->SkipBits(safeSize.ValueOrDie()); | 4789 hStream->SkipBits(safeSize.ValueOrDie()); |
4783 } | 4790 } |
4784 hStream->ByteAlign(); | 4791 hStream->ByteAlign(); |
| 4792 |
4785 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); | 4793 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); |
4786 safeTotalPageLen *= dwDeltaPageLenBits; | 4794 safeTotalPageLen *= dwDeltaPageLenBits; |
4787 if (!safeTotalPageLen.IsValid() || | 4795 if (!CanReadFromBitStream(hStream, safeTotalPageLen)) |
4788 hStream->BitsRemaining() < safeTotalPageLen.ValueOrDie()) | |
4789 return FALSE; | 4796 return FALSE; |
4790 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); | 4797 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); |
4791 hStream->ByteAlign(); | 4798 hStream->ByteAlign(); |
4792 return TRUE; | 4799 return TRUE; |
4793 } | 4800 } |
4794 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, | 4801 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
4795 FX_DWORD offset) { | 4802 FX_DWORD offset) { |
4796 if (!hStream || hStream->IsEOF()) | 4803 if (!hStream || hStream->IsEOF()) |
4797 return FALSE; | 4804 return FALSE; |
4798 int nStreamOffset = ReadPrimaryHintStreamOffset(); | 4805 int nStreamOffset = ReadPrimaryHintStreamOffset(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4831 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); | 4838 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); |
4832 CPDF_Object* pFirstPageObj = | 4839 CPDF_Object* pFirstPageObj = |
4833 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | 4840 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
4834 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | 4841 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
4835 if (nFirstPageObjNum < 0) | 4842 if (nFirstPageObjNum < 0) |
4836 return FALSE; | 4843 return FALSE; |
4837 FX_DWORD dwPrevObjLen = 0; | 4844 FX_DWORD dwPrevObjLen = 0; |
4838 FX_DWORD dwCurObjLen = 0; | 4845 FX_DWORD dwCurObjLen = 0; |
4839 FX_SAFE_DWORD required_bits = dwSharedObjTotal; | 4846 FX_SAFE_DWORD required_bits = dwSharedObjTotal; |
4840 required_bits *= dwDeltaGroupLen; | 4847 required_bits *= dwDeltaGroupLen; |
4841 if (!required_bits.IsValid() || | 4848 if (!CanReadFromBitStream(hStream, required_bits)) |
4842 hStream->BitsRemaining() < required_bits.ValueOrDie()) | |
4843 return FALSE; | 4849 return FALSE; |
4844 | 4850 |
4845 for (int i = 0; i < dwSharedObjTotal; ++i) { | 4851 for (int i = 0; i < dwSharedObjTotal; ++i) { |
4846 dwPrevObjLen = dwCurObjLen; | 4852 dwPrevObjLen = dwCurObjLen; |
4847 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); | 4853 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); |
4848 safeObjLen += dwGroupLeastLen; | 4854 safeObjLen += dwGroupLeastLen; |
4849 if (!safeObjLen.IsValid()) | 4855 if (!safeObjLen.IsValid()) |
4850 return FALSE; | 4856 return FALSE; |
4851 dwCurObjLen = safeObjLen.ValueOrDie(); | 4857 dwCurObjLen = safeObjLen.ValueOrDie(); |
4852 if (i < m_nFirstPageSharedObjs) { | 4858 if (i < m_nFirstPageSharedObjs) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4966 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) | 4972 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) |
4967 return FALSE; | 4973 return FALSE; |
4968 int shared_hint_table_offset = pOffset->GetInteger(); | 4974 int shared_hint_table_offset = pOffset->GetInteger(); |
4969 CPDF_StreamAcc acc; | 4975 CPDF_StreamAcc acc; |
4970 acc.LoadAllData(pHintStream); | 4976 acc.LoadAllData(pHintStream); |
4971 FX_DWORD size = acc.GetSize(); | 4977 FX_DWORD size = acc.GetSize(); |
4972 // The header section of page offset hint table is 36 bytes. | 4978 // The header section of page offset hint table is 36 bytes. |
4973 // The header section of shared object hint table is 24 bytes. | 4979 // The header section of shared object hint table is 24 bytes. |
4974 // Hint table has at least 60 bytes. | 4980 // Hint table has at least 60 bytes. |
4975 const FX_DWORD MIN_STREAM_LEN = 60; | 4981 const FX_DWORD MIN_STREAM_LEN = 60; |
4976 if (size < MIN_STREAM_LEN || shared_hint_table_offset < 0 || | 4982 if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || |
4977 size < shared_hint_table_offset || !shared_hint_table_offset) { | 4983 size < shared_hint_table_offset) { |
4978 return FALSE; | 4984 return FALSE; |
4979 } | 4985 } |
4980 CFX_BitStream bs; | 4986 CFX_BitStream bs; |
4981 bs.Init(acc.GetData(), size); | 4987 bs.Init(acc.GetData(), size); |
4982 return ReadPageHintTable(&bs) && | 4988 return ReadPageHintTable(&bs) && |
4983 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( | 4989 ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( |
4984 shared_hint_table_offset)); | 4990 shared_hint_table_offset)); |
4985 } | 4991 } |
4986 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { | 4992 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
4987 if (!m_pLinearizedDict) | 4993 if (!m_pLinearizedDict) |
(...skipping 10 matching lines...) Expand all Loading... |
4998 if (!m_pLinearizedDict) | 5004 if (!m_pLinearizedDict) |
4999 return -1; | 5005 return -1; |
5000 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | 5006 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
5001 if (!pRange) | 5007 if (!pRange) |
5002 return -1; | 5008 return -1; |
5003 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 5009 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
5004 if (!pStreamLen) | 5010 if (!pStreamLen) |
5005 return -1; | 5011 return -1; |
5006 return pStreamLen->GetInteger(); | 5012 return pStreamLen->GetInteger(); |
5007 } | 5013 } |
OLD | NEW |