Index: core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp |
diff --git a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp b/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp |
index 7a3fbacfb3ae91b71b9ca87da99b2edcb44ecb69..4d48ab4bfa5d8e6f8ad8918a07cd3601da4320fa 100644 |
--- a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp |
+++ b/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp |
@@ -6,9 +6,10 @@ |
#include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h" |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
#include "core/fxcrt/include/fx_safe_types.h" |
@@ -16,9 +17,8 @@ |
namespace { |
bool CanReadFromBitStream(const CFX_BitStream* hStream, |
- const FX_SAFE_UINT32& num_bits) { |
- return num_bits.IsValid() && |
- hStream->BitsRemaining() >= num_bits.ValueOrDie(); |
+ const FX_SAFE_UINT32& bits) { |
+ return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie(); |
} |
} // namespace |
@@ -28,15 +28,12 @@ CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail, |
: m_pDataAvail(pDataAvail), |
m_pLinearizedDict(pLinearized), |
m_nFirstPageSharedObjs(0), |
- m_szFirstPageObjOffset(0) {} |
- |
-CPDF_HintTables::~CPDF_HintTables() { |
- m_dwDeltaNObjsArray.RemoveAll(); |
- m_dwNSharedObjsArray.RemoveAll(); |
- m_dwSharedObjNumArray.RemoveAll(); |
- m_dwIdentifierArray.RemoveAll(); |
+ m_szFirstPageObjOffset(0) { |
+ ASSERT(m_pLinearizedDict); |
} |
+CPDF_HintTables::~CPDF_HintTables() {} |
+ |
uint32_t CPDF_HintTables::GetItemLength( |
int index, |
const std::vector<FX_FILESIZE>& szArray) { |
@@ -48,18 +45,18 @@ uint32_t CPDF_HintTables::GetItemLength( |
return szArray[index + 1] - szArray[index]; |
} |
-FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
+bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
if (!hStream || hStream->IsEOF()) |
- return FALSE; |
+ return false; |
int nStreamOffset = ReadPrimaryHintStreamOffset(); |
int nStreamLen = ReadPrimaryHintStreamLength(); |
if (nStreamOffset < 0 || nStreamLen < 1) |
- return FALSE; |
+ return false; |
const uint32_t kHeaderSize = 288; |
if (hStream->BitsRemaining() < kHeaderSize) |
- return FALSE; |
+ return false; |
// Item 1: The least number of objects in a page. |
uint32_t dwObjLeastNum = hStream->GetBits(32); |
@@ -70,7 +67,7 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
FX_SAFE_UINT32 safeLoc = pdfium::base::checked_cast<uint32_t>(nStreamLen); |
safeLoc += dwFirstObjLoc; |
if (!safeLoc.IsValid()) |
- return FALSE; |
+ return false; |
m_szFirstPageObjOffset = |
pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); |
} else { |
@@ -113,48 +110,46 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
// shared object references. 2^39 should be more than enough. |
constexpr uint32_t kMaxSharedObjBits = 39; |
if (dwSharedObjBits > kMaxSharedObjBits) |
- return FALSE; |
+ return false; |
- CPDF_Object* pPageNum = m_pLinearizedDict->GetDirectObjectBy("N"); |
- int nPages = pPageNum ? pPageNum->GetInteger() : 0; |
+ const int nPages = GetNumberOfPages(); |
if (nPages < 1) |
- return FALSE; |
+ return false; |
+ const uint32_t dwPages = pdfium::base::checked_cast<uint32_t>(nPages); |
FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits; |
- required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); |
+ required_bits *= dwPages; |
if (!CanReadFromBitStream(hStream, required_bits)) |
- return FALSE; |
+ return false; |
for (int i = 0; i < nPages; ++i) { |
FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); |
safeDeltaObj += dwObjLeastNum; |
if (!safeDeltaObj.IsValid()) |
- return FALSE; |
- m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); |
+ return false; |
+ m_dwDeltaNObjsArray.push_back(safeDeltaObj.ValueOrDie()); |
} |
hStream->ByteAlign(); |
required_bits = dwDeltaPageLenBits; |
- required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); |
+ required_bits *= dwPages; |
if (!CanReadFromBitStream(hStream, required_bits)) |
- return FALSE; |
+ return false; |
CFX_ArrayTemplate<uint32_t> dwPageLenArray; |
for (int i = 0; i < nPages; ++i) { |
FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits); |
safePageLen += dwPageLeastLen; |
if (!safePageLen.IsValid()) |
- return FALSE; |
+ return false; |
dwPageLenArray.Add(safePageLen.ValueOrDie()); |
} |
- CPDF_Object* pOffsetE = m_pLinearizedDict->GetDirectObjectBy("E"); |
- int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; |
+ int nOffsetE = GetEndOfFirstPageOffset(); |
if (nOffsetE < 0) |
- return FALSE; |
+ return false; |
- CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P"); |
- int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; |
+ int nFirstPageNum = GetFirstPageNumber(); |
for (int i = 0; i < nPages; ++i) { |
if (i == nFirstPageNum) { |
m_szPageOffsetArray.push_back(m_szFirstPageObjOffset); |
@@ -175,20 +170,18 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
} |
} |
- if (nPages > 0) { |
Lei Zhang
2016/08/15 05:50:55
Always true. See line 120.
|
- m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] + |
- dwPageLenArray[nPages - 1]); |
- } |
+ m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] + |
+ dwPageLenArray[nPages - 1]); |
hStream->ByteAlign(); |
// Number of shared objects. |
required_bits = dwSharedObjBits; |
- required_bits *= pdfium::base::checked_cast<uint32_t>(nPages); |
+ required_bits *= dwPages; |
if (!CanReadFromBitStream(hStream, required_bits)) |
- return FALSE; |
+ return false; |
for (int i = 0; i < nPages; i++) |
- m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); |
+ m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits)); |
hStream->ByteAlign(); |
// Array of identifiers, size = nshared_objects. |
@@ -196,10 +189,10 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
required_bits = dwSharedIdBits; |
required_bits *= m_dwNSharedObjsArray[i]; |
if (!CanReadFromBitStream(hStream, required_bits)) |
- return FALSE; |
+ return false; |
for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++) |
- m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); |
+ m_dwIdentifierArray.push_back(hStream->GetBits(dwSharedIdBits)); |
} |
hStream->ByteAlign(); |
@@ -207,42 +200,41 @@ FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i]; |
safeSize *= dwSharedNumeratorBits; |
if (!CanReadFromBitStream(hStream, safeSize)) |
- return FALSE; |
+ return false; |
hStream->SkipBits(safeSize.ValueOrDie()); |
} |
hStream->ByteAlign(); |
- FX_SAFE_UINT32 safeTotalPageLen = |
- pdfium::base::checked_cast<uint32_t>(nPages); |
+ FX_SAFE_UINT32 safeTotalPageLen = dwPages; |
safeTotalPageLen *= dwDeltaPageLenBits; |
if (!CanReadFromBitStream(hStream, safeTotalPageLen)) |
- return FALSE; |
+ return false; |
hStream->SkipBits(safeTotalPageLen.ValueOrDie()); |
hStream->ByteAlign(); |
- return TRUE; |
+ return true; |
} |
-FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
- uint32_t offset) { |
+bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
+ uint32_t offset) { |
if (!hStream || hStream->IsEOF()) |
- return FALSE; |
+ return false; |
int nStreamOffset = ReadPrimaryHintStreamOffset(); |
int nStreamLen = ReadPrimaryHintStreamLength(); |
if (nStreamOffset < 0 || nStreamLen < 1) |
- return FALSE; |
+ return false; |
FX_SAFE_UINT32 bit_offset = offset; |
bit_offset *= 8; |
if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) |
- return FALSE; |
+ return false; |
hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); |
const uint32_t kHeaderSize = 192; |
if (hStream->BitsRemaining() < kHeaderSize) |
- return FALSE; |
+ return false; |
// Item 1: The object number of the first object in the shared objects |
// section. |
@@ -270,41 +262,41 @@ FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
// Item 7: The number of bits needed to represent the difference between the |
// greatest and least length of a shared object group, in bytes. |
uint32_t dwDeltaGroupLen = hStream->GetBits(16); |
- CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O"); |
- int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
+ |
+ int nFirstPageObjNum = GetFirstPageObjectNumber(); |
if (nFirstPageObjNum < 0) |
- return FALSE; |
+ return false; |
uint32_t dwPrevObjLen = 0; |
uint32_t dwCurObjLen = 0; |
FX_SAFE_UINT32 required_bits = dwSharedObjTotal; |
required_bits *= dwDeltaGroupLen; |
if (!CanReadFromBitStream(hStream, required_bits)) |
- return FALSE; |
+ return false; |
for (uint32_t i = 0; i < dwSharedObjTotal; ++i) { |
dwPrevObjLen = dwCurObjLen; |
FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen); |
safeObjLen += dwGroupLeastLen; |
if (!safeObjLen.IsValid()) |
- return FALSE; |
+ return false; |
dwCurObjLen = safeObjLen.ValueOrDie(); |
if (i < m_nFirstPageSharedObjs) { |
- m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); |
+ m_dwSharedObjNumArray.push_back(nFirstPageObjNum + i); |
if (i == 0) |
m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset); |
} else { |
FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum; |
safeObjNum += i - m_nFirstPageSharedObjs; |
if (!safeObjNum.IsValid()) |
- return FALSE; |
+ return false; |
- m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); |
+ m_dwSharedObjNumArray.push_back(safeObjNum.ValueOrDie()); |
if (i == m_nFirstPageSharedObjs) { |
FX_SAFE_FILESIZE safeLoc = dwFirstSharedObjLoc; |
if (!safeLoc.IsValid()) |
- return FALSE; |
+ return false; |
m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); |
} |
@@ -314,7 +306,7 @@ FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
FX_SAFE_FILESIZE safeLoc = dwPrevObjLen; |
safeLoc += m_szSharedObjOffsetArray[i - 1]; |
if (!safeLoc.IsValid()) |
- return FALSE; |
+ return false; |
m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); |
} |
@@ -324,61 +316,54 @@ FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, |
FX_SAFE_FILESIZE safeLoc = dwCurObjLen; |
safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; |
if (!safeLoc.IsValid()) |
- return FALSE; |
+ return false; |
m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); |
} |
hStream->ByteAlign(); |
if (hStream->BitsRemaining() < dwSharedObjTotal) |
- return FALSE; |
+ return false; |
hStream->SkipBits(dwSharedObjTotal); |
hStream->ByteAlign(); |
- return TRUE; |
+ return true; |
} |
-FX_BOOL CPDF_HintTables::GetPagePos(int index, |
- FX_FILESIZE& szPageStartPos, |
- FX_FILESIZE& szPageLength, |
- uint32_t& dwObjNum) { |
- if (!m_pLinearizedDict) |
- return FALSE; |
- |
- szPageStartPos = m_szPageOffsetArray[index]; |
- szPageLength = GetItemLength(index, m_szPageOffsetArray); |
+bool CPDF_HintTables::GetPagePos(int index, |
+ FX_FILESIZE* szPageStartPos, |
+ FX_FILESIZE* szPageLength, |
+ uint32_t* dwObjNum) { |
+ *szPageStartPos = m_szPageOffsetArray[index]; |
+ *szPageLength = GetItemLength(index, m_szPageOffsetArray); |
- CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P"); |
- int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; |
- |
- CPDF_Object* pFirstPageObjNum = m_pLinearizedDict->GetDirectObjectBy("O"); |
- if (!pFirstPageObjNum) |
- return FALSE; |
+ int nFirstPageObjNum = GetFirstPageObjectNumber(); |
+ if (nFirstPageObjNum < 0) |
+ return false; |
- int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); |
+ int nFirstPageNum = GetFirstPageNumber(); |
if (index == nFirstPageNum) { |
- dwObjNum = nFirstPageObjNum; |
- return TRUE; |
+ *dwObjNum = nFirstPageObjNum; |
+ return true; |
} |
// The object number of remaining pages starts from 1. |
- dwObjNum = 1; |
+ *dwObjNum = 1; |
for (int i = 0; i < index; ++i) { |
if (i == nFirstPageNum) |
continue; |
- dwObjNum += m_dwDeltaNObjsArray[i]; |
+ *dwObjNum += m_dwDeltaNObjsArray[i]; |
} |
- return TRUE; |
+ return true; |
} |
CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( |
int index, |
CPDF_DataAvail::DownloadHints* pHints) { |
- if (!m_pLinearizedDict || !pHints) |
+ if (!pHints) |
return CPDF_DataAvail::DataError; |
- CPDF_Object* pFirstAvailPage = m_pLinearizedDict->GetDirectObjectBy("P"); |
- int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; |
+ int nFirstAvailPage = GetFirstPageNumber(); |
if (index == nFirstAvailPage) |
return CPDF_DataAvail::DataAvailable; |
@@ -395,8 +380,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( |
for (int i = 0; i < index; ++i) |
offset += m_dwNSharedObjsArray[i]; |
- CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O"); |
- int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
+ int nFirstPageObjNum = GetFirstPageObjectNumber(); |
if (nFirstPageObjNum < 0) |
return CPDF_DataAvail::DataError; |
@@ -404,7 +388,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( |
uint32_t dwObjNum = 0; |
for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) { |
dwIndex = m_dwIdentifierArray[offset + j]; |
- if (dwIndex >= static_cast<uint32_t>(m_dwSharedObjNumArray.GetSize())) |
+ if (dwIndex >= m_dwSharedObjNumArray.size()) |
return CPDF_DataAvail::DataNotAvailable; |
dwObjNum = m_dwSharedObjNumArray[dwIndex]; |
@@ -427,18 +411,18 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( |
return CPDF_DataAvail::DataAvailable; |
} |
-FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
- if (!pHintStream || !m_pLinearizedDict) |
- return FALSE; |
+bool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
+ if (!pHintStream) |
+ return false; |
CPDF_Dictionary* pDict = pHintStream->GetDict(); |
CPDF_Object* pOffset = pDict ? pDict->GetObjectBy("S") : nullptr; |
if (!pOffset || !pOffset->IsNumber()) |
- return FALSE; |
+ return false; |
int shared_hint_table_offset = pOffset->GetInteger(); |
if (shared_hint_table_offset <= 0) |
- return FALSE; |
+ return false; |
CPDF_StreamAcc acc; |
acc.LoadAllData(pHintStream); |
@@ -449,12 +433,12 @@ FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
// Hint table has at least 60 bytes. |
const uint32_t kMinStreamLength = 60; |
if (size < kMinStreamLength) |
- return FALSE; |
+ return false; |
FX_SAFE_UINT32 safe_shared_hint_table_offset = shared_hint_table_offset; |
if (!safe_shared_hint_table_offset.IsValid() || |
size < safe_shared_hint_table_offset.ValueOrDie()) { |
- return FALSE; |
+ return false; |
} |
CFX_BitStream bs; |
@@ -463,32 +447,39 @@ FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
ReadSharedObjHintTable(&bs, shared_hint_table_offset); |
} |
-int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
- if (!m_pLinearizedDict) |
- return -1; |
+int CPDF_HintTables::GetEndOfFirstPageOffset() const { |
+ CPDF_Object* pOffsetE = m_pLinearizedDict->GetDirectObjectBy("E"); |
+ return pOffsetE ? pOffsetE->GetInteger() : -1; |
+} |
- CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); |
- if (!pRange) |
- return -1; |
+int CPDF_HintTables::GetNumberOfPages() const { |
+ CPDF_Object* pPageNum = m_pLinearizedDict->GetDirectObjectBy("N"); |
+ return pPageNum ? pPageNum->GetInteger() : 0; |
+} |
- CPDF_Object* pStreamOffset = pRange->GetDirectObjectAt(0); |
- if (!pStreamOffset) |
- return -1; |
+int CPDF_HintTables::GetFirstPageObjectNumber() const { |
+ CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectBy("O"); |
+ return pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
+} |
- return pStreamOffset->GetInteger(); |
+int CPDF_HintTables::GetFirstPageNumber() const { |
+ CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectBy("P"); |
+ return pFirstPageNum ? pFirstPageNum->GetInteger() : 0; |
+} |
+ |
+int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
+ return ReadPrimaryHintStream(0); |
} |
int CPDF_HintTables::ReadPrimaryHintStreamLength() const { |
- if (!m_pLinearizedDict) |
- return -1; |
+ return ReadPrimaryHintStream(1); |
+} |
+int CPDF_HintTables::ReadPrimaryHintStream(int index) const { |
CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); |
if (!pRange) |
return -1; |
- CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(1); |
- if (!pStreamLen) |
- return -1; |
- |
- return pStreamLen->GetInteger(); |
+ CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index); |
+ return pStreamLen ? pStreamLen->GetInteger() : -1; |
} |