summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_hint_tables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/parser/cpdf_hint_tables.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables.cpp103
1 files changed, 45 insertions, 58 deletions
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp
index 7d371909e9..fc9a46d68a 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp
@@ -37,6 +37,9 @@ bool IsValidPageOffsetHintTableBitCount(uint32_t bits) {
} // namespace
+CPDF_HintTables::PageInfo::PageInfo() = default;
+CPDF_HintTables::PageInfo::~PageInfo() = default;
+
CPDF_HintTables::CPDF_HintTables(CPDF_ReadValidator* pValidator,
CPDF_LinearizedHeader* pLinearized)
: m_pValidator(pValidator),
@@ -59,6 +62,14 @@ uint32_t CPDF_HintTables::GetItemLength(
}
bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
+ const uint32_t nPages = m_pLinearized->GetPageCount();
+ if (nPages < 1 || nPages >= CPDF_Document::kPageMaxNum)
+ return false;
+
+ const uint32_t nFirstPageNum = m_pLinearized->GetFirstPageNo();
+ if (nFirstPageNum >= nPages)
+ return false;
+
if (!hStream || hStream->IsEOF())
return false;
@@ -122,83 +133,78 @@ bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
// Item 13: Skip Item 13 which has 16 bits.
hStream->SkipBits(16);
- const uint32_t nPages = m_pLinearized->GetPageCount();
- if (nPages < 1 || nPages >= CPDF_Document::kPageMaxNum)
- return false;
-
- const uint32_t dwPages = pdfium::base::checked_cast<uint32_t>(nPages);
FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits;
- required_bits *= dwPages;
+ required_bits *= nPages;
if (!CanReadFromBitStream(hStream, required_bits))
return false;
+ m_PageInfos = std::vector<PageInfo>(nPages);
+ m_PageInfos[nFirstPageNum].set_start_obj_num(
+ m_pLinearized->GetFirstPageObjNum());
+ // The object number of remaining pages starts from 1.
+ uint32_t dwStartObjNum = 1;
for (uint32_t i = 0; i < nPages; ++i) {
FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
safeDeltaObj += dwObjLeastNum;
if (!safeDeltaObj.IsValid())
return false;
- m_dwDeltaNObjsArray.push_back(safeDeltaObj.ValueOrDie());
+ m_PageInfos[i].set_objects_count(safeDeltaObj.ValueOrDie());
+ if (i == nFirstPageNum)
+ continue;
+ m_PageInfos[i].set_start_obj_num(dwStartObjNum);
+ dwStartObjNum += m_PageInfos[i].objects_count();
}
hStream->ByteAlign();
required_bits = dwDeltaPageLenBits;
- required_bits *= dwPages;
+ required_bits *= nPages;
if (!CanReadFromBitStream(hStream, required_bits))
return false;
- std::vector<uint32_t> dwPageLenArray;
for (uint32_t i = 0; i < nPages; ++i) {
FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits);
safePageLen += dwPageLeastLen;
if (!safePageLen.IsValid())
return false;
-
- dwPageLenArray.push_back(safePageLen.ValueOrDie());
+ m_PageInfos[i].set_page_length(safePageLen.ValueOrDie());
}
- const uint32_t nFirstPageNum = m_pLinearized->GetFirstPageNo();
- if (nFirstPageNum >= nPages)
- return false;
-
- m_szPageOffsetArray.resize(nPages, 0);
ASSERT(m_szFirstPageObjOffset);
- m_szPageOffsetArray[nFirstPageNum] = m_szFirstPageObjOffset;
- FX_FILESIZE prev_page_offset = m_pLinearized->GetFirstPageEndOffset();
+ m_PageInfos[nFirstPageNum].set_page_offset(m_szFirstPageObjOffset);
+ FX_FILESIZE prev_page_end = m_pLinearized->GetFirstPageEndOffset();
for (uint32_t i = 0; i < nPages; ++i) {
if (i == nFirstPageNum)
continue;
-
- m_szPageOffsetArray[i] = prev_page_offset;
- prev_page_offset += dwPageLenArray[i];
+ m_PageInfos[i].set_page_offset(prev_page_end);
+ prev_page_end += m_PageInfos[i].page_length();
}
- m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] +
- dwPageLenArray[nPages - 1]);
hStream->ByteAlign();
// Number of shared objects.
required_bits = dwSharedObjBits;
- required_bits *= dwPages;
+ required_bits *= nPages;
if (!CanReadFromBitStream(hStream, required_bits))
return false;
+ std::vector<uint32_t> dwNSharedObjsArray(nPages);
for (uint32_t i = 0; i < nPages; i++)
- m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits));
+ dwNSharedObjsArray[i] = hStream->GetBits(dwSharedObjBits);
hStream->ByteAlign();
// Array of identifiers, size = nshared_objects.
for (uint32_t i = 0; i < nPages; i++) {
required_bits = dwSharedIdBits;
- required_bits *= m_dwNSharedObjsArray[i];
+ required_bits *= dwNSharedObjsArray[i];
if (!CanReadFromBitStream(hStream, required_bits))
return false;
- for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++)
- m_dwIdentifierArray.push_back(hStream->GetBits(dwSharedIdBits));
+ for (uint32_t j = 0; j < dwNSharedObjsArray[i]; j++)
+ m_PageInfos[i].AddIdentifier(hStream->GetBits(dwSharedIdBits));
}
hStream->ByteAlign();
for (uint32_t i = 0; i < nPages; i++) {
- FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i];
+ FX_SAFE_UINT32 safeSize = dwNSharedObjsArray[i];
safeSize *= dwSharedNumeratorBits;
if (!CanReadFromBitStream(hStream, safeSize))
return false;
@@ -207,7 +213,7 @@ bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
}
hStream->ByteAlign();
- FX_SAFE_UINT32 safeTotalPageLen = dwPages;
+ FX_SAFE_UINT32 safeTotalPageLen = nPages;
safeTotalPageLen *= dwDeltaPageLenBits;
if (!CanReadFromBitStream(hStream, safeTotalPageLen))
return false;
@@ -343,24 +349,9 @@ bool CPDF_HintTables::GetPagePos(uint32_t index,
if (index >= m_pLinearized->GetPageCount())
return false;
- *szPageStartPos = m_szPageOffsetArray[index];
- *szPageLength = GetItemLength(index, m_szPageOffsetArray);
-
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
-
- const uint32_t dwFirstPageNum = m_pLinearized->GetFirstPageNo();
- if (index == dwFirstPageNum) {
- *dwObjNum = nFirstPageObjNum;
- return true;
- }
-
- // The object number of remaining pages starts from 1.
- *dwObjNum = 1;
- for (uint32_t i = 0; i < index; ++i) {
- if (i == dwFirstPageNum)
- continue;
- *dwObjNum += m_dwDeltaNObjsArray[i];
- }
+ *szPageStartPos = m_PageInfos[index].page_offset();
+ *szPageLength = m_PageInfos[index].page_length();
+ *dwObjNum = m_PageInfos[index].start_obj_num();
return true;
}
@@ -368,27 +359,23 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(uint32_t index) {
if (index == m_pLinearized->GetFirstPageNo())
return CPDF_DataAvail::DataAvailable;
- uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray);
- // If two pages have the same offset, it should be treated as an error.
+ if (index >= m_pLinearized->GetPageCount())
+ return CPDF_DataAvail::DataError;
+
+ uint32_t dwLength = m_PageInfos[index].page_length();
if (!dwLength)
return CPDF_DataAvail::DataError;
if (!m_pValidator->CheckDataRangeAndRequestIfUnavailable(
- m_szPageOffsetArray[index], dwLength)) {
+ m_PageInfos[index].page_offset(), dwLength)) {
return CPDF_DataAvail::DataNotAvailable;
}
// Download data of shared objects in the page.
- uint32_t offset = 0;
- for (uint32_t i = 0; i < index; ++i)
- offset += m_dwNSharedObjsArray[i];
-
const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
- uint32_t dwIndex = 0;
uint32_t dwObjNum = 0;
- for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
- dwIndex = m_dwIdentifierArray[offset + j];
+ for (const uint32_t dwIndex : m_PageInfos[index].Identifiers()) {
if (dwIndex >= m_dwSharedObjNumArray.size())
continue;