Refactor SearchNameNodeByNameInternal()

Refactor SearchNameNodeByNameInternal() by performing the following:
1. Update the function comment to make it clearer and more modern.
2. Combine `ppFind` and `pFindIndex` into a single struct, so that
   callers are forced to pass in both or neither. Update callers to use
   this struct.

Bug: 372523840
Change-Id: I78d2257242f7afbfc22c75fee9fdb8e97caae7b7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/128230
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index ecc64cf..adfb890 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -24,6 +24,12 @@
 
 constexpr int kNameTreeMaxRecursion = 32;
 
+// The node where a new name should be inserted at `index`.
+struct NodeToInsert {
+  RetainPtr<CPDF_Array> names;
+  int index = -1;
+};
+
 std::pair<WideString, WideString> GetNodeLimitsAndSanitize(
     CPDF_Array* pLimits) {
   DCHECK(pLimits);
@@ -190,19 +196,17 @@
   return false;
 }
 
-// Search for |csName| in the tree with root |pNode|. If successful, return the
-// value that |csName| points to; |nIndex| will be the index of |csName|,
-// |ppFind| will be the leaf array that |csName| is found in, and |pFindIndex|
-// will be the index of |csName| in |ppFind|. If |csName| is not found, |ppFind|
-// will be the leaf array that |csName| should be added to, and |pFindIndex|
-// will be the index that it should be added at.
+// Search for `csName` in the tree with root `pNode`. If successful, return the
+// value that `csName` points to; `nIndex` will be the index of `csName`. If
+// `node_to_insert` is non-nullptr, then on a successful search, it will contain
+// the leaf array where `csName` is found in at the provided index, or on
+// failure, the array that `csName` should be inserted in at the provided index.
 RetainPtr<const CPDF_Object> SearchNameNodeByNameInternal(
     const RetainPtr<CPDF_Dictionary>& pNode,
     const WideString& csName,
     int nLevel,
     size_t* nIndex,
-    RetainPtr<CPDF_Array>* ppFind,
-    int* pFindIndex,
+    NodeToInsert* node_to_insert,
     std::set<uint32_t>* seen_obj_nums) {
   if (nLevel > kNameTreeMaxRecursion)
     return nullptr;
@@ -223,10 +227,10 @@
     // Skip this node if the name to look for is greater than its higher limit,
     // and the node itself is a leaf node.
     if (csName.Compare(csRight) > 0 && pNames) {
-      if (ppFind)
-        *ppFind = pNames;
-      if (pFindIndex)
-        *pFindIndex = fxcrt::CollectionSize<int32_t>(*pNames) / 2 - 1;
+      if (node_to_insert) {
+        node_to_insert->names = pNames;
+        node_to_insert->index = fxcrt::CollectionSize<int32_t>(*pNames) / 2 - 1;
+      }
       return nullptr;
     }
   }
@@ -239,10 +243,10 @@
       int32_t iCompare = csValue.Compare(csName);
       if (iCompare > 0)
         break;
-      if (ppFind)
-        *ppFind = pNames;
-      if (pFindIndex)
-        *pFindIndex = pdfium::checked_cast<int32_t>(i);
+      if (node_to_insert) {
+        node_to_insert->names = pNames;
+        node_to_insert->index = pdfium::checked_cast<int32_t>(i);
+      }
       if (iCompare < 0)
         continue;
 
@@ -264,7 +268,7 @@
       continue;
 
     RetainPtr<const CPDF_Object> pFound = SearchNameNodeByNameInternal(
-        pKid, csName, nLevel + 1, nIndex, ppFind, pFindIndex, seen_obj_nums);
+        pKid, csName, nLevel + 1, nIndex, node_to_insert, seen_obj_nums);
     if (pFound)
       return pFound;
   }
@@ -276,12 +280,11 @@
 RetainPtr<const CPDF_Object> SearchNameNodeByName(
     const RetainPtr<CPDF_Dictionary>& pNode,
     const WideString& csName,
-    RetainPtr<CPDF_Array>* ppFind,
-    int* pFindIndex) {
+    NodeToInsert* node_to_insert) {
   size_t nIndex = 0;
   std::set<uint32_t> seen_obj_nums;
-  return SearchNameNodeByNameInternal(pNode, csName, 0, &nIndex, ppFind,
-                                      pFindIndex, &seen_obj_nums);
+  return SearchNameNodeByNameInternal(pNode, csName, 0, &nIndex, node_to_insert,
+                                      &seen_obj_nums);
 }
 
 struct IndexSearchResult {
@@ -484,25 +487,26 @@
 
 bool CPDF_NameTree::AddValueAndName(RetainPtr<CPDF_Object> pObj,
                                     const WideString& name) {
-  RetainPtr<CPDF_Array> pFind;
-  int nFindIndex = -1;
+  NodeToInsert node_to_insert;
   // Handle the corner case where the root node is empty. i.e. No kids and no
   // names. In which case, just insert into it and skip all the searches.
   RetainPtr<CPDF_Array> pNames = m_pRoot->GetMutableArrayFor("Names");
-  if (pNames && pNames->IsEmpty() && !m_pRoot->GetArrayFor("Kids"))
-    pFind = pNames;
-
-  if (!pFind) {
-    // Fail if the tree already contains this name or if the tree is too deep.
-    if (SearchNameNodeByName(m_pRoot, name, &pFind, &nFindIndex))
-      return false;
+  if (pNames && pNames->IsEmpty() && !m_pRoot->GetArrayFor("Kids")) {
+    node_to_insert.names = pNames;
   }
 
-  // If the returned |pFind| is a nullptr, then |name| is smaller than all
-  // existing entries in the tree, and we did not find a leaf array to place
-  // |name| into. We instead will find the leftmost leaf array in which to place
-  // |name| and |pObj|.
-  if (!pFind) {
+  if (!node_to_insert.names) {
+    // Fail if the tree already contains this name or if the tree is too deep.
+    if (SearchNameNodeByName(m_pRoot, name, &node_to_insert)) {
+      return false;
+    }
+  }
+
+  // If the returned `node_to_insert.names` is a nullptr, then `name` is smaller
+  // than all existing entries in the tree, and we did not find a leaf array to
+  // place `name` into. We instead will find the leftmost leaf array in which to
+  // place `name` and `pObj`.
+  if (!node_to_insert.names) {
     std::optional<IndexSearchResult> result =
         SearchNameNodeByIndex(m_pRoot.Get(), 0);
     if (!result.has_value()) {
@@ -510,21 +514,22 @@
       return false;
     }
 
-    pFind = result.value().container;
-    DCHECK(pFind);
+    node_to_insert.names = result.value().container;
+    DCHECK(node_to_insert.names);
   }
 
   // Insert the name and the object into the leaf array found. Note that the
   // insertion position is right after the key-value pair returned by |index|.
-  size_t nNameIndex = (nFindIndex + 1) * 2;
+  size_t nNameIndex = (node_to_insert.index + 1) * 2;
   size_t nValueIndex = nNameIndex + 1;
-  pFind->InsertNewAt<CPDF_String>(nNameIndex, name.AsStringView());
-  pFind->InsertAt(nValueIndex, std::move(pObj));
+  node_to_insert.names->InsertNewAt<CPDF_String>(nNameIndex,
+                                                 name.AsStringView());
+  node_to_insert.names->InsertAt(nValueIndex, std::move(pObj));
 
   // Expand the limits that the newly added name is under, if the name falls
   // outside of the limits of its leaf array or any arrays above it.
   std::vector<CPDF_Array*> all_limits =
-      GetNodeAncestorsLimits(m_pRoot, pFind.Get());
+      GetNodeAncestorsLimits(m_pRoot, node_to_insert.names.Get());
   for (auto* pLimits : all_limits) {
     if (!pLimits)
       continue;
@@ -573,7 +578,7 @@
 
 RetainPtr<const CPDF_Object> CPDF_NameTree::LookupValue(
     const WideString& csName) const {
-  return SearchNameNodeByName(m_pRoot, csName, nullptr, nullptr);
+  return SearchNameNodeByName(m_pRoot, csName, nullptr);
 }
 
 RetainPtr<const CPDF_Array> CPDF_NameTree::LookupNewStyleNamedDest(