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

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

Issue 1523523002: Fix hint table loading issues. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: address comments 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') | core/src/fpdfapi/fpdf_parser/parser_int.h » ('j') | 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(CFX_BitStream* hStream,
Lei Zhang 2015/12/12 02:51:18 |hStream| can now be a const ptr.
Oliver Chang 2015/12/12 03:02:07 Done.
Lei Zhang 2015/12/12 03:11:59 Sorry, I meant 'const CFX_BitStream*'
Oliver Chang 2015/12/12 03:16:43 Oops, mixed up my understanding of const * vs * co
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
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
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 FX_SAFE_DWORD required_bits = dwDeltaObjectsBits;
Lei Zhang 2015/12/12 02:51:18 Can you add a line break above, so it's clear the
Oliver Chang 2015/12/12 03:02:07 Done.
4706 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4707 if (!CanReadFromBitStream(hStream, required_bits))
4708 return FALSE;
4695 for (int i = 0; i < nPages; ++i) { 4709 for (int i = 0; i < nPages; ++i) {
4696 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); 4710 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
4697 safeDeltaObj += dwObjLeastNum; 4711 safeDeltaObj += dwObjLeastNum;
4698 if (!safeDeltaObj.IsValid()) 4712 if (!safeDeltaObj.IsValid())
4699 return FALSE; 4713 return FALSE;
4700 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); 4714 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie());
4701 } 4715 }
4702 hStream->ByteAlign(); 4716 hStream->ByteAlign();
4717 required_bits = dwDeltaPageLenBits;
4718 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4719 if (!CanReadFromBitStream(hStream, required_bits))
4720 return FALSE;
4703 CFX_DWordArray dwPageLenArray; 4721 CFX_DWordArray dwPageLenArray;
4704 for (int i = 0; i < nPages; ++i) { 4722 for (int i = 0; i < nPages; ++i) {
4705 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); 4723 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits);
4706 safePageLen += dwPageLeastLen; 4724 safePageLen += dwPageLeastLen;
4707 if (!safePageLen.IsValid()) 4725 if (!safePageLen.IsValid())
4708 return FALSE; 4726 return FALSE;
4709 dwPageLenArray.Add(safePageLen.ValueOrDie()); 4727 dwPageLenArray.Add(safePageLen.ValueOrDie());
4710 } 4728 }
4711 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); 4729 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E"));
4712 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; 4730 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1;
(...skipping 20 matching lines...) Expand all
4733 dwPageLenArray[i - 1]); 4751 dwPageLenArray[i - 1]);
4734 } 4752 }
4735 } 4753 }
4736 } 4754 }
4737 if (nPages > 0) { 4755 if (nPages > 0) {
4738 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + 4756 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] +
4739 dwPageLenArray[nPages - 1]); 4757 dwPageLenArray[nPages - 1]);
4740 } 4758 }
4741 hStream->ByteAlign(); 4759 hStream->ByteAlign();
4742 // number of shared objects 4760 // number of shared objects
4761 required_bits = dwSharedObjBits;
4762 required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages);
4763 if (!CanReadFromBitStream(hStream, required_bits))
4764 return FALSE;
4743 for (int i = 0; i < nPages; i++) { 4765 for (int i = 0; i < nPages; i++) {
4744 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); 4766 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits));
4745 } 4767 }
4746 hStream->ByteAlign(); 4768 hStream->ByteAlign();
4747 // array of identifier, sizes = nshared_objects 4769 // array of identifier, sizes = nshared_objects
4748 for (int i = 0; i < nPages; i++) { 4770 for (int i = 0; i < nPages; i++) {
4771 required_bits = dwSharedIdBits;
4772 required_bits *= m_dwNSharedObjsArray[i];
4773 if (!CanReadFromBitStream(hStream, required_bits))
4774 return FALSE;
4749 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { 4775 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) {
4750 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); 4776 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits));
4751 } 4777 }
4752 } 4778 }
4753 hStream->ByteAlign(); 4779 hStream->ByteAlign();
4754 for (int i = 0; i < nPages; i++) { 4780 for (int i = 0; i < nPages; i++) {
4755 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; 4781 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i];
4756 safeSize *= dwSharedNumeratorBits; 4782 safeSize *= dwSharedNumeratorBits;
4757 if (!safeSize.IsValid()) 4783 if (!CanReadFromBitStream(hStream, safeSize))
4758 return FALSE; 4784 return FALSE;
4759 hStream->SkipBits(safeSize.ValueOrDie()); 4785 hStream->SkipBits(safeSize.ValueOrDie());
4760 } 4786 }
4761 hStream->ByteAlign(); 4787 hStream->ByteAlign();
4762 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); 4788 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages);
4763 safeTotalPageLen *= dwDeltaPageLenBits; 4789 safeTotalPageLen *= dwDeltaPageLenBits;
4764 if (!safeTotalPageLen.IsValid()) 4790 if (!CanReadFromBitStream(hStream, safeTotalPageLen))
4765 return FALSE; 4791 return FALSE;
4766 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); 4792 hStream->SkipBits(safeTotalPageLen.ValueOrDie());
4767 hStream->ByteAlign(); 4793 hStream->ByteAlign();
4768 return TRUE; 4794 return TRUE;
4769 } 4795 }
4770 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { 4796 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
4771 if (!hStream) 4797 FX_DWORD offset) {
4798 if (!hStream || hStream->IsEOF())
4772 return FALSE; 4799 return FALSE;
4773 int nStreamOffset = ReadPrimaryHintStreamOffset(); 4800 int nStreamOffset = ReadPrimaryHintStreamOffset();
4774 int nStreamLen = ReadPrimaryHintStreamLength(); 4801 int nStreamLen = ReadPrimaryHintStreamLength();
4775 if (nStreamOffset < 0 || nStreamLen < 1) 4802 if (nStreamOffset < 0 || nStreamLen < 1)
4776 return FALSE; 4803 return FALSE;
4804
4805 FX_SAFE_DWORD bit_offset = offset;
4806 bit_offset *= 8;
4807 if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie())
4808 return FALSE;
4809 hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos());
4810
4811 const FX_DWORD kHeaderSize = 192;
4812 if (hStream->BitsRemaining() < kHeaderSize)
4813 return FALSE;
4777 // Item 1: The object number of the first object in the shared objects 4814 // Item 1: The object number of the first object in the shared objects
4778 // section. 4815 // section.
4779 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); 4816 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32);
4780 // Item 2: The location of the first object in the shared objects section. 4817 // Item 2: The location of the first object in the shared objects section.
4781 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); 4818 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32);
4782 if (dwFirstSharedObjLoc > nStreamOffset) 4819 if (dwFirstSharedObjLoc > nStreamOffset)
4783 dwFirstSharedObjLoc += nStreamLen; 4820 dwFirstSharedObjLoc += nStreamLen;
4784 // Item 3: The number of shared object entries for the first page. 4821 // Item 3: The number of shared object entries for the first page.
4785 m_nFirstPageSharedObjs = hStream->GetBits(32); 4822 m_nFirstPageSharedObjs = hStream->GetBits(32);
4786 // Item 4: The number of shared object entries for the shared objects 4823 // 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. 4824 // section, including the number of shared object entries for the first page.
4788 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); 4825 FX_DWORD dwSharedObjTotal = hStream->GetBits(32);
4789 // Item 5: The number of bits needed to represent the greatest number of 4826 // Item 5: The number of bits needed to represent the greatest number of
4790 // objects in a shared object group. Skipped. 4827 // objects in a shared object group. Skipped.
4791 hStream->SkipBits(16); 4828 hStream->SkipBits(16);
4792 // Item 6: The least length of a shared object group in bytes. 4829 // Item 6: The least length of a shared object group in bytes.
4793 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); 4830 FX_DWORD dwGroupLeastLen = hStream->GetBits(32);
4794 // Item 7: The number of bits needed to represent the difference between the 4831 // 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. 4832 // greatest and least length of a shared object group, in bytes.
4796 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); 4833 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16);
4797 CPDF_Object* pFirstPageObj = 4834 CPDF_Object* pFirstPageObj =
4798 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); 4835 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4799 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; 4836 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
4800 if (nFirstPageObjNum < 0) 4837 if (nFirstPageObjNum < 0)
4801 return FALSE; 4838 return FALSE;
4802 FX_DWORD dwPrevObjLen = 0; 4839 FX_DWORD dwPrevObjLen = 0;
4803 FX_DWORD dwCurObjLen = 0; 4840 FX_DWORD dwCurObjLen = 0;
4841 FX_SAFE_DWORD required_bits = dwSharedObjTotal;
4842 required_bits *= dwDeltaGroupLen;
4843 if (!CanReadFromBitStream(hStream, required_bits))
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
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
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) {
Lei Zhang 2015/12/12 02:51:18 Can't you merge "!shared_hint_table_offset" with "
Oliver Chang 2015/12/12 03:02:07 Done.
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 }
OLDNEW
« no previous file with comments | « core/include/fxcrt/fx_basic.h ('k') | core/src/fpdfapi/fpdf_parser/parser_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698