Reduce lookups in CPDF_Parser::ParseIndirectObject()
ParseIndirectObject() calls several helper functions that in turn calls
CPDF_CrossRefTable::GetObjectInfo(). Instead of doing multiple lookups
like this, just call GetObjectInfo() once and directly interpret the
result. After this, CPDF_Parser::GetObjectType() only has a single
caller left, so fold it into that caller.
Change-Id: If6ffa1bce8d58f90bab57c1ac8ea882ddf748a0d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121232
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 28dcb14..c7f0044 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -183,14 +183,10 @@
return (info && info->type == ObjectType::kNormal) ? info->pos : 0;
}
-ObjectType CPDF_Parser::GetObjectType(uint32_t objnum) const {
+bool CPDF_Parser::IsObjectFree(uint32_t objnum) const {
DCHECK(IsValidObjectNumber(objnum));
const auto* info = m_CrossRefTable->GetObjectInfo(objnum);
- return info ? info->type : ObjectType::kFree;
-}
-
-bool CPDF_Parser::IsObjectFree(uint32_t objnum) const {
- return GetObjectType(objnum) == ObjectType::kFree;
+ return !info || info->type == ObjectType::kFree;
}
bool CPDF_Parser::InitSyntaxParser(RetainPtr<CPDF_ReadValidator> validator) {
@@ -1002,31 +998,40 @@
}
RetainPtr<CPDF_Object> CPDF_Parser::ParseIndirectObject(uint32_t objnum) {
- if (!IsValidObjectNumber(objnum))
+ if (!IsValidObjectNumber(objnum)) {
return nullptr;
+ }
// Prevent circular parsing the same object.
- if (pdfium::Contains(m_ParsingObjNums, objnum))
+ if (pdfium::Contains(m_ParsingObjNums, objnum)) {
return nullptr;
+ }
ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
- if (GetObjectType(objnum) == ObjectType::kNormal) {
- FX_FILESIZE pos = GetObjectPositionOrZero(objnum);
- if (pos <= 0)
+ const auto* info = m_CrossRefTable->GetObjectInfo(objnum);
+ if (!info) {
+ return nullptr;
+ }
+
+ switch (info->type) {
+ case ObjectType::kFree: {
return nullptr;
- return ParseIndirectObjectAt(pos, objnum);
+ }
+ case ObjectType::kNormal: {
+ if (info->pos <= 0) {
+ return nullptr;
+ }
+ return ParseIndirectObjectAt(info->pos, objnum);
+ }
+ case ObjectType::kCompressed: {
+ const auto* obj_stream = GetObjectStream(info->archive.obj_num);
+ if (!obj_stream) {
+ return nullptr;
+ }
+ return obj_stream->ParseObject(m_pObjectsHolder, objnum,
+ info->archive.obj_index);
+ }
}
- if (GetObjectType(objnum) != ObjectType::kCompressed) {
- return nullptr;
- }
-
- const auto& info = *m_CrossRefTable->GetObjectInfo(objnum);
- const CPDF_ObjectStream* pObjStream = GetObjectStream(info.archive.obj_num);
- if (!pObjStream)
- return nullptr;
-
- return pObjStream->ParseObject(m_pObjectsHolder, objnum,
- info.archive.obj_index);
}
const CPDF_ObjectStream* CPDF_Parser::GetObjectStream(uint32_t object_number) {
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index cabc332..d659c9b 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -174,8 +174,6 @@
bool InitSyntaxParser(RetainPtr<CPDF_ReadValidator> validator);
bool ParseFileVersion();
- CPDF_CrossRefTable::ObjectType GetObjectType(uint32_t objnum) const;
-
std::unique_ptr<CPDF_SyntaxParser> m_pSyntax;
std::unique_ptr<ParsedObjectsHolder> m_pOwnedObjectsHolder;
UnownedPtr<ParsedObjectsHolder> m_pObjectsHolder;