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

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp

Issue 2300903002: Handle another integer overflow in ReadPageHintTable(). (Closed)
Patch Set: FALSE-false Created 4 years, 3 months 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 | « no previous file | 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 2016 PDFium Authors. All rights reserved. 1 // Copyright 2016 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 "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h" 7 #include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h"
8 8
9 #include <limits>
10
9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h"
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
15 #include "core/fxcrt/include/fx_safe_types.h" 17 #include "core/fxcrt/include/fx_safe_types.h"
16 18
17 namespace { 19 namespace {
18 20
(...skipping 23 matching lines...) Expand all
42 szArray[index] > szArray[index + 1]) { 44 szArray[index] > szArray[index + 1]) {
43 return 0; 45 return 0;
44 } 46 }
45 return szArray[index + 1] - szArray[index]; 47 return szArray[index + 1] - szArray[index];
46 } 48 }
47 49
48 bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { 50 bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
49 if (!hStream || hStream->IsEOF()) 51 if (!hStream || hStream->IsEOF())
50 return false; 52 return false;
51 53
52 int nStreamOffset = ReadPrimaryHintStreamOffset(); 54 int nStreamOffset = ReadPrimaryHintStreamOffset();
Tom Sepez 2016/09/01 16:08:04 nit: can these two be int32_t's since presumably t
Lei Zhang 2016/09/01 17:49:19 No, they are from CPDF_Number::GetInteger() and no
55 if (nStreamOffset < 0)
56 return false;
57
53 int nStreamLen = ReadPrimaryHintStreamLength(); 58 int nStreamLen = ReadPrimaryHintStreamLength();
54 if (nStreamOffset < 0 || nStreamLen < 1) 59 if (nStreamLen < 1 ||
60 !pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(nStreamLen)) {
Tom Sepez 2016/09/01 16:08:04 Ok, but I thought FX_FILESIZE was signed so we cou
Lei Zhang 2016/09/01 17:49:18 It may not be obvious if an int fits inside a FX_F
55 return false; 61 return false;
62 }
56 63
57 const uint32_t kHeaderSize = 288; 64 const uint32_t kHeaderSize = 288;
58 if (hStream->BitsRemaining() < kHeaderSize) 65 if (hStream->BitsRemaining() < kHeaderSize)
59 return false; 66 return false;
60 67
61 // Item 1: The least number of objects in a page. 68 // Item 1: The least number of objects in a page.
62 const uint32_t dwObjLeastNum = hStream->GetBits(32); 69 const uint32_t dwObjLeastNum = hStream->GetBits(32);
63 if (!dwObjLeastNum) 70 if (!dwObjLeastNum)
64 return FALSE; 71 return false;
65 72
66 // Item 2: The location of the first page's page object. 73 // Item 2: The location of the first page's page object.
67 const uint32_t dwFirstObjLoc = hStream->GetBits(32); 74 const uint32_t dwFirstObjLoc = hStream->GetBits(32);
68 if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) { 75 if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) {
69 FX_SAFE_UINT32 safeLoc = pdfium::base::checked_cast<uint32_t>(nStreamLen); 76 FX_SAFE_FILESIZE safeLoc = nStreamLen;
70 safeLoc += dwFirstObjLoc; 77 safeLoc += dwFirstObjLoc;
71 if (!safeLoc.IsValid()) 78 if (!safeLoc.IsValid())
72 return false; 79 return false;
73 m_szFirstPageObjOffset = 80 m_szFirstPageObjOffset = safeLoc.ValueOrDie();
74 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie());
75 } else { 81 } else {
76 m_szFirstPageObjOffset = 82 if (!pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(dwFirstObjLoc))
77 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); 83 return false;
84 m_szFirstPageObjOffset = dwFirstObjLoc;
78 } 85 }
79 86
80 // Item 3: The number of bits needed to represent the difference 87 // Item 3: The number of bits needed to represent the difference
81 // between the greatest and least number of objects in a page. 88 // between the greatest and least number of objects in a page.
82 const uint32_t dwDeltaObjectsBits = hStream->GetBits(16); 89 const uint32_t dwDeltaObjectsBits = hStream->GetBits(16);
83 if (!dwDeltaObjectsBits) 90 if (!dwDeltaObjectsBits)
84 return FALSE; 91 return false;
85 92
86 // Item 4: The least length of a page in bytes. 93 // Item 4: The least length of a page in bytes.
87 const uint32_t dwPageLeastLen = hStream->GetBits(32); 94 const uint32_t dwPageLeastLen = hStream->GetBits(32);
88 if (!dwPageLeastLen) 95 if (!dwPageLeastLen)
89 return FALSE; 96 return false;
90 97
91 // Item 5: The number of bits needed to represent the difference 98 // Item 5: The number of bits needed to represent the difference
92 // between the greatest and least length of a page, in bytes. 99 // between the greatest and least length of a page, in bytes.
93 const uint32_t dwDeltaPageLenBits = hStream->GetBits(16); 100 const uint32_t dwDeltaPageLenBits = hStream->GetBits(16);
94 if (!dwDeltaPageLenBits) 101 if (!dwDeltaPageLenBits)
95 return FALSE; 102 return false;
96 103
97 // Skip Item 6, 7, 8, 9 total 96 bits. 104 // Skip Item 6, 7, 8, 9 total 96 bits.
98 hStream->SkipBits(96); 105 hStream->SkipBits(96);
99 106
100 // Item 10: The number of bits needed to represent the greatest 107 // Item 10: The number of bits needed to represent the greatest
101 // number of shared object references. 108 // number of shared object references.
102 const uint32_t dwSharedObjBits = hStream->GetBits(16); 109 const uint32_t dwSharedObjBits = hStream->GetBits(16);
103 110
104 // Item 11: The number of bits needed to represent the numerically 111 // Item 11: The number of bits needed to represent the numerically
105 // greatest shared object identifier used by the pages. 112 // greatest shared object identifier used by the pages.
106 const uint32_t dwSharedIdBits = hStream->GetBits(16); 113 const uint32_t dwSharedIdBits = hStream->GetBits(16);
107 if (!dwSharedObjBits) 114 if (!dwSharedObjBits)
108 return FALSE; 115 return false;
109 116
110 // Item 12: The number of bits needed to represent the numerator of 117 // Item 12: The number of bits needed to represent the numerator of
111 // the fractional position for each shared object reference. For each 118 // the fractional position for each shared object reference. For each
112 // shared object referenced from a page, there is an indication of 119 // shared object referenced from a page, there is an indication of
113 // where in the page's content stream the object is first referenced. 120 // where in the page's content stream the object is first referenced.
114 const uint32_t dwSharedNumeratorBits = hStream->GetBits(16); 121 const uint32_t dwSharedNumeratorBits = hStream->GetBits(16);
115 if (!dwSharedIdBits) 122 if (!dwSharedIdBits)
116 return FALSE; 123 return false;
117 124
118 // Item 13: Skip Item 13 which has 16 bits. 125 // Item 13: Skip Item 13 which has 16 bits.
119 hStream->SkipBits(16); 126 hStream->SkipBits(16);
120 127
121 // Sanity check values from the page table header. 2^|kMaxBits| should be more 128 // Sanity check values from the page table header. 2^|kMaxBits| should be more
122 // than enough to represent most of the values here. 129 // than enough to represent most of the values here.
123 constexpr uint32_t kMaxBits = 34; 130 constexpr uint32_t kMaxBits = 34;
124 if (dwSharedObjBits > kMaxBits || dwDeltaObjectsBits > kMaxBits || 131 if (dwSharedObjBits > kMaxBits || dwDeltaObjectsBits > kMaxBits ||
125 dwDeltaPageLenBits > kMaxBits || dwSharedIdBits > kMaxBits) { 132 dwDeltaPageLenBits > kMaxBits || dwSharedIdBits > kMaxBits) {
126 return false; 133 return false;
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 } 512 }
506 513
507 int CPDF_HintTables::ReadPrimaryHintStream(int index) const { 514 int CPDF_HintTables::ReadPrimaryHintStream(int index) const {
508 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); 515 CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H");
509 if (!pRange) 516 if (!pRange)
510 return -1; 517 return -1;
511 518
512 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index); 519 CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index);
513 return pStreamLen ? pStreamLen->GetInteger() : -1; 520 return pStreamLen ? pStreamLen->GetInteger() : -1;
514 } 521 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698