Further split CPDF_Parser::LoadCrossRefV5().
Move the /W and /Index parsing code into their own functions.
Change-Id: I98939e157f3617b583c497e0e64acc3ac48ff743
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86171
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 3a5f4fb..89505dc 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -62,6 +62,43 @@
return result;
}
+std::vector<CrossRefV5IndexEntry> GetCrossRefV5Indices(const CPDF_Array* array,
+ uint32_t size) {
+ std::vector<CrossRefV5IndexEntry> indices;
+ if (array) {
+ for (size_t i = 0; i < array->size() / 2; i++) {
+ const CPDF_Number* pStartNumObj = ToNumber(array->GetObjectAt(i * 2));
+ const CPDF_Number* pCountObj = ToNumber(array->GetObjectAt(i * 2 + 1));
+
+ if (!pStartNumObj || !pCountObj)
+ continue;
+
+ int nStartNum = pStartNumObj->GetInteger();
+ int nCount = pCountObj->GetInteger();
+ if (nStartNum < 0 || nCount <= 0)
+ continue;
+
+ indices.push_back(
+ {static_cast<uint32_t>(nStartNum), static_cast<uint32_t>(nCount)});
+ }
+ }
+
+ if (indices.empty())
+ indices.push_back({0, size});
+ return indices;
+}
+
+std::vector<uint32_t> GetFieldWidths(const CPDF_Array* array) {
+ std::vector<uint32_t> results;
+ if (!array)
+ return results;
+
+ CPDF_ArrayLocker locker(array);
+ for (const auto& obj : locker)
+ results.push_back(obj->GetInteger());
+ return results;
+}
+
class ObjectsHolderStub final : public CPDF_Parser::ParsedObjectsHolder {
public:
ObjectsHolderStub() = default;
@@ -677,7 +714,7 @@
if (!pStream)
return false;
- CPDF_Dictionary* pDict = pStream->GetDict();
+ const CPDF_Dictionary* pDict = pStream->GetDict();
*pos = pDict->GetIntegerFor("Prev");
int32_t size = pDict->GetIntegerFor("Size");
if (size < 0)
@@ -694,41 +731,17 @@
std::move(m_CrossRefTable));
}
- std::vector<CrossRefV5IndexEntry> indices;
- CPDF_Array* pArray = pDict->GetArrayFor("Index");
- if (pArray) {
- for (size_t i = 0; i < pArray->size() / 2; i++) {
- CPDF_Number* pStartNumObj = ToNumber(pArray->GetObjectAt(i * 2));
- CPDF_Number* pCountObj = ToNumber(pArray->GetObjectAt(i * 2 + 1));
+ std::vector<CrossRefV5IndexEntry> indices =
+ GetCrossRefV5Indices(pDict->GetArrayFor("Index"), size);
- if (!pStartNumObj || !pCountObj)
- continue;
-
- int nStartNum = pStartNumObj->GetInteger();
- int nCount = pCountObj->GetInteger();
- if (nStartNum < 0 || nCount <= 0)
- continue;
-
- indices.push_back(
- {static_cast<uint32_t>(nStartNum), static_cast<uint32_t>(nCount)});
- }
- }
-
- if (indices.empty())
- indices.push_back({0, static_cast<uint32_t>(size)});
-
- pArray = pDict->GetArrayFor("W");
- if (!pArray)
+ std::vector<uint32_t> field_widths = GetFieldWidths(pDict->GetArrayFor("W"));
+ if (field_widths.size() < kMinFieldCount)
return false;
- std::vector<uint32_t> field_widths;
- FX_SAFE_UINT32 dwAccWidth = 0;
- for (size_t i = 0; i < pArray->size(); ++i) {
- field_widths.push_back(pArray->GetIntegerAt(i));
- dwAccWidth += field_widths[i];
- }
-
- if (!dwAccWidth.IsValid() || field_widths.size() < kMinFieldCount)
+ FX_SAFE_UINT32 dwAccWidth;
+ for (uint32_t width : field_widths)
+ dwAccWidth += width;
+ if (!dwAccWidth.IsValid())
return false;
uint32_t total_width = dwAccWidth.ValueOrDie();