Revert "Simplify CPDF_HintsTable."
This reverts commit 33591752d2cb14f2e07726ca52afce6efbdc07c9.
Reason for revert:
https://bugs.chromium.org/p/chromium/issues/detail?id=781529
Original change's description:
> Simplify CPDF_HintsTable.
>
> Use CPDF_LinearizedHeader directly.
>
> Change-Id: Id12402ef6e6f92fef68d0932df2e1ccb2dcf06aa
> Reviewed-on: https://pdfium-review.googlesource.com/15770
> Reviewed-by: Lei Zhang <thestig@chromium.org>
> Commit-Queue: Lei Zhang <thestig@chromium.org>
TBR=thestig@chromium.org,tsepez@chromium.org,art-snake@yandex-team.ru
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: Idaf8d4c91e869d92b44211cfe48f162037ed7327
Reviewed-on: https://pdfium-review.googlesource.com/17830
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp
index f27657e..2b58e9d 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp
@@ -61,8 +61,15 @@
if (!hStream || hStream->IsEOF())
return false;
- const FX_FILESIZE nStreamOffset = m_pLinearized->GetHintStart();
- const uint32_t nStreamLen = m_pLinearized->GetHintLength();
+ int nStreamOffset = ReadPrimaryHintStreamOffset();
+ if (nStreamOffset < 0)
+ return false;
+
+ int nStreamLen = ReadPrimaryHintStreamLength();
+ if (nStreamLen < 1 ||
+ !pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(nStreamLen)) {
+ return false;
+ }
const uint32_t kHeaderSize = 288;
if (hStream->BitsRemaining() < kHeaderSize)
@@ -130,7 +137,7 @@
// Item 13: Skip Item 13 which has 16 bits.
hStream->SkipBits(16);
- const uint32_t nPages = m_pLinearized->GetPageCount();
+ const int nPages = GetNumberOfPages();
if (nPages < 1 || nPages >= FPDF_PAGE_MAX_NUM)
return false;
@@ -140,7 +147,7 @@
if (!CanReadFromBitStream(hStream, required_bits))
return false;
- for (uint32_t i = 0; i < nPages; ++i) {
+ for (int i = 0; i < nPages; ++i) {
FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
safeDeltaObj += dwObjLeastNum;
if (!safeDeltaObj.IsValid())
@@ -155,7 +162,7 @@
return false;
std::vector<uint32_t> dwPageLenArray;
- for (uint32_t i = 0; i < nPages; ++i) {
+ for (int i = 0; i < nPages; ++i) {
FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits);
safePageLen += dwPageLeastLen;
if (!safePageLen.IsValid())
@@ -164,9 +171,15 @@
dwPageLenArray.push_back(safePageLen.ValueOrDie());
}
- const FX_FILESIZE nOffsetE = m_pLinearized->GetFirstPageEndOffset();
- const uint32_t nFirstPageNum = m_pLinearized->GetFirstPageNo();
- for (uint32_t i = 0; i < nPages; ++i) {
+ int nOffsetE = GetEndOfFirstPageOffset();
+ if (nOffsetE < 0)
+ return false;
+
+ int nFirstPageNum = GetFirstPageNumber();
+ if (nFirstPageNum < 0 || nFirstPageNum > std::numeric_limits<int>::max() - 1)
+ return false;
+
+ for (int i = 0; i < nPages; ++i) {
if (i == nFirstPageNum) {
m_szPageOffsetArray.push_back(m_szFirstPageObjOffset);
} else if (i == nFirstPageNum + 1) {
@@ -196,12 +209,12 @@
if (!CanReadFromBitStream(hStream, required_bits))
return false;
- for (uint32_t i = 0; i < nPages; i++)
+ for (int i = 0; i < nPages; i++)
m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits));
hStream->ByteAlign();
// Array of identifiers, size = nshared_objects.
- for (uint32_t i = 0; i < nPages; i++) {
+ for (int i = 0; i < nPages; i++) {
required_bits = dwSharedIdBits;
required_bits *= m_dwNSharedObjsArray[i];
if (!CanReadFromBitStream(hStream, required_bits))
@@ -212,7 +225,7 @@
}
hStream->ByteAlign();
- for (uint32_t i = 0; i < nPages; i++) {
+ for (int i = 0; i < nPages; i++) {
FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i];
safeSize *= dwSharedNumeratorBits;
if (!CanReadFromBitStream(hStream, safeSize))
@@ -237,8 +250,10 @@
if (!hStream || hStream->IsEOF())
return false;
- const FX_FILESIZE nStreamOffset = m_pLinearized->GetHintStart();
- const uint32_t nStreamLen = m_pLinearized->GetHintLength();
+ int nStreamOffset = ReadPrimaryHintStreamOffset();
+ int nStreamLen = ReadPrimaryHintStreamLength();
+ if (nStreamOffset < 0 || nStreamLen < 1)
+ return false;
FX_SAFE_UINT32 bit_offset = offset;
bit_offset *= 8;
@@ -288,7 +303,9 @@
return false;
}
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
+ int nFirstPageObjNum = GetFirstPageObjectNumber();
+ if (nFirstPageObjNum < 0)
+ return false;
uint32_t dwPrevObjLen = 0;
uint32_t dwCurObjLen = 0;
@@ -363,9 +380,15 @@
*szPageStartPos = m_szPageOffsetArray[index];
*szPageLength = GetItemLength(index, m_szPageOffsetArray);
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
+ int nFirstPageObjNum = GetFirstPageObjectNumber();
+ if (nFirstPageObjNum < 0)
+ return false;
- const uint32_t dwFirstPageNum = m_pLinearized->GetFirstPageNo();
+ int nFirstPageNum = GetFirstPageNumber();
+ if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
+ return false;
+
+ uint32_t dwFirstPageNum = static_cast<uint32_t>(nFirstPageNum);
if (index == dwFirstPageNum) {
*dwObjNum = nFirstPageObjNum;
return true;
@@ -382,7 +405,11 @@
}
CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(uint32_t index) {
- if (index == m_pLinearized->GetFirstPageNo())
+ int nFirstPageNum = GetFirstPageNumber();
+ if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
+ return CPDF_DataAvail::DataError;
+
+ if (index == static_cast<uint32_t>(nFirstPageNum))
return CPDF_DataAvail::DataAvailable;
uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray);
@@ -399,7 +426,9 @@
for (uint32_t i = 0; i < index; ++i)
offset += m_dwNSharedObjsArray[i];
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
+ int nFirstPageObjNum = GetFirstPageObjectNumber();
+ if (nFirstPageObjNum < 0)
+ return CPDF_DataAvail::DataError;
uint32_t dwIndex = 0;
uint32_t dwObjNum = 0;
@@ -429,7 +458,7 @@
}
bool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
- if (!pHintStream || !m_pLinearized->HasHintTable())
+ if (!pHintStream)
return false;
CPDF_Dictionary* pDict = pHintStream->GetDict();
@@ -462,3 +491,27 @@
return ReadPageHintTable(&bs) &&
ReadSharedObjHintTable(&bs, shared_hint_table_offset);
}
+
+int CPDF_HintTables::GetEndOfFirstPageOffset() const {
+ return static_cast<int>(m_pLinearized->GetFirstPageEndOffset());
+}
+
+int CPDF_HintTables::GetNumberOfPages() const {
+ return static_cast<int>(m_pLinearized->GetPageCount());
+}
+
+int CPDF_HintTables::GetFirstPageObjectNumber() const {
+ return static_cast<int>(m_pLinearized->GetFirstPageObjNum());
+}
+
+int CPDF_HintTables::GetFirstPageNumber() const {
+ return static_cast<int>(m_pLinearized->GetFirstPageNo());
+}
+
+int CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
+ return static_cast<int>(m_pLinearized->GetHintStart());
+}
+
+int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
+ return static_cast<int>(m_pLinearized->GetHintLength());
+}
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.h b/core/fpdfapi/parser/cpdf_hint_tables.h
index 3664e15..d5feb46 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.h
+++ b/core/fpdfapi/parser/cpdf_hint_tables.h
@@ -38,6 +38,14 @@
bool ReadSharedObjHintTable(CFX_BitStream* hStream, uint32_t offset);
private:
+ // Tests can override.
+ virtual int GetEndOfFirstPageOffset() const;
+ virtual int GetNumberOfPages() const;
+ virtual int GetFirstPageObjectNumber() const;
+ virtual int GetFirstPageNumber() const;
+ virtual int ReadPrimaryHintStreamOffset() const;
+ virtual int ReadPrimaryHintStreamLength() const;
+
uint32_t GetItemLength(uint32_t index,
const std::vector<FX_FILESIZE>& szArray) const;