summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables.cpp82
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables.h11
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp25
3 files changed, 58 insertions, 60 deletions
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp
index fc9a46d68a..f4f87d59e6 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp
@@ -277,60 +277,38 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
return false;
}
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
-
- uint32_t dwPrevObjLen = 0;
- uint32_t dwCurObjLen = 0;
FX_SAFE_UINT32 required_bits = dwSharedObjTotal;
required_bits *= dwDeltaGroupLen;
if (!CanReadFromBitStream(hStream, required_bits))
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;
-
- dwCurObjLen = safeObjLen.ValueOrDie();
- if (i < m_nFirstPageSharedObjs) {
- m_dwSharedObjNumArray.push_back(nFirstPageObjNum + i);
- if (i == 0)
- m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset);
- } else {
+ if (dwSharedObjTotal > 0) {
+ uint32_t dwLastSharedObj = dwSharedObjTotal - 1;
+ if (dwLastSharedObj > m_nFirstPageSharedObjs) {
FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum;
- safeObjNum += i - m_nFirstPageSharedObjs;
+ safeObjNum += dwLastSharedObj - m_nFirstPageSharedObjs;
if (!safeObjNum.IsValid())
return false;
-
- m_dwSharedObjNumArray.push_back(safeObjNum.ValueOrDie());
- if (i == m_nFirstPageSharedObjs) {
- FX_SAFE_FILESIZE safeLoc = szFirstSharedObjLoc;
- if (!safeLoc.IsValid())
- return false;
-
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
- }
- }
-
- if (i != 0 && i != m_nFirstPageSharedObjs) {
- FX_SAFE_FILESIZE safeLoc = dwPrevObjLen;
- safeLoc += m_szSharedObjOffsetArray[i - 1];
- if (!safeLoc.IsValid())
- return false;
-
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
}
}
- if (dwSharedObjTotal > 0) {
- FX_SAFE_FILESIZE safeLoc = dwCurObjLen;
- safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
- if (!safeLoc.IsValid())
+ m_SharedObjGroupInfos.resize(dwSharedObjTotal);
+ FX_SAFE_FILESIZE prev_shared_group_end_offset = m_szFirstPageObjOffset;
+ for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
+ if (i == m_nFirstPageSharedObjs)
+ prev_shared_group_end_offset = szFirstSharedObjLoc;
+
+ FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen);
+ safeObjLen += dwGroupLeastLen;
+ if (!safeObjLen.IsValid())
return false;
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
+ m_SharedObjGroupInfos[i].m_dwLength = safeObjLen.ValueOrDie();
+ m_SharedObjGroupInfos[i].m_szOffset =
+ prev_shared_group_end_offset.ValueOrDie();
+ prev_shared_group_end_offset += m_SharedObjGroupInfos[i].m_dwLength;
+ if (!prev_shared_group_end_offset.IsValid())
+ return false;
}
hStream->ByteAlign();
@@ -362,7 +340,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(uint32_t index) {
if (index >= m_pLinearized->GetPageCount())
return CPDF_DataAvail::DataError;
- uint32_t dwLength = m_PageInfos[index].page_length();
+ const uint32_t dwLength = m_PageInfos[index].page_length();
if (!dwLength)
return CPDF_DataAvail::DataError;
@@ -372,27 +350,17 @@ CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(uint32_t index) {
}
// Download data of shared objects in the page.
- const uint32_t nFirstPageObjNum = m_pLinearized->GetFirstPageObjNum();
-
- uint32_t dwObjNum = 0;
for (const uint32_t dwIndex : m_PageInfos[index].Identifiers()) {
- if (dwIndex >= m_dwSharedObjNumArray.size())
+ if (dwIndex >= m_SharedObjGroupInfos.size())
continue;
+ const SharedObjGroupInfo& shared_group_info =
+ m_SharedObjGroupInfos[dwIndex];
- dwObjNum = m_dwSharedObjNumArray[dwIndex];
- if (dwObjNum >= static_cast<uint32_t>(nFirstPageObjNum) &&
- dwObjNum <
- static_cast<uint32_t>(nFirstPageObjNum) + m_nFirstPageSharedObjs) {
- continue;
- }
-
- dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
- // If two objects have the same offset, it should be treated as an error.
- if (!dwLength)
+ if (!shared_group_info.m_szOffset || !shared_group_info.m_dwLength)
return CPDF_DataAvail::DataError;
if (!m_pValidator->CheckDataRangeAndRequestIfUnavailable(
- m_szSharedObjOffsetArray[dwIndex], dwLength)) {
+ shared_group_info.m_szOffset, shared_group_info.m_dwLength)) {
return CPDF_DataAvail::DataNotAvailable;
}
}
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.h b/core/fpdfapi/parser/cpdf_hint_tables.h
index 0db190b189..861f231547 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.h
+++ b/core/fpdfapi/parser/cpdf_hint_tables.h
@@ -20,6 +20,11 @@ class CPDF_ReadValidator;
class CPDF_HintTables {
public:
+ struct SharedObjGroupInfo {
+ FX_FILESIZE m_szOffset = 0;
+ uint32_t m_dwLength = 0;
+ };
+
class PageInfo {
public:
PageInfo();
@@ -74,6 +79,9 @@ class CPDF_HintTables {
bool LoadHintStream(CPDF_Stream* pHintStream);
const std::vector<PageInfo>& PageInfos() const { return m_PageInfos; }
+ const std::vector<SharedObjGroupInfo>& SharedGroupInfos() const {
+ return m_SharedObjGroupInfos;
+ }
protected:
bool ReadPageHintTable(CFX_BitStream* hStream);
@@ -95,8 +103,7 @@ class CPDF_HintTables {
FX_FILESIZE m_szFirstPageObjOffset;
std::vector<PageInfo> m_PageInfos;
- std::vector<uint32_t> m_dwSharedObjNumArray;
- std::vector<FX_FILESIZE> m_szSharedObjOffsetArray;
+ std::vector<SharedObjGroupInfo> m_SharedObjGroupInfos;
};
#endif // CORE_FPDFAPI_PARSER_CPDF_HINT_TABLES_H_
diff --git a/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp b/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
index 3d98196093..af0e9ff745 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
@@ -10,6 +10,8 @@
#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/parser/cpdf_data_avail.h"
+#include "core/fpdfapi/parser/cpdf_object.h"
+#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fxcrt/fx_stream.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -68,7 +70,7 @@ TEST_F(CPDF_HintTablesTest, Load) {
hint_tables->GetPagePos(2, &page_start, &page_length, &page_obj_num));
}
-TEST_F(CPDF_HintTablesTest, PageInfos) {
+TEST_F(CPDF_HintTablesTest, PageAndGroupInfos) {
auto data_avail = MakeDataAvailFromFile("feature_linearized_loading.pdf");
ASSERT_EQ(CPDF_DataAvail::DocAvailStatus::DataAvailable,
data_avail->IsDocAvail(nullptr));
@@ -95,4 +97,25 @@ TEST_F(CPDF_HintTablesTest, PageInfos) {
EXPECT_EQ(2u, hint_tables->PageInfos()[1].Identifiers()[0]);
EXPECT_EQ(5u, hint_tables->PageInfos()[1].Identifiers()[1]);
EXPECT_EQ(3u, hint_tables->PageInfos()[1].Identifiers()[2]);
+
+ // SharedGroupInfo
+ ASSERT_EQ(6u, hint_tables->SharedGroupInfos().size());
+
+ EXPECT_EQ(777, hint_tables->SharedGroupInfos()[0].m_szOffset);
+ EXPECT_EQ(254u, hint_tables->SharedGroupInfos()[0].m_dwLength);
+
+ EXPECT_EQ(1031, hint_tables->SharedGroupInfos()[1].m_szOffset);
+ EXPECT_EQ(389u, hint_tables->SharedGroupInfos()[1].m_dwLength);
+
+ EXPECT_EQ(1420, hint_tables->SharedGroupInfos()[2].m_szOffset);
+ EXPECT_EQ(726u, hint_tables->SharedGroupInfos()[2].m_dwLength);
+
+ EXPECT_EQ(2146, hint_tables->SharedGroupInfos()[3].m_szOffset);
+ EXPECT_EQ(290u, hint_tables->SharedGroupInfos()[3].m_dwLength);
+
+ EXPECT_EQ(2436, hint_tables->SharedGroupInfos()[4].m_szOffset);
+ EXPECT_EQ(2669u, hint_tables->SharedGroupInfos()[4].m_dwLength);
+
+ EXPECT_EQ(10939, hint_tables->SharedGroupInfos()[5].m_szOffset);
+ EXPECT_EQ(544u, hint_tables->SharedGroupInfos()[5].m_dwLength);
}