summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/edit/cpdf_creator.cpp8
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp7
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp79
-rw-r--r--core/fpdfapi/parser/cpdf_parser.h13
-rw-r--r--core/fpdfapi/parser/cpdf_parser_unittest.cpp47
5 files changed, 114 insertions, 40 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 858d56cbaf..ceffa5077f 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -323,9 +323,9 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) {
m_ObjectOffsets[objnum] = m_Archive->CurrentOffset();
bool bExistInMap = !!m_pDocument->GetIndirectObject(objnum);
- const uint8_t object_type = m_pParser->GetObjectType(objnum);
+ const CPDF_Parser::ObjectType object_type = m_pParser->GetObjectType(objnum);
if (m_pParser->IsVersionUpdated() || m_bSecurityChanged || bExistInMap ||
- (object_type == 2 && m_pEncryptDict)) {
+ (object_type == CPDF_Parser::ObjectType::kCompressed && m_pEncryptDict)) {
CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum);
if (!pObj) {
m_ObjectOffsets.erase(objnum);
@@ -341,7 +341,7 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) {
m_pParser->GetIndirectBinary(objnum, pBuffer, size);
if (!pBuffer)
return true;
- if (object_type == 2) {
+ if (object_type == CPDF_Parser::ObjectType::kCompressed) {
if (!m_Archive->WriteDWord(objnum) ||
!m_Archive->WriteString(" 0 obj ") ||
!m_Archive->WriteBlock(pBuffer, size) ||
@@ -412,7 +412,7 @@ void CPDF_Creator::InitNewObjNumOffsets() {
continue;
}
if (m_pParser && m_pParser->IsValidObjectNumber(objnum) &&
- m_pParser->GetObjectType(objnum)) {
+ m_pParser->GetObjectType(objnum) != CPDF_Parser::ObjectType::kFree) {
continue;
}
m_NewObjNumArray.insert(std::lower_bound(m_NewObjNumArray.begin(),
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index b4da893429..6f12260eae 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -94,11 +94,12 @@ uint32_t CPDF_DataAvail::GetObjectSize(uint32_t objnum, FX_FILESIZE& offset) {
if (!pParser || !pParser->IsValidObjectNumber(objnum))
return 0;
- if (pParser->GetObjectType(objnum) == 2)
+ if (pParser->GetObjectType(objnum) == CPDF_Parser::ObjectType::kCompressed)
objnum = pParser->GetObjectPositionOrZero(objnum);
- if (pParser->GetObjectType(objnum) != 1 &&
- pParser->GetObjectType(objnum) != 255) {
+ if (pParser->GetObjectType(objnum) !=
+ CPDF_Parser::ObjectType::kNotCompressed &&
+ pParser->GetObjectType(objnum) != CPDF_Parser::ObjectType::kNull) {
return 0;
}
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 841bf2778a..0f4da6e28f 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -49,6 +49,20 @@ int32_t GetStreamFirst(const CFX_RetainPtr<CPDF_StreamAcc>& pObjStream) {
return pObjStream->GetDict()->GetIntegerFor("First");
}
+CPDF_Parser::ObjectType GetObjectTypeFromCrossRefStreamType(
+ int cross_ref_stream_type) {
+ switch (cross_ref_stream_type) {
+ case 0:
+ return CPDF_Parser::ObjectType::kFree;
+ case 1:
+ return CPDF_Parser::ObjectType::kNotCompressed;
+ case 2:
+ return CPDF_Parser::ObjectType::kCompressed;
+ default:
+ return CPDF_Parser::ObjectType::kNull;
+ }
+}
+
} // namespace
CPDF_Parser::CPDF_Parser()
@@ -78,10 +92,10 @@ FX_FILESIZE CPDF_Parser::GetObjectPositionOrZero(uint32_t objnum) const {
return it != m_ObjectInfo.end() ? it->second.pos : 0;
}
-uint8_t CPDF_Parser::GetObjectType(uint32_t objnum) const {
+CPDF_Parser::ObjectType CPDF_Parser::GetObjectType(uint32_t objnum) const {
ASSERT(IsValidObjectNumber(objnum));
auto it = m_ObjectInfo.find(objnum);
- return it != m_ObjectInfo.end() ? it->second.type : 0;
+ return it != m_ObjectInfo.end() ? it->second.type : ObjectType::kFree;
}
uint16_t CPDF_Parser::GetObjectGenNum(uint32_t objnum) const {
@@ -91,8 +105,16 @@ uint16_t CPDF_Parser::GetObjectGenNum(uint32_t objnum) const {
}
bool CPDF_Parser::IsObjectFreeOrNull(uint32_t objnum) const {
- uint8_t type = GetObjectType(objnum);
- return type == 0 || type == 255;
+ switch (GetObjectType(objnum)) {
+ case ObjectType::kFree:
+ case ObjectType::kNull:
+ return true;
+ case ObjectType::kNotCompressed:
+ case ObjectType::kCompressed:
+ return false;
+ }
+ ASSERT(false); // NOTREACHED();
+ return false;
}
void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) {
@@ -265,10 +287,10 @@ FX_FILESIZE CPDF_Parser::GetObjectOffset(uint32_t objnum) const {
if (!IsValidObjectNumber(objnum))
return 0;
- if (GetObjectType(objnum) == 1)
+ if (GetObjectType(objnum) == ObjectType::kNotCompressed)
return GetObjectPositionOrZero(objnum);
- if (GetObjectType(objnum) == 2) {
+ if (GetObjectType(objnum) == ObjectType::kCompressed) {
FX_FILESIZE pos = GetObjectPositionOrZero(objnum);
return GetObjectPositionOrZero(pos);
}
@@ -444,7 +466,7 @@ bool CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
char* pEntry = &buf[i * recordsize];
if (pEntry[17] == 'f') {
m_ObjectInfo[objnum].pos = 0;
- m_ObjectInfo[objnum].type = 0;
+ m_ObjectInfo[objnum].type = ObjectType::kFree;
} else {
int32_t offset = FXSYS_atoi(pEntry);
if (offset == 0) {
@@ -463,7 +485,7 @@ bool CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen)
m_SortedOffset.insert(m_ObjectInfo[objnum].pos);
- m_ObjectInfo[objnum].type = 1;
+ m_ObjectInfo[objnum].type = ObjectType::kNotCompressed;
}
}
}
@@ -519,7 +541,7 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
char* pEntry = &buf[i * recordsize];
if (pEntry[17] == 'f') {
m_ObjectInfo[objnum].pos = 0;
- m_ObjectInfo[objnum].type = 0;
+ m_ObjectInfo[objnum].type = ObjectType::kFree;
} else {
FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
if (offset == 0) {
@@ -538,7 +560,7 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen)
m_SortedOffset.insert(m_ObjectInfo[objnum].pos);
- m_ObjectInfo[objnum].type = 1;
+ m_ObjectInfo[objnum].type = ObjectType::kNotCompressed;
}
}
}
@@ -766,7 +788,7 @@ bool CPDF_Parser::RebuildCrossRef() {
}
} else {
m_ObjectInfo[objnum].pos = obj_pos;
- m_ObjectInfo[objnum].type = 1;
+ m_ObjectInfo[objnum].type = ObjectType::kNotCompressed;
m_ObjectInfo[objnum].gennum = gennum;
}
}
@@ -959,7 +981,7 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) {
m_TrailerPos = m_Trailers.size() - 1;
ShrinkObjectMap(size);
for (auto& it : m_ObjectInfo)
- it.second.type = 0;
+ it.second.type = ObjectType::kFree;
} else {
m_Trailers.push_back(std::move(pNewTrailer));
}
@@ -1027,12 +1049,15 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) {
continue;
for (uint32_t j = 0; j < count; j++) {
- int32_t type = 1;
+ ObjectType type = ObjectType::kNotCompressed;
const uint8_t* entrystart = segstart + j * totalWidth;
- if (WidthArray[0])
- type = GetVarInt(entrystart, WidthArray[0]);
+ if (WidthArray[0]) {
+ const int cross_ref_stream_obj_type =
+ GetVarInt(entrystart, WidthArray[0]);
+ type = GetObjectTypeFromCrossRefStreamType(cross_ref_stream_obj_type);
+ }
- if (GetObjectType(startnum + j) == 255) {
+ if (GetObjectType(startnum + j) == ObjectType::kNull) {
FX_FILESIZE offset =
GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
m_ObjectInfo[startnum + j].pos = offset;
@@ -1040,22 +1065,22 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) {
continue;
}
- if (GetObjectType(startnum + j))
+ if (GetObjectType(startnum + j) != ObjectType::kFree)
continue;
m_ObjectInfo[startnum + j].type = type;
- if (type == 0) {
+ if (type == ObjectType::kFree) {
m_ObjectInfo[startnum + j].pos = 0;
} else {
FX_FILESIZE offset =
GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
m_ObjectInfo[startnum + j].pos = offset;
- if (type == 1) {
+ if (type == ObjectType::kNotCompressed) {
m_SortedOffset.insert(offset);
} else {
if (offset < 0 || !IsValidObjectNumber(offset))
return false;
- m_ObjectInfo[offset].type = 255;
+ m_ObjectInfo[offset].type = ObjectType::kNull;
}
}
}
@@ -1117,13 +1142,14 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
return nullptr;
pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
- if (GetObjectType(objnum) == 1 || GetObjectType(objnum) == 255) {
+ if (GetObjectType(objnum) == ObjectType::kNotCompressed ||
+ GetObjectType(objnum) == ObjectType::kNull) {
FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
if (pos <= 0)
return nullptr;
return ParseIndirectObjectAt(pObjList, pos, objnum);
}
- if (GetObjectType(objnum) != 2)
+ if (GetObjectType(objnum) != ObjectType::kCompressed)
return nullptr;
CFX_RetainPtr<CPDF_StreamAcc> pObjStream =
@@ -1178,10 +1204,11 @@ FX_FILESIZE CPDF_Parser::GetObjectSize(uint32_t objnum) const {
if (!IsValidObjectNumber(objnum))
return 0;
- if (GetObjectType(objnum) == 2)
+ if (GetObjectType(objnum) == ObjectType::kCompressed)
objnum = GetObjectPositionOrZero(objnum);
- if (GetObjectType(objnum) != 1 && GetObjectType(objnum) != 255)
+ if (GetObjectType(objnum) != ObjectType::kNotCompressed &&
+ GetObjectType(objnum) != ObjectType::kNull)
return 0;
FX_FILESIZE offset = GetObjectPositionOrZero(objnum);
@@ -1203,7 +1230,7 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
if (!IsValidObjectNumber(objnum))
return;
- if (GetObjectType(objnum) == 2) {
+ if (GetObjectType(objnum) == ObjectType::kCompressed) {
CFX_RetainPtr<CPDF_StreamAcc> pObjStream =
GetObjectStream(m_ObjectInfo[objnum].pos);
if (!pObjStream)
@@ -1238,7 +1265,7 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
return;
}
- if (GetObjectType(objnum) != 1)
+ if (GetObjectType(objnum) != ObjectType::kNotCompressed)
return;
FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index efe10555f7..3acdbbfa6f 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -38,6 +38,13 @@ class CPDF_Parser {
HANDLER_ERROR
};
+ enum class ObjectType : uint8_t {
+ kFree = 0x00,
+ kNotCompressed = 0x01,
+ kCompressed = 0x02,
+ kNull = 0xFF,
+ };
+
// A limit on the maximum object number in the xref table. Theoretical limits
// are higher, but this may be large enough in practice.
static const uint32_t kMaxObjectNumber = 1048576;
@@ -74,7 +81,7 @@ class CPDF_Parser {
uint32_t GetLastObjNum() const;
bool IsValidObjectNumber(uint32_t objnum) const;
FX_FILESIZE GetObjectPositionOrZero(uint32_t objnum) const;
- uint8_t GetObjectType(uint32_t objnum) const;
+ ObjectType GetObjectType(uint32_t objnum) const;
uint16_t GetObjectGenNum(uint32_t objnum) const;
bool IsVersionUpdated() const { return m_bVersionUpdated; }
bool IsObjectFreeOrNull(uint32_t objnum) const;
@@ -103,10 +110,10 @@ class CPDF_Parser {
protected:
struct ObjectInfo {
- ObjectInfo() : pos(0), type(0), gennum(0) {}
+ ObjectInfo() : pos(0), type(ObjectType::kFree), gennum(0) {}
FX_FILESIZE pos;
- uint8_t type;
+ ObjectType type;
uint16_t gennum;
};
diff --git a/core/fpdfapi/parser/cpdf_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_parser_unittest.cpp
index f988f8248b..25c22c701b 100644
--- a/core/fpdfapi/parser/cpdf_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_parser_unittest.cpp
@@ -118,7 +118,13 @@ TEST(cpdf_parser, LoadCrossRefV4) {
ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, false));
const FX_FILESIZE offsets[] = {0, 17, 81, 0, 331, 409};
- const uint8_t types[] = {0, 1, 1, 0, 1, 1};
+ const CPDF_Parser::ObjectType types[] = {
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kNotCompressed};
for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
@@ -144,7 +150,20 @@ TEST(cpdf_parser, LoadCrossRefV4) {
ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, false));
const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0,
0, 25518, 25635, 0, 0, 25777};
- const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1};
+ const CPDF_Parser::ObjectType types[] = {
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed};
for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
@@ -170,7 +189,20 @@ TEST(cpdf_parser, LoadCrossRefV4) {
ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, false));
const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0,
0, 0, 25635, 0, 0, 25777};
- const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1};
+ const CPDF_Parser::ObjectType types[] = {
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed};
for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
@@ -194,7 +226,14 @@ TEST(cpdf_parser, LoadCrossRefV4) {
ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, false));
const FX_FILESIZE offsets[] = {0, 23, 0, 0, 0, 45, 179};
- const uint8_t types[] = {0, 1, 0, 0, 0, 1, 1};
+ const CPDF_Parser::ObjectType types[] = {
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kFree,
+ CPDF_Parser::ObjectType::kNotCompressed,
+ CPDF_Parser::ObjectType::kNotCompressed};
for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);