summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables.cpp53
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables.h8
-rw-r--r--core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp12
3 files changed, 65 insertions, 8 deletions
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp
index 04e673bc97..8d8aa3263a 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp
@@ -233,6 +233,8 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
// Item 1: The object number of the first object in the shared objects
// section.
uint32_t dwFirstSharedObjNum = hStream->GetBits(32);
+ if (!dwFirstSharedObjNum)
+ return false;
// Item 2: The location of the first object in the shared objects section.
const FX_FILESIZE szFirstSharedObjLoc =
@@ -248,8 +250,8 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
uint32_t dwSharedObjTotal = hStream->GetBits(32);
// Item 5: The number of bits needed to represent the greatest number of
- // objects in a shared object group. Skipped.
- hStream->SkipBits(16);
+ // objects in a shared object group.
+ uint32_t dwSharedObjNumBits = hStream->GetBits(16);
// Item 6: The least length of a shared object group in bytes.
uint32_t dwGroupLeastLen = hStream->GetBits(32);
@@ -285,6 +287,9 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
}
m_SharedObjGroupInfos.resize(dwSharedObjTotal);
+ // Table F.6 – Shared object hint table, shared object group entries:
+ // Item 1: A number that, when added to the least shared object
+ // group length.
FX_SAFE_FILESIZE prev_shared_group_end_offset = m_szFirstPageObjOffset;
for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
if (i == m_nFirstPageSharedObjs)
@@ -304,10 +309,48 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
}
hStream->ByteAlign();
- if (hStream->BitsRemaining() < dwSharedObjTotal)
- return false;
+ {
+ // Item 2: A flag indicating whether the shared object signature (item 3) is
+ // present.
+ uint32_t signature_count = 0;
+ for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
+ signature_count += hStream->GetBits(1);
+ }
+ hStream->ByteAlign();
+ // Item 3: (Only if item 2 is 1) The shared object signature, a 16-byte MD5
+ // hash that uniquely identifies the resource that the group of objects
+ // represents.
+ if (signature_count) {
+ required_bits = signature_count;
+ required_bits *= 128;
+ if (!CanReadFromBitStream(hStream, required_bits))
+ return false;
+
+ hStream->SkipBits(required_bits.ValueOrDie());
+ hStream->ByteAlign();
+ }
+ }
+ // Item 4: A number equal to 1 less than the number of objects in the group.
+ FX_SAFE_UINT32 cur_obj_num = m_pLinearized->GetFirstPageObjNum();
+ for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
+ if (i == m_nFirstPageSharedObjs)
+ cur_obj_num = dwFirstSharedObjNum;
+
+ FX_SAFE_UINT32 obj_count =
+ dwSharedObjNumBits ? hStream->GetBits(dwSharedObjNumBits) : 0;
+ obj_count += 1;
+ if (!obj_count.IsValid())
+ return false;
+
+ uint32_t obj_num = cur_obj_num.ValueOrDie();
+ cur_obj_num += obj_count.ValueOrDie();
+ if (!cur_obj_num.IsValid())
+ return false;
+
+ m_SharedObjGroupInfos[i].m_dwStartObjNum = obj_num;
+ m_SharedObjGroupInfos[i].m_dwObjectsCount = obj_count.ValueOrDie();
+ }
- hStream->SkipBits(dwSharedObjTotal);
hStream->ByteAlign();
return true;
}
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.h b/core/fpdfapi/parser/cpdf_hint_tables.h
index 5b978f99b2..20ba9be051 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.h
+++ b/core/fpdfapi/parser/cpdf_hint_tables.h
@@ -23,6 +23,8 @@ class CPDF_HintTables {
struct SharedObjGroupInfo {
FX_FILESIZE m_szOffset = 0;
uint32_t m_dwLength = 0;
+ uint32_t m_dwObjectsCount = 0;
+ uint32_t m_dwStartObjNum = 0;
};
class PageInfo {
@@ -31,9 +33,9 @@ class CPDF_HintTables {
~PageInfo();
void set_objects_count(uint32_t objects_count) {
- m_nObjectsCount = objects_count;
+ m_dwObjectsCount = objects_count;
}
- uint32_t objects_count() const { return m_nObjectsCount; }
+ uint32_t objects_count() const { return m_dwObjectsCount; }
void set_page_offset(FX_FILESIZE offset) { m_szOffset = offset; }
FX_FILESIZE page_offset() const { return m_szOffset; }
@@ -55,7 +57,7 @@ class CPDF_HintTables {
}
private:
- uint32_t m_nObjectsCount = 0;
+ uint32_t m_dwObjectsCount = 0;
FX_FILESIZE m_szOffset = 0;
uint32_t m_dwLength = 0;
uint32_t m_dwStartObjNum = 0;
diff --git a/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp b/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
index dba39f5594..97ba434768 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp
@@ -130,21 +130,33 @@ TEST_F(CPDF_HintTablesTest, PageAndGroupInfos) {
EXPECT_EQ(777, hint_tables->SharedGroupInfos()[0].m_szOffset);
EXPECT_EQ(254u, hint_tables->SharedGroupInfos()[0].m_dwLength);
+ EXPECT_EQ(39u, hint_tables->SharedGroupInfos()[0].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[0].m_dwObjectsCount);
EXPECT_EQ(1031, hint_tables->SharedGroupInfos()[1].m_szOffset);
EXPECT_EQ(389u, hint_tables->SharedGroupInfos()[1].m_dwLength);
+ EXPECT_EQ(40u, hint_tables->SharedGroupInfos()[1].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[1].m_dwObjectsCount);
EXPECT_EQ(1420, hint_tables->SharedGroupInfos()[2].m_szOffset);
EXPECT_EQ(726u, hint_tables->SharedGroupInfos()[2].m_dwLength);
+ EXPECT_EQ(41u, hint_tables->SharedGroupInfos()[2].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[2].m_dwObjectsCount);
EXPECT_EQ(2146, hint_tables->SharedGroupInfos()[3].m_szOffset);
EXPECT_EQ(290u, hint_tables->SharedGroupInfos()[3].m_dwLength);
+ EXPECT_EQ(42u, hint_tables->SharedGroupInfos()[3].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[3].m_dwObjectsCount);
EXPECT_EQ(2436, hint_tables->SharedGroupInfos()[4].m_szOffset);
EXPECT_EQ(2669u, hint_tables->SharedGroupInfos()[4].m_dwLength);
+ EXPECT_EQ(43u, hint_tables->SharedGroupInfos()[4].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[4].m_dwObjectsCount);
EXPECT_EQ(10939, hint_tables->SharedGroupInfos()[5].m_szOffset);
EXPECT_EQ(544u, hint_tables->SharedGroupInfos()[5].m_dwLength);
+ EXPECT_EQ(4u, hint_tables->SharedGroupInfos()[5].m_dwStartObjNum);
+ EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[5].m_dwObjectsCount);
}
TEST_F(CPDF_HintTablesTest, FirstPageOffset) {