Index: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
index db9e1779768341a57480a5e2ef751118f96a55bf..c2a856cb5049fce1203860de5b73ca024a21e508 100644 |
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
@@ -75,6 +75,12 @@ int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { |
return pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); |
} |
+bool CanReadFromBitStream(const CFX_BitStream* hStream, |
+ const FX_SAFE_DWORD& num_bits) { |
+ return (num_bits.IsValid() && |
+ hStream->BitsRemaining() >= num_bits.ValueOrDie()); |
+} |
+ |
} // namespace |
// TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal. |
@@ -4695,10 +4701,10 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
int nPages = pPageNum ? pPageNum->GetInteger() : 0; |
if (nPages < 1) |
return FALSE; |
+ |
FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; |
required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
- if (!required_bits.IsValid() || |
- hStream->BitsRemaining() < required_bits.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, required_bits)) |
return FALSE; |
for (int i = 0; i < nPages; ++i) { |
FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); |
@@ -4708,10 +4714,10 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); |
} |
hStream->ByteAlign(); |
+ |
required_bits = dwDeltaPageLenBits; |
required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
- if (!required_bits.IsValid() || |
- hStream->BitsRemaining() < required_bits.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, required_bits)) |
return FALSE; |
CFX_DWordArray dwPageLenArray; |
for (int i = 0; i < nPages; ++i) { |
@@ -4752,40 +4758,41 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
dwPageLenArray[nPages - 1]); |
} |
hStream->ByteAlign(); |
+ |
// number of shared objects |
required_bits = dwSharedObjBits; |
required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); |
- if (!required_bits.IsValid() || |
- hStream->BitsRemaining() < required_bits.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, required_bits)) |
return FALSE; |
for (int i = 0; i < nPages; i++) { |
m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); |
} |
hStream->ByteAlign(); |
+ |
// array of identifier, sizes = nshared_objects |
for (int i = 0; i < nPages; i++) { |
required_bits = dwSharedIdBits; |
required_bits *= m_dwNSharedObjsArray[i]; |
- if (!required_bits.IsValid() || |
- hStream->BitsRemaining() < required_bits.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, required_bits)) |
return FALSE; |
for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { |
m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); |
} |
} |
hStream->ByteAlign(); |
+ |
for (int i = 0; i < nPages; i++) { |
FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; |
safeSize *= dwSharedNumeratorBits; |
- if (!safeSize.IsValid() || hStream->BitsRemaining() < safeSize.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, safeSize)) |
return FALSE; |
hStream->SkipBits(safeSize.ValueOrDie()); |
} |
hStream->ByteAlign(); |
+ |
FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); |
safeTotalPageLen *= dwDeltaPageLenBits; |
- if (!safeTotalPageLen.IsValid() || |
- hStream->BitsRemaining() < safeTotalPageLen.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, safeTotalPageLen)) |
return FALSE; |
hStream->SkipBits(safeTotalPageLen.ValueOrDie()); |
hStream->ByteAlign(); |
@@ -4838,8 +4845,7 @@ FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
FX_DWORD dwCurObjLen = 0; |
FX_SAFE_DWORD required_bits = dwSharedObjTotal; |
required_bits *= dwDeltaGroupLen; |
- if (!required_bits.IsValid() || |
- hStream->BitsRemaining() < required_bits.ValueOrDie()) |
+ if (!CanReadFromBitStream(hStream, required_bits)) |
return FALSE; |
for (int i = 0; i < dwSharedObjTotal; ++i) { |
@@ -4973,8 +4979,8 @@ FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
// The header section of shared object hint table is 24 bytes. |
// Hint table has at least 60 bytes. |
const FX_DWORD MIN_STREAM_LEN = 60; |
- if (size < MIN_STREAM_LEN || shared_hint_table_offset < 0 || |
- size < shared_hint_table_offset || !shared_hint_table_offset) { |
+ if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || |
+ size < shared_hint_table_offset) { |
return FALSE; |
} |
CFX_BitStream bs; |