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

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

Issue 1524983002: Properly land "Fix hint table loading issues." (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: 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') | no next file » | 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,
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/include/fxcrt/fx_basic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698