| 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 |