Revert "Remove potentially tree-corrupting methods from CXFA_LayoutItem."

This reverts commit d8beda83b6696f4745c49f5fb77861fb953f9575.

Reason for revert: causes hang in i-134.pdf

TBR=thestig@chromium.org
Bug: pdfium:1287
Change-Id: I228eeb3186525556a9832c419c64ac52b07f8cf4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53570
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/layout/cxfa_itemlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_itemlayoutprocessor.cpp
index 2387b57..a6ddfc8 100644
--- a/xfa/fxfa/layout/cxfa_itemlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_itemlayoutprocessor.cpp
@@ -722,21 +722,22 @@
       }
     }
   } else {
-    if (pSecondLayoutItem->GetParent())
-      pSecondLayoutItem->GetParent()->RemoveChild(pSecondLayoutItem);
-    pLayoutItem->GetParent()->InsertChild(pLayoutItem, pSecondLayoutItem);
+    pSecondLayoutItem->SetParent(pLayoutItem->GetParent());
+    pSecondLayoutItem->SetNextSibling(pLayoutItem->GetNextSibling());
+    pLayoutItem->SetNextSibling(pSecondLayoutItem);
   }
 
-  std::vector<CXFA_ContentLayoutItem*> children;
-  while (auto* pFirst = ToContentLayoutItem(pLayoutItem->GetFirstChild())) {
-    children.push_back(pFirst);
-    pLayoutItem->RemoveChild(pFirst);
-  }
+  CXFA_ContentLayoutItem* pChildren =
+      ToContentLayoutItem(pLayoutItem->GetFirstChild());
+  pLayoutItem->SetFirstChild(nullptr);
 
   float lHeightForKeep = 0;
   float fAddMarginHeight = 0;
   std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
-  for (auto* pChildItem : children) {
+  for (CXFA_ContentLayoutItem *pChildItem = pChildren, *pChildNext = nullptr;
+       pChildItem; pChildItem = pChildNext) {
+    pChildNext = ToContentLayoutItem(pChildItem->GetNextSibling());
+    pChildItem->SetNextSibling(nullptr);
     if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                          kXFALayoutPrecision) {
       if (!ExistContainerKeep(pChildItem->GetFormNode(), true)) {
@@ -797,8 +798,7 @@
   CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
   if (pLayoutItem) {
     m_pLayoutItem = ToContentLayoutItem(pLayoutItem->GetNextSibling());
-    if (pLayoutItem->GetParent())
-      pLayoutItem->GetParent()->RemoveChild(pLayoutItem);
+    pLayoutItem->SetNextSibling(nullptr);
   }
 
   if (m_nCurChildNodeStage != Stage::kDone || !m_pOldLayoutItem)
@@ -1588,23 +1588,28 @@
         }
       }
 
-      // TODO(tsepez): avoid looping if we can prove it is in the list.
-      for (CXFA_LayoutItem* pLayoutNext = m_pLayoutItem->GetFirstChild();
-           pLayoutNext; pLayoutNext = pLayoutNext->GetNextSibling()) {
-        if (ToContentLayoutItem(pLayoutNext) == pLastChild) {
-          m_pLayoutItem->RemoveChild(pLastChild);
-          break;
+      if (ToContentLayoutItem(m_pLayoutItem->GetFirstChild()) == pLastChild) {
+        m_pLayoutItem->SetFirstChild(nullptr);
+      } else {
+        for (CXFA_LayoutItem* pLayoutNext = m_pLayoutItem->GetFirstChild();
+             pLayoutNext; pLayoutNext = pLayoutNext->GetNextSibling()) {
+          if (ToContentLayoutItem(pLayoutNext->GetNextSibling()) ==
+              pLastChild) {
+            pLayoutNext->SetNextSibling(nullptr);
+            break;
+          }
         }
       }
 
-      CXFA_ContentLayoutItem* pLayoutNextTemp = pLastChild;
+      CXFA_ContentLayoutItem* pLayoutNextTemp = ToContentLayoutItem(pLastChild);
       while (pLayoutNextTemp) {
+        pLayoutNextTemp->SetParent(nullptr);
         CXFA_ContentLayoutItem* pSaveLayoutNext =
             ToContentLayoutItem(pLayoutNextTemp->GetNextSibling());
-        if (pLayoutNextTemp->GetParent())
-          pLayoutNextTemp->GetParent()->RemoveChild(pLayoutNextTemp);
+        pLayoutNextTemp->SetNextSibling(nullptr);
         pLayoutNextTemp = pSaveLayoutNext;
       }
+      pLastChild = nullptr;
     }
 
     while (m_pCurChildNode) {
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.cpp b/xfa/fxfa/layout/cxfa_layoutitem.cpp
index 543e99d..3dc65ce 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutitem.cpp
@@ -21,7 +21,7 @@
   CXFA_LayoutProcessor* pDocLayout = pDocument->GetLayoutProcessor();
   while (pNode) {
     CXFA_LayoutItem* pNext = pNode->GetNextSibling();
-    pLayoutItem->RemoveChild(pNode);
+    pNode->SetParent(nullptr);
     pNotify->OnLayoutItemRemoving(pDocLayout, pNode);
     XFA_ReleaseLayoutItem(pNode);
     pNode = pNext;
@@ -103,11 +103,14 @@
                                   CXFA_LayoutItem* pChildItem) {
   if (pBeforeItem->m_pParent != this)
     return;
+  if (pChildItem->m_pParent)
+    pChildItem->m_pParent = nullptr;
 
-  ASSERT(!pChildItem->m_pParent);
   pChildItem->m_pParent = this;
-  pChildItem->m_pNextSibling = pBeforeItem->m_pNextSibling;
+
+  CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling;
   pBeforeItem->m_pNextSibling = pChildItem;
+  pChildItem->m_pNextSibling = pExistingChildItem;
 }
 
 void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) {
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.h b/xfa/fxfa/layout/cxfa_layoutitem.h
index c983668..3dd6754 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.h
+++ b/xfa/fxfa/layout/cxfa_layoutitem.h
@@ -32,6 +32,11 @@
   CXFA_Node* GetFormNode() const { return m_pFormNode.Get(); }
   void SetFormNode(CXFA_Node* pNode) { m_pFormNode = pNode; }
 
+  // TODO(tsepez) replace these calls with AddChild() etc.
+  void SetParent(CXFA_LayoutItem* pParent) { m_pParent = pParent; }
+  void SetFirstChild(CXFA_LayoutItem* pChild) { m_pFirstChild = pChild; }
+  void SetNextSibling(CXFA_LayoutItem* pSibling) { m_pNextSibling = pSibling; }
+
   void AddChild(CXFA_LayoutItem* pChildItem);
   void AddHeadChild(CXFA_LayoutItem* pChildItem);
   void RemoveChild(CXFA_LayoutItem* pChildItem);
diff --git a/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp b/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
index 63743ce..917e748 100644
--- a/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
@@ -158,7 +158,7 @@
   }
 }
 
-void ReorderLayoutItemToTail(CXFA_LayoutItem* pLayoutItem) {
+void ReorderLayoutItemToTail(CXFA_ViewLayoutItem* pLayoutItem) {
   CXFA_ViewLayoutItem* pParentLayoutItem =
       ToViewLayoutItem(pLayoutItem->GetParent());
   if (!pParentLayoutItem)
@@ -168,7 +168,7 @@
   pParentLayoutItem->AddChild(pLayoutItem);
 }
 
-void RemoveLayoutItem(CXFA_LayoutItem* pLayoutItem) {
+void RemoveLayoutItem(CXFA_ViewLayoutItem* pLayoutItem) {
   CXFA_ViewLayoutItem* pParentLayoutItem =
       ToViewLayoutItem(pLayoutItem->GetParent());
   if (!pParentLayoutItem)
@@ -389,7 +389,9 @@
   ASSERT(m_pTemplatePageSetRoot);
 
   if (m_pPageSetLayoutItemRoot) {
-    RemoveLayoutItem(m_pPageSetLayoutItemRoot);
+    m_pPageSetLayoutItemRoot->SetParent(nullptr);
+    m_pPageSetLayoutItemRoot->SetFirstChild(nullptr);
+    m_pPageSetLayoutItemRoot->SetNextSibling(nullptr);
     m_pPageSetLayoutItemRoot->SetFormNode(m_pTemplatePageSetRoot);
   } else {
     m_pPageSetLayoutItemRoot =
@@ -647,7 +649,7 @@
     while (pPrePageSet->GetNextSibling()) {
       pPrePageSet = pPrePageSet->GetNextSibling()->AsViewLayoutItem();
     }
-    pPrePageSet->GetParent()->InsertChild(pPrePageSet, pPageSetLayoutItem);
+    pPrePageSet->SetNextSibling(pPageSetLayoutItem);
     m_pPageSetCurRoot = pPageSetLayoutItem;
   } else {
     pParentPageSetLayout->AddChild(pPageSetLayoutItem);
@@ -1642,7 +1644,9 @@
     if (pCurLayoutItem->GetFirstChild())
       SaveLayoutItem(pCurLayoutItem);
 
-    RemoveLayoutItem(pCurLayoutItem);
+    pCurLayoutItem->SetParent(nullptr);
+    pCurLayoutItem->SetNextSibling(nullptr);
+    pCurLayoutItem->SetFirstChild(nullptr);
     if (!pCurLayoutItem->IsContentLayoutItem() &&
         pCurLayoutItem->GetFormNode()->GetElementType() !=
             XFA_Element::PageArea) {
@@ -1937,7 +1941,7 @@
   CXFA_LayoutItem* pNode = pLayoutItem->GetFirstChild();
   while (pNode) {
     CXFA_LayoutItem* pNext = pNode->GetNextSibling();
-    pLayoutItem->RemoveChild(pNode);
+    pNode->SetParent(nullptr);
     XFA_ReleaseLayoutItem_NoPageArea(pNode);
     pNode = pNext;
   }