Remove CFX_PtrList from renderer main loop.

Exposes an iterator over the object list, but not the object
holder, since pages and forms inherit from object holder, and
we don't want to imply that there's only one thing that might
be iterated over for those classes.

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1700183002 .
diff --git a/core/include/fpdfapi/fpdf_page.h b/core/include/fpdfapi/fpdf_page.h
index fb95128..3d98e34 100644
--- a/core/include/fpdfapi/fpdf_page.h
+++ b/core/include/fpdfapi/fpdf_page.h
@@ -7,6 +7,7 @@
 #ifndef CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_
 #define CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_
 
+#include <list>
 #include <memory>
 
 #include "core/include/fpdfapi/fpdf_parser.h"
@@ -27,33 +28,15 @@
 #define PDFTRANS_ISOLATED 0x0200
 #define PDFTRANS_KNOCKOUT 0x0400
 
-class CPDF_PageObjectList : public CFX_PtrList {
+class CPDF_PageObjectList : public std::list<std::unique_ptr<CPDF_PageObject>> {
  public:
-  explicit CPDF_PageObjectList(int nBlockSize) : CFX_PtrList(nBlockSize) {}
-
-  CPDF_PageObject* GetNextObject(FX_POSITION& pos) const {
-    return static_cast<CPDF_PageObject*>(GetNext(pos));
-  }
-
-  CPDF_PageObject* GetPrevObject(FX_POSITION& pos) const {
-    return static_cast<CPDF_PageObject*>(GetPrev(pos));
-  }
-
-  CPDF_PageObject* GetObjectAt(FX_POSITION pos) const {
-    return static_cast<CPDF_PageObject*>(GetAt(pos));
-  }
-
   // Linear complexity, to be avoided except as needed by public APIs.
-  CPDF_PageObject* GetObjectByIndex(int index) const;
-
-  FX_POSITION InsertObject(FX_POSITION posInsertAfter,
-                           CPDF_PageObject* pNewObject);
+  CPDF_PageObject* GetPageObjectByIndex(int index);
 };
 
 class CPDF_PageObjectHolder {
  public:
   CPDF_PageObjectHolder();
-  ~CPDF_PageObjectHolder();
 
   void ContinueParse(IFX_Pause* pPause);
   FX_BOOL IsParsed() const { return m_ParseState == CONTENT_PARSED; }
@@ -165,8 +148,8 @@
 };
 class CPDF_PageContentGenerator {
  public:
-  CPDF_PageContentGenerator(CPDF_Page* pPage);
-  ~CPDF_PageContentGenerator();
+  explicit CPDF_PageContentGenerator(CPDF_Page* pPage);
+
   FX_BOOL InsertPageObject(CPDF_PageObject* pPageObject);
   void GenerateContent();
   void TransformContent(CFX_Matrix& matrix);
diff --git a/core/include/fpdfapi/fpdf_render.h b/core/include/fpdfapi/fpdf_render.h
index fc0f68a..cc9b941 100644
--- a/core/include/fpdfapi/fpdf_render.h
+++ b/core/include/fpdfapi/fpdf_render.h
@@ -151,7 +151,7 @@
   CFX_FloatRect m_ClipRect;
   FX_DWORD m_LayerIndex;
   CPDF_RenderContext::Layer* m_pCurrentLayer;
-  FX_POSITION m_LastObjectRendered;
+  CPDF_PageObjectList::iterator m_LastObjectRendered;
 };
 
 class CPDF_TextRenderer {
diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
index 82ab370..ef0344c 100644
--- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
+++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
@@ -14,25 +14,18 @@
      << matrix.e << " " << matrix.f;
   return ar;
 }
+
 CPDF_PageContentGenerator::CPDF_PageContentGenerator(CPDF_Page* pPage)
-    : m_pPage(pPage) {
-  m_pDocument = NULL;
-  if (m_pPage) {
-    m_pDocument = m_pPage->m_pDocument;
-  }
-  FX_POSITION pos = pPage->GetPageObjectList()->GetHeadPosition();
-  while (pos) {
-    InsertPageObject(pPage->GetPageObjectList()->GetNextObject(pos));
-  }
+    : m_pPage(pPage), m_pDocument(m_pPage->m_pDocument) {
+  for (const auto& pObj : *pPage->GetPageObjectList())
+    InsertPageObject(pObj.get());
 }
-CPDF_PageContentGenerator::~CPDF_PageContentGenerator() {}
+
 FX_BOOL CPDF_PageContentGenerator::InsertPageObject(
     CPDF_PageObject* pPageObject) {
-  if (!pPageObject) {
-    return FALSE;
-  }
-  return m_pageObjects.Add(pPageObject);
+  return pPageObject && m_pageObjects.Add(pPageObject);
 }
+
 void CPDF_PageContentGenerator::GenerateContent() {
   CFX_ByteTextBuf buf;
   CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict;
diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
index 52b79b0..540f9a0 100644
--- a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
+++ b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
@@ -1706,7 +1706,7 @@
   ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
   CPDF_Type3Char* pCachedChar = pNewChar.release();
   m_CacheMap[charcode] = pCachedChar;
-  if (pCachedChar->m_pForm->GetPageObjectList()->GetCount() == 0) {
+  if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
     delete pCachedChar->m_pForm;
     pCachedChar->m_pForm = nullptr;
   }
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
index 4194ff7..b1de6d6 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
@@ -6,8 +6,11 @@
 
 #include "core/src/fpdfapi/fpdf_page/pageint.h"
 
+#include <algorithm>
+
 #include "core/include/fpdfapi/fpdf_module.h"
 #include "core/include/fpdfapi/fpdf_page.h"
+#include "third_party/base/stl_util.h"
 
 CPDF_PageObject* CPDF_PageObject::Create(int type) {
   switch (type) {
@@ -670,6 +673,19 @@
   m_Right = form_rect.right;
   m_Top = form_rect.top;
 }
+
+CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) {
+  if (index < 0 || index >= pdfium::CollectionSize<int>(*this))
+    return nullptr;
+  int current = 0;
+  for (const auto& pObj : *this) {
+    if (index == current)
+      return pObj.get();
+    ++current;
+  }
+  return nullptr;
+}
+
 CPDF_PageObjectHolder::CPDF_PageObjectHolder()
     : m_pFormDict(nullptr),
       m_pFormStream(nullptr),
@@ -679,15 +695,8 @@
       m_Transparency(0),
       m_bBackgroundAlphaNeeded(FALSE),
       m_bHasImageMask(FALSE),
-      m_ParseState(CONTENT_NOT_PARSED),
-      m_PageObjectList(128) {}
+      m_ParseState(CONTENT_NOT_PARSED) {}
 
-CPDF_PageObjectHolder::~CPDF_PageObjectHolder() {
-  FX_POSITION pos = m_PageObjectList.GetHeadPosition();
-  while (pos) {
-    delete m_PageObjectList.GetNextObject(pos);
-  }
-}
 void CPDF_PageObjectHolder::ContinueParse(IFX_Pause* pPause) {
   if (!m_pParser) {
     return;
@@ -698,48 +707,29 @@
     m_pParser.reset();
   }
 }
-FX_POSITION CPDF_PageObjectList::InsertObject(FX_POSITION posInsertAfter,
-                                              CPDF_PageObject* pNewObject) {
-  if (!posInsertAfter) {
-    return AddHead(pNewObject);
-  }
-  return InsertAfter(posInsertAfter, pNewObject);
-}
-CPDF_PageObject* CPDF_PageObjectList::GetObjectByIndex(int index) const {
-  FX_POSITION pos = FindIndex(index);
-  return pos ? GetObjectAt(pos) : nullptr;
-}
+
 void CPDF_PageObjectHolder::Transform(const CFX_Matrix& matrix) {
-  FX_POSITION pos = m_PageObjectList.GetHeadPosition();
-  while (pos) {
-    m_PageObjectList.GetNextObject(pos)->Transform(matrix);
-  }
+  for (auto& pObj : m_PageObjectList)
+    pObj->Transform(matrix);
 }
+
 CFX_FloatRect CPDF_PageObjectHolder::CalcBoundingBox() const {
-  if (m_PageObjectList.GetCount() == 0) {
+  if (m_PageObjectList.empty())
     return CFX_FloatRect(0, 0, 0, 0);
-  }
-  FX_FLOAT left, right, top, bottom;
-  left = bottom = 1000000 * 1.0f;
-  right = top = -1000000 * 1.0f;
-  FX_POSITION pos = m_PageObjectList.GetHeadPosition();
-  while (pos) {
-    CPDF_PageObject* pObj = (CPDF_PageObject*)m_PageObjectList.GetNext(pos);
-    if (left > pObj->m_Left) {
-      left = pObj->m_Left;
-    }
-    if (right < pObj->m_Right) {
-      right = pObj->m_Right;
-    }
-    if (top < pObj->m_Top) {
-      top = pObj->m_Top;
-    }
-    if (bottom > pObj->m_Bottom) {
-      bottom = pObj->m_Bottom;
-    }
+
+  FX_FLOAT left = 1000000.0f;
+  FX_FLOAT right = -1000000.0f;
+  FX_FLOAT bottom = 1000000.0f;
+  FX_FLOAT top = -1000000.0f;
+  for (const auto& pObj : m_PageObjectList) {
+    left = std::min(left, pObj->m_Left);
+    right = std::max(right, pObj->m_Right);
+    bottom = std::min(bottom, pObj->m_Bottom);
+    top = std::max(top, pObj->m_Top);
   }
   return CFX_FloatRect(left, bottom, right, top);
 }
+
 void CPDF_PageObjectHolder::LoadTransInfo() {
   if (!m_pFormDict) {
     return;
@@ -889,7 +879,9 @@
   m_Transparency = 0;
   LoadTransInfo();
 }
+
 CPDF_Form::~CPDF_Form() {}
+
 void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates,
                            CFX_Matrix* pParentMatrix,
                            CPDF_Type3Char* pType3Char,
@@ -903,6 +895,7 @@
                    level);
   m_ParseState = CONTENT_PARSING;
 }
+
 void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates,
                              CFX_Matrix* pParentMatrix,
                              CPDF_Type3Char* pType3Char,
@@ -911,16 +904,16 @@
   StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
   ContinueParse(NULL);
 }
+
 CPDF_Form* CPDF_Form::Clone() const {
-  CPDF_Form* pClone =
+  CPDF_Form* pCloneForm =
       new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources);
-  FX_POSITION pos = m_PageObjectList.GetHeadPosition();
-  while (pos) {
-    CPDF_PageObject* pObj = (CPDF_PageObject*)m_PageObjectList.GetNext(pos);
-    pClone->m_PageObjectList.AddTail(pObj->Clone());
-  }
-  return pClone;
+  for (const auto& pObj : m_PageObjectList)
+    pCloneForm->m_PageObjectList.emplace_back(pObj->Clone());
+
+  return pCloneForm;
 }
+
 void CPDF_Page::GetDisplayMatrix(CFX_Matrix& matrix,
                                  int xPos,
                                  int yPos,
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
index 6e02cb1..d491863 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
@@ -780,7 +780,7 @@
     parser.Parse(stream.GetData(), stream.GetSize(), 0);
     return;
   }
-  CPDF_FormObject* pFormObj = new CPDF_FormObject;
+  std::unique_ptr<CPDF_FormObject> pFormObj(new CPDF_FormObject);
   pFormObj->m_pForm =
       new CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources);
   pFormObj->m_FormMatrix = m_pCurStates->m_CTM;
@@ -796,8 +796,8 @@
     m_pObjectHolder->SetBackgroundAlphaNeeded(TRUE);
   }
   pFormObj->CalcBoundingBox();
-  SetGraphicStates(pFormObj, TRUE, TRUE, TRUE);
-  m_pObjectHolder->GetPageObjectList()->AddTail(pFormObj);
+  SetGraphicStates(pFormObj.get(), TRUE, TRUE, TRUE);
+  m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj));
 }
 
 CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream,
@@ -809,7 +809,8 @@
   CFX_Matrix ImageMatrix;
   ImageMatrix.Copy(m_pCurStates->m_CTM);
   ImageMatrix.Concat(m_mtContentToUser);
-  CPDF_ImageObject* pImageObj = new CPDF_ImageObject;
+
+  std::unique_ptr<CPDF_ImageObject> pImageObj(new CPDF_ImageObject);
   if (pImage) {
     pImageObj->m_pImage =
         m_pDocument->GetPageData()->GetImage(pImage->GetStream());
@@ -819,11 +820,13 @@
     pImageObj->m_pImage = new CPDF_Image(m_pDocument);
     pImageObj->m_pImage->LoadImageF(pStream, bInline);
   }
-  SetGraphicStates(pImageObj, pImageObj->m_pImage->IsMask(), FALSE, FALSE);
+  SetGraphicStates(pImageObj.get(), pImageObj->m_pImage->IsMask(), FALSE,
+                   FALSE);
   pImageObj->m_Matrix = ImageMatrix;
   pImageObj->CalcBoundingBox();
-  m_pObjectHolder->GetPageObjectList()->AddTail(pImageObj);
-  return pImageObj;
+  CPDF_ImageObject* pRet = pImageObj.get();
+  m_pObjectHolder->GetPageObjectList()->push_back(std::move(pImageObj));
+  return pRet;
 }
 
 void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {}
@@ -1190,9 +1193,9 @@
   if (!pShading->Load()) {
     return;
   }
-  CPDF_ShadingObject* pObj = new CPDF_ShadingObject;
+  std::unique_ptr<CPDF_ShadingObject> pObj(new CPDF_ShadingObject);
   pObj->m_pShading = pShading;
-  SetGraphicStates(pObj, FALSE, FALSE, FALSE);
+  SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE);
   pObj->m_Matrix = m_pCurStates->m_CTM;
   pObj->m_Matrix.Concat(m_mtContentToUser);
   CFX_FloatRect bbox;
@@ -1211,7 +1214,7 @@
   pObj->m_Right = bbox.right;
   pObj->m_Top = bbox.top;
   pObj->m_Bottom = bbox.bottom;
-  m_pObjectHolder->GetPageObjectList()->AddTail(pObj);
+  m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj));
 }
 
 void CPDF_StreamContentParser::Handle_SetCharSpace() {
@@ -1365,31 +1368,34 @@
   } else {
     textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode;
   }
-  CPDF_TextObject* pText = new CPDF_TextObject;
-  m_pLastTextObject = pText;
-  SetGraphicStates(pText, TRUE, TRUE, TRUE);
-  if (textmode && textmode != 3 && textmode != 4 && textmode != 7) {
-    FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM;
-    pCTM[0] = m_pCurStates->m_CTM.a;
-    pCTM[1] = m_pCurStates->m_CTM.c;
-    pCTM[2] = m_pCurStates->m_CTM.b;
-    pCTM[3] = m_pCurStates->m_CTM.d;
+  {
+    std::unique_ptr<CPDF_TextObject> pText(new CPDF_TextObject);
+    m_pLastTextObject = pText.get();
+    SetGraphicStates(m_pLastTextObject, TRUE, TRUE, TRUE);
+    if (textmode && textmode != 3 && textmode != 4 && textmode != 7) {
+      FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM;
+      pCTM[0] = m_pCurStates->m_CTM.a;
+      pCTM[1] = m_pCurStates->m_CTM.c;
+      pCTM[2] = m_pCurStates->m_CTM.b;
+      pCTM[3] = m_pCurStates->m_CTM.d;
+    }
+    pText->SetSegments(pStrs, pKerning, nsegs);
+    pText->m_PosX = m_pCurStates->m_TextX;
+    pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise;
+    ConvertTextSpace(pText->m_PosX, pText->m_PosY);
+    FX_FLOAT x_advance;
+    FX_FLOAT y_advance;
+    pText->CalcPositionData(&x_advance, &y_advance,
+                            m_pCurStates->m_TextHorzScale, m_Level);
+    m_pCurStates->m_TextX += x_advance;
+    m_pCurStates->m_TextY += y_advance;
+    if (textmode > 3) {
+      CPDF_TextObject* pCopy = new CPDF_TextObject;
+      pCopy->Copy(pText.get());
+      m_ClipTextList.Add(pCopy);
+    }
+    m_pObjectHolder->GetPageObjectList()->push_back(std::move(pText));
   }
-  pText->SetSegments(pStrs, pKerning, nsegs);
-  pText->m_PosX = m_pCurStates->m_TextX;
-  pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise;
-  ConvertTextSpace(pText->m_PosX, pText->m_PosY);
-  FX_FLOAT x_advance, y_advance;
-  pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale,
-                          m_Level);
-  m_pCurStates->m_TextX += x_advance;
-  m_pCurStates->m_TextY += y_advance;
-  if (textmode > 3) {
-    CPDF_TextObject* pCopy = new CPDF_TextObject;
-    pCopy->Copy(pText);
-    m_ClipTextList.Add(pCopy);
-  }
-  m_pObjectHolder->GetPageObjectList()->AddTail(pText);
   if (pKerning && pKerning[nsegs - 1] != 0) {
     if (!pFont->IsVertWriting()) {
       m_pCurStates->m_TextX -=
@@ -1617,14 +1623,14 @@
   CFX_Matrix matrix = m_pCurStates->m_CTM;
   matrix.Concat(m_mtContentToUser);
   if (bStroke || FillType) {
-    CPDF_PathObject* pPathObj = new CPDF_PathObject;
+    std::unique_ptr<CPDF_PathObject> pPathObj(new CPDF_PathObject);
     pPathObj->m_bStroke = bStroke;
     pPathObj->m_FillType = FillType;
     pPathObj->m_Path = Path;
     pPathObj->m_Matrix = matrix;
-    SetGraphicStates(pPathObj, TRUE, FALSE, TRUE);
+    SetGraphicStates(pPathObj.get(), TRUE, FALSE, TRUE);
     pPathObj->CalcBoundingBox();
-    m_pObjectHolder->GetPageObjectList()->AddTail(pPathObj);
+    m_pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj));
   }
   if (PathClipType) {
     if (!matrix.IsIdentity()) {
@@ -1641,13 +1647,12 @@
   if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
     return dwSize;
   }
-  FX_DWORD InitObjCount = m_pObjectHolder->GetPageObjectList()->GetCount();
+  FX_DWORD InitObjCount = m_pObjectHolder->GetPageObjectList()->size();
   CPDF_StreamParser syntax(pData, dwSize);
   CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax);
   m_CompatCount = 0;
   while (1) {
-    FX_DWORD cost =
-        m_pObjectHolder->GetPageObjectList()->GetCount() - InitObjCount;
+    FX_DWORD cost = m_pObjectHolder->GetPageObjectList()->size() - InitObjCount;
     if (max_cost && cost >= max_cost) {
       break;
     }
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index 7fa3286..20f0c39 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -666,7 +666,7 @@
 CPDF_ContentParser::CPDF_ContentParser()
     : m_Status(Ready),
       m_InternalStage(STAGE_GETCONTENT),
-      m_pObjects(nullptr),
+      m_pObjectHolder(nullptr),
       m_bForm(false),
       m_pType3Char(nullptr),
       m_pData(nullptr),
@@ -684,7 +684,7 @@
     m_Status = Done;
     return;
   }
-  m_pObjects = pPage;
+  m_pObjectHolder = pPage;
   m_bForm = FALSE;
   if (pOptions) {
     m_Options = *pOptions;
@@ -720,7 +720,7 @@
                                CPDF_ParseOptions* pOptions,
                                int level) {
   m_pType3Char = pType3Char;
-  m_pObjects = pForm;
+  m_pObjectHolder = pForm;
   m_bForm = TRUE;
   CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixBy("Matrix");
   if (pGraphicStates) {
@@ -803,7 +803,8 @@
         m_InternalStage = STAGE_PARSE;
         m_CurrentOffset = 0;
       } else {
-        CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArrayBy("Contents");
+        CPDF_Array* pContent =
+            m_pObjectHolder->m_pFormDict->GetArrayBy("Contents");
         m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc);
         CPDF_Stream* pStreamObj = ToStream(
             pContent ? pContent->GetElementValue(m_CurrentOffset) : nullptr);
@@ -814,9 +815,9 @@
     if (m_InternalStage == STAGE_PARSE) {
       if (!m_pParser) {
         m_pParser.reset(new CPDF_StreamContentParser(
-            m_pObjects->m_pDocument, m_pObjects->m_pPageResources, nullptr,
-            nullptr, m_pObjects, m_pObjects->m_pResources, &m_pObjects->m_BBox,
-            &m_Options, nullptr, 0));
+            m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources,
+            nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources,
+            &m_pObjectHolder->m_BBox, &m_Options, nullptr, 0));
         m_pParser->GetCurStates()->m_ColorState.GetModify()->Default();
       }
       if (m_CurrentOffset >= m_Size) {
@@ -841,10 +842,7 @@
         m_pType3Char->m_BBox.top =
             FXSYS_round(m_pParser->GetType3Data()[5] * 1000);
       }
-      FX_POSITION pos = m_pObjects->GetPageObjectList()->GetHeadPosition();
-      while (pos) {
-        CPDF_PageObject* pObj =
-            m_pObjects->GetPageObjectList()->GetNextObject(pos);
+      for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) {
         if (pObj->m_ClipPath.IsNull()) {
           continue;
         }
diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h
index 4df8d6a..fb95b6b 100644
--- a/core/src/fpdfapi/fpdf_page/pageint.h
+++ b/core/src/fpdfapi/fpdf_page/pageint.h
@@ -94,7 +94,7 @@
                            CPDF_Dictionary* pPageResources,
                            CPDF_Dictionary* pParentResources,
                            CFX_Matrix* pmtContentToUser,
-                           CPDF_PageObjectHolder* pObjHolder,
+                           CPDF_PageObjectHolder* pObjectHolder,
                            CPDF_Dictionary* pResources,
                            CFX_FloatRect* pBBox,
                            CPDF_ParseOptions* pOptions,
@@ -298,7 +298,7 @@
 
   ParseStatus m_Status;
   InternalStage m_InternalStage;
-  CPDF_PageObjectHolder* m_pObjects;
+  CPDF_PageObjectHolder* m_pObjectHolder;
   FX_BOOL m_bForm;
   CPDF_ParseOptions m_Options;
   CPDF_Type3Char* m_pType3Char;
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
index 0023ee9..147de51 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
@@ -244,29 +244,24 @@
   CFX_Matrix device2object;
   device2object.SetReverse(*pObj2Device);
   device2object.TransformRect(clip_rect);
-  int index = 0;
-  FX_POSITION pos = pObjectHolder->GetPageObjectList()->GetHeadPosition();
-  while (pos) {
-    index++;
-    CPDF_PageObject* pCurObj =
-        pObjectHolder->GetPageObjectList()->GetNextObject(pos);
-    if (pCurObj == m_pStopObj) {
+
+  for (const auto& pCurObj : *pObjectHolder->GetPageObjectList()) {
+    if (pCurObj.get() == m_pStopObj) {
       m_bStopped = TRUE;
       return;
     }
-    if (!pCurObj) {
+    if (!pCurObj)
       continue;
-    }
-    if (!pCurObj || pCurObj->m_Left > clip_rect.right ||
+
+    if (pCurObj->m_Left > clip_rect.right ||
         pCurObj->m_Right < clip_rect.left ||
         pCurObj->m_Bottom > clip_rect.top ||
         pCurObj->m_Top < clip_rect.bottom) {
       continue;
     }
-    RenderSingleObject(pCurObj, pObj2Device);
-    if (m_bStopped) {
+    RenderSingleObject(pCurObj.get(), pObj2Device);
+    if (m_bStopped)
       return;
-    }
   }
 }
 void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj,
@@ -1037,8 +1032,7 @@
       m_pDevice(pDevice),
       m_pOptions(pOptions),
       m_LayerIndex(0),
-      m_pCurrentLayer(nullptr),
-      m_LastObjectRendered(nullptr) {}
+      m_pCurrentLayer(nullptr) {}
 
 CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() {
   if (m_pRenderStatus)
@@ -1062,7 +1056,8 @@
         return;
       }
       m_pCurrentLayer = m_pContext->GetLayer(m_LayerIndex);
-      m_LastObjectRendered = nullptr;
+      m_LastObjectRendered =
+          m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->end();
       m_pRenderStatus.reset(new CPDF_RenderStatus());
       m_pRenderStatus->Initialize(
           m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions,
@@ -1073,19 +1068,18 @@
       device2object.SetReverse(m_pCurrentLayer->m_Matrix);
       device2object.TransformRect(m_ClipRect);
     }
-    FX_POSITION pos;
-    if (m_LastObjectRendered) {
-      pos = m_LastObjectRendered;
-      m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->GetNextObject(pos);
+    CPDF_PageObjectList::iterator iter;
+    CPDF_PageObjectList::iterator iterEnd =
+        m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->end();
+    if (m_LastObjectRendered != iterEnd) {
+      iter = m_LastObjectRendered;
+      ++iter;
     } else {
-      pos = m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()
-                ->GetHeadPosition();
+      iter = m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->begin();
     }
     int nObjsToGo = kStepLimit;
-    while (pos) {
-      CPDF_PageObject* pCurObj =
-          m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->GetObjectAt(
-              pos);
+    while (iter != iterEnd) {
+      CPDF_PageObject* pCurObj = iter->get();
       if (pCurObj && pCurObj->m_Left <= m_ClipRect.right &&
           pCurObj->m_Right >= m_ClipRect.left &&
           pCurObj->m_Bottom <= m_ClipRect.top &&
@@ -1106,19 +1100,18 @@
           --nObjsToGo;
         }
       }
-      m_LastObjectRendered = pos;
+      m_LastObjectRendered = iter;
       if (nObjsToGo == 0) {
         if (pPause && pPause->NeedToPauseNow())
           return;
         nObjsToGo = kStepLimit;
       }
-      m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->GetNextObject(pos);
+      ++iter;
     }
     if (m_pCurrentLayer->m_pObjectHolder->IsParsed()) {
       m_pRenderStatus.reset();
       m_pDevice->RestoreState();
       m_pCurrentLayer = nullptr;
-      m_LastObjectRendered = nullptr;
       m_LayerIndex++;
       if (pPause && pPause->NeedToPauseNow()) {
         return;
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
index f19e6f8..d2faac3 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
@@ -316,11 +316,10 @@
   if (m_pBitmap || !m_pForm) {
     return TRUE;
   }
-  if (m_pForm->GetPageObjectList()->GetCount() == 1 && !m_bColored) {
-    CPDF_PageObject* pPageObj = m_pForm->GetPageObjectList()->GetObjectAt(
-        m_pForm->GetPageObjectList()->GetHeadPosition());
+  if (m_pForm->GetPageObjectList()->size() == 1 && !m_bColored) {
+    auto& pPageObj = m_pForm->GetPageObjectList()->front();
     if (pPageObj->m_Type == CPDF_PageObject::IMAGE) {
-      CPDF_ImageObject* pImage = (CPDF_ImageObject*)pPageObj;
+      CPDF_ImageObject* pImage = static_cast<CPDF_ImageObject*>(pPageObj.get());
       m_ImageMatrix = pImage->m_Matrix;
       const CFX_DIBSource* pSource = pImage->m_pImage->LoadDIBSource();
       if (pSource) {
diff --git a/core/src/fpdftext/fpdf_text_int.cpp b/core/src/fpdftext/fpdf_text_int.cpp
index aa13ace..8972f84 100644
--- a/core/src/fpdftext/fpdf_text_int.cpp
+++ b/core/src/fpdftext/fpdf_text_int.cpp
@@ -761,20 +761,13 @@
   uint8_t* pDataV = nVerticalMask.data();
   int32_t index = 0;
   FX_FLOAT fLineHeight = 0.0f;
-  CPDF_PageObject* pPageObj = NULL;
-  FX_POSITION pos = NULL;
-  pos = m_pPage->GetPageObjectList()->GetHeadPosition();
-  if (!pos) {
+  if (m_pPage->GetPageObjectList()->empty())
     return -1;
-  }
-  while (pos) {
-    pPageObj = m_pPage->GetPageObjectList()->GetNextObject(pos);
-    if (!pPageObj) {
+
+  for (auto& pPageObj : *m_pPage->GetPageObjectList()) {
+    if (!pPageObj || pPageObj->m_Type != CPDF_PageObject::TEXT)
       continue;
-    }
-    if (CPDF_PageObject::TEXT != pPageObj->m_Type) {
-      continue;
-    }
+
     int32_t minH =
         (int32_t)pPageObj->m_Left < 0 ? 0 : (int32_t)pPageObj->m_Left;
     int32_t maxH = (int32_t)pPageObj->m_Right > nPageWidth
@@ -785,28 +778,26 @@
     int32_t maxV = (int32_t)pPageObj->m_Top > nPageHeight
                        ? nPageHeight
                        : (int32_t)pPageObj->m_Top;
-    if (minH >= maxH || minV >= maxV) {
+    if (minH >= maxH || minV >= maxV)
       continue;
-    }
+
     FXSYS_memset(pDataH + minH, 1, maxH - minH);
     FXSYS_memset(pDataV + minV, 1, maxV - minV);
-    if (fLineHeight <= 0.0f) {
+    if (fLineHeight <= 0.0f)
       fLineHeight = pPageObj->m_Top - pPageObj->m_Bottom;
-    }
-    pPageObj = NULL;
   }
   int32_t nStartH = 0;
   int32_t nEndH = 0;
   FX_FLOAT nSumH = 0.0f;
-  for (index = 0; index < nPageWidth; index++)
-    if (1 == nHorizontalMask[index]) {
+  for (index = 0; index < nPageWidth; index++) {
+    if (1 == nHorizontalMask[index])
       break;
-    }
+  }
   nStartH = index;
-  for (index = nPageWidth; index > 0; index--)
-    if (1 == nHorizontalMask[index - 1]) {
+  for (index = nPageWidth; index > 0; index--) {
+    if (1 == nHorizontalMask[index - 1])
       break;
-    }
+  }
   nEndH = index;
   for (index = nStartH; index < nEndH; index++) {
     nSumH += nHorizontalMask[index];
@@ -815,15 +806,15 @@
   int32_t nStartV = 0;
   int32_t nEndV = 0;
   FX_FLOAT nSumV = 0.0f;
-  for (index = 0; index < nPageHeight; index++)
-    if (1 == nVerticalMask[index]) {
+  for (index = 0; index < nPageHeight; index++) {
+    if (1 == nVerticalMask[index])
       break;
-    }
+  }
   nStartV = index;
-  for (index = nPageHeight; index > 0; index--)
-    if (1 == nVerticalMask[index - 1]) {
+  for (index = nPageHeight; index > 0; index--) {
+    if (1 == nVerticalMask[index - 1])
       break;
-    }
+  }
   nEndV = index;
   for (index = nStartV; index < nEndV; index++) {
     nSumV += nVerticalMask[index];
@@ -848,58 +839,50 @@
 }
 
 void CPDF_TextPage::ProcessObject() {
-  FX_POSITION pos = m_pPage->GetPageObjectList()->GetHeadPosition();
-  if (!pos) {
+  if (m_pPage->GetPageObjectList()->empty())
     return;
-  }
+
   m_TextlineDir = FindTextlineFlowDirection();
-  int nCount = 0;
-  while (pos) {
-    CPDF_PageObject* pPageObj =
-        m_pPage->GetPageObjectList()->GetNextObject(pos);
-    if (pPageObj) {
-      if (pPageObj->m_Type == CPDF_PageObject::TEXT) {
+  const CPDF_PageObjectList* pObjList = m_pPage->GetPageObjectList();
+  for (auto it = pObjList->begin(); it != pObjList->end(); ++it) {
+    if (CPDF_PageObject* pObj = it->get()) {
+      if (pObj->m_Type == CPDF_PageObject::TEXT) {
         CFX_Matrix matrix;
-        ProcessTextObject((CPDF_TextObject*)pPageObj, matrix, pos);
-        nCount++;
-      } else if (pPageObj->m_Type == CPDF_PageObject::FORM) {
+        ProcessTextObject(static_cast<CPDF_TextObject*>(pObj), matrix, pObjList,
+                          it);
+      } else if (pObj->m_Type == CPDF_PageObject::FORM) {
         CFX_Matrix formMatrix(1, 0, 0, 1, 0, 0);
-        ProcessFormObject((CPDF_FormObject*)pPageObj, formMatrix);
+        ProcessFormObject(static_cast<CPDF_FormObject*>(pObj), formMatrix);
       }
     }
   }
-  int count = m_LineObj.GetSize();
-  for (int i = 0; i < count; i++) {
+  for (int i = 0; i < m_LineObj.GetSize(); i++)
     ProcessTextObject(m_LineObj.GetAt(i));
-  }
+
   m_LineObj.RemoveAll();
   CloseTempLine();
 }
 
 void CPDF_TextPage::ProcessFormObject(CPDF_FormObject* pFormObj,
                                       const CFX_Matrix& formMatrix) {
-  CPDF_PageObject* pPageObj = NULL;
-  FX_POSITION pos;
-  if (!pFormObj) {
+  CPDF_PageObjectList* pObjectList = pFormObj->m_pForm->GetPageObjectList();
+  if (pObjectList->empty())
     return;
-  }
-  pos = pFormObj->m_pForm->GetPageObjectList()->GetHeadPosition();
-  if (!pos) {
-    return;
-  }
+
   CFX_Matrix curFormMatrix;
   curFormMatrix.Copy(pFormObj->m_FormMatrix);
   curFormMatrix.Concat(formMatrix);
-  while (pos) {
-    pPageObj = pFormObj->m_pForm->GetPageObjectList()->GetNextObject(pos);
-    if (pPageObj) {
+
+  for (auto it = pObjectList->begin(); it != pObjectList->end(); ++it) {
+    if (CPDF_PageObject* pPageObj = it->get()) {
       if (pPageObj->m_Type == CPDF_PageObject::TEXT) {
-        ProcessTextObject((CPDF_TextObject*)pPageObj, curFormMatrix, pos);
+        ProcessTextObject(static_cast<CPDF_TextObject*>(pPageObj),
+                          curFormMatrix, pObjectList, it);
       } else if (pPageObj->m_Type == CPDF_PageObject::FORM) {
-        ProcessFormObject((CPDF_FormObject*)pPageObj, curFormMatrix);
+        ProcessFormObject(static_cast<CPDF_FormObject*>(pPageObj),
+                          curFormMatrix);
       }
     }
-    pPageObj = NULL;
   }
 }
 
@@ -1032,9 +1015,11 @@
   m_TempTextBuf.Delete(0, m_TempTextBuf.GetLength());
 }
 
-void CPDF_TextPage::ProcessTextObject(CPDF_TextObject* pTextObj,
-                                      const CFX_Matrix& formMatrix,
-                                      FX_POSITION ObjPos) {
+void CPDF_TextPage::ProcessTextObject(
+    CPDF_TextObject* pTextObj,
+    const CFX_Matrix& formMatrix,
+    const CPDF_PageObjectList* pObjList,
+    CPDF_PageObjectList::const_iterator ObjPos) {
   CFX_FloatRect re(pTextObj->m_Left, pTextObj->m_Bottom, pTextObj->m_Right,
                    pTextObj->m_Top);
   if (FXSYS_fabs(pTextObj->m_Right - pTextObj->m_Left) < 0.01f) {
@@ -1048,7 +1033,7 @@
     m_LineObj.Add(Obj);
     return;
   }
-  if (IsSameAsPreTextObject(pTextObj, ObjPos)) {
+  if (IsSameAsPreTextObject(pTextObj, pObjList, ObjPos)) {
     return;
   }
   PDFTEXT_Obj prev_Obj = m_LineObj.GetAt(count - 1);
@@ -1832,29 +1817,19 @@
   }
   return TRUE;
 }
-
-FX_BOOL CPDF_TextPage::IsSameAsPreTextObject(CPDF_TextObject* pTextObj,
-                                             FX_POSITION ObjPos) {
-  if (!pTextObj) {
-    return FALSE;
-  }
+FX_BOOL CPDF_TextPage::IsSameAsPreTextObject(
+    CPDF_TextObject* pTextObj,
+    const CPDF_PageObjectList* pObjList,
+    CPDF_PageObjectList::const_iterator iter) {
   int i = 0;
-  if (!ObjPos) {
-    ObjPos = m_pPage->GetPageObjectList()->GetTailPosition();
-  }
-  CPDF_PageObject* pObj = m_pPage->GetPageObjectList()->GetPrevObject(ObjPos);
-  while (i < 5 && ObjPos) {
-    pObj = m_pPage->GetPageObjectList()->GetPrevObject(ObjPos);
-    if (pObj == pTextObj) {
+  while (i < 5 && iter != pObjList->begin()) {
+    --iter;
+    CPDF_PageObject* pOtherObj = iter->get();
+    if (pOtherObj == pTextObj || pOtherObj->m_Type != CPDF_PageObject::TEXT)
       continue;
-    }
-    if (pObj->m_Type != CPDF_PageObject::TEXT) {
-      continue;
-    }
-    if (IsSameTextObject((CPDF_TextObject*)pObj, pTextObj)) {
+    if (IsSameTextObject(static_cast<CPDF_TextObject*>(pOtherObj), pTextObj))
       return TRUE;
-    }
-    i++;
+    ++i;
   }
   return FALSE;
 }
diff --git a/core/src/fpdftext/text_int.h b/core/src/fpdftext/text_int.h
index 9b7d654..113e1d1 100644
--- a/core/src/fpdftext/text_int.h
+++ b/core/src/fpdftext/text_int.h
@@ -10,6 +10,7 @@
 #include <deque>
 #include <vector>
 
+#include "core/include/fpdfapi/fpdf_page.h"
 #include "core/include/fpdftext/fpdf_text.h"
 #include "core/include/fxcrt/fx_basic.h"
 
@@ -107,11 +108,14 @@
   void ProcessTextObject(PDFTEXT_Obj pObj);
   void ProcessTextObject(CPDF_TextObject* pTextObj,
                          const CFX_Matrix& formMatrix,
-                         FX_POSITION ObjPos);
+                         const CPDF_PageObjectList* pObjList,
+                         CPDF_PageObjectList::const_iterator ObjPos);
   int ProcessInsertObject(const CPDF_TextObject* pObj,
                           const CFX_Matrix& formMatrix);
   FX_BOOL GenerateCharInfo(FX_WCHAR unicode, PAGECHAR_INFO& info);
-  FX_BOOL IsSameAsPreTextObject(CPDF_TextObject* pTextObj, FX_POSITION ObjPos);
+  FX_BOOL IsSameAsPreTextObject(CPDF_TextObject* pTextObj,
+                                const CPDF_PageObjectList* pObjList,
+                                CPDF_PageObjectList::const_iterator ObjPos);
   FX_BOOL IsSameTextObject(CPDF_TextObject* pTextObj1,
                            CPDF_TextObject* pTextObj2);
   int GetCharWidth(FX_DWORD charCode, CPDF_Font* pFont) const;
diff --git a/fpdfsdk/include/fxedit/fx_edit.h b/fpdfsdk/include/fxedit/fx_edit.h
index 359f7d8..5e1ac0f 100644
--- a/fpdfsdk/include/fxedit/fx_edit.h
+++ b/fpdfsdk/include/fxedit/fx_edit.h
@@ -458,19 +458,19 @@
                            const CPDF_Point& ptOffset,
                            const CPVT_WordRange* pRange);
   static void GeneratePageObjects(
-      CPDF_PageObjectHolder* pPageObjects,
+      CPDF_PageObjectHolder* pObjectHolder,
       IFX_Edit* pEdit,
       const CPDF_Point& ptOffset,
       const CPVT_WordRange* pRange,
       FX_COLORREF crText,
       CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
   static void GenerateRichPageObjects(
-      CPDF_PageObjectHolder* pPageObjects,
+      CPDF_PageObjectHolder* pObjectHolder,
       IFX_Edit* pEdit,
       const CPDF_Point& ptOffset,
       const CPVT_WordRange* pRange,
       CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-  static void GenerateUnderlineObjects(CPDF_PageObjectHolder* pPageObjects,
+  static void GenerateUnderlineObjects(CPDF_PageObjectHolder* pObjectHolder,
                                        IFX_Edit* pEdit,
                                        const CPDF_Point& ptOffset,
                                        const CPVT_WordRange* pRange,
diff --git a/fpdfsdk/include/pdfwindow/PWL_Edit.h b/fpdfsdk/include/pdfwindow/PWL_Edit.h
index 4b3411b..7352818 100644
--- a/fpdfsdk/include/pdfwindow/PWL_Edit.h
+++ b/fpdfsdk/include/pdfwindow/PWL_Edit.h
@@ -110,10 +110,10 @@
     m_pFillerNotify = pNotify;
   }
 
-  void GeneratePageObjects(CPDF_PageObjectHolder* pPageObjects,
+  void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                            const CPDF_Point& ptOffset,
                            CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-  void GeneratePageObjects(CPDF_PageObjectHolder* pPageObjects,
+  void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                            const CPDF_Point& ptOffset);
 
  protected:
diff --git a/fpdfsdk/src/fpdf_flatten.cpp b/fpdfsdk/src/fpdf_flatten.cpp
index 36b8319..9aee35f 100644
--- a/fpdfsdk/src/fpdf_flatten.cpp
+++ b/fpdfsdk/src/fpdf_flatten.cpp
@@ -35,17 +35,14 @@
   return TRUE;
 }
 
-FX_BOOL GetContentsRect(CPDF_Document* pDoc,
-                        CPDF_Dictionary* pDict,
-                        CPDF_RectArray* pRectArray) {
-  CPDF_Page* pPDFPage = new CPDF_Page;
+void GetContentsRect(CPDF_Document* pDoc,
+                     CPDF_Dictionary* pDict,
+                     CPDF_RectArray* pRectArray) {
+  std::unique_ptr<CPDF_Page> pPDFPage(new CPDF_Page);
   pPDFPage->Load(pDoc, pDict, FALSE);
   pPDFPage->ParseContent(nullptr);
 
-  FX_POSITION pos = pPDFPage->GetPageObjectList()->GetHeadPosition();
-  while (pos) {
-    CPDF_PageObject* pPageObject =
-        pPDFPage->GetPageObjectList()->GetNextObject(pos);
+  for (auto& pPageObject : *pPDFPage->GetPageObjectList()) {
     if (!pPageObject)
       continue;
 
@@ -54,14 +51,9 @@
     rc.right = pPageObject->m_Right;
     rc.bottom = pPageObject->m_Bottom;
     rc.top = pPageObject->m_Top;
-
-    if (IsValiableRect(rc, pDict->GetRectBy("MediaBox"))) {
+    if (IsValiableRect(rc, pDict->GetRectBy("MediaBox")))
       pRectArray->Add(rc);
-    }
   }
-
-  delete pPDFPage;
-  return TRUE;
 }
 
 void ParserStream(CPDF_Dictionary* pPageDic,
diff --git a/fpdfsdk/src/fpdfeditpage.cpp b/fpdfsdk/src/fpdfeditpage.cpp
index 6d39cb1..6c14079 100644
--- a/fpdfsdk/src/fpdfeditpage.cpp
+++ b/fpdfsdk/src/fpdfeditpage.cpp
@@ -8,6 +8,7 @@
 
 #include "fpdfsdk/include/fsdk_define.h"
 #include "public/fpdf_formfill.h"
+#include "third_party/base/stl_util.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
@@ -135,9 +136,10 @@
   CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
   if (!pPageObj)
     return;
-  FX_POSITION LastPersition = pPage->GetPageObjectList()->GetTailPosition();
 
-  pPage->GetPageObjectList()->InsertObject(LastPersition, pPageObj);
+  pPage->GetPageObjectList()->push_back(
+      std::unique_ptr<CPDF_PageObject>(pPageObj));
+
   switch (pPageObj->m_Type) {
     case FPDF_PAGEOBJ_PATH: {
       CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
@@ -145,8 +147,6 @@
       break;
     }
     case FPDF_PAGEOBJ_TEXT: {
-      //	CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
-      //	pPathObj->CalcBoundingBox();
       break;
     }
     case FPDF_PAGEOBJ_IMAGE: {
@@ -177,7 +177,7 @@
           "Page")) {
     return -1;
   }
-  return pPage->GetPageObjectList()->GetCount();
+  return pdfium::CollectionSize<int>(*pPage->GetPageObjectList());
 }
 
 DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page,
@@ -186,9 +186,9 @@
   if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
       pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
           "Page")) {
-    return NULL;
+    return nullptr;
   }
-  return pPage->GetPageObjectList()->GetObjectByIndex(index);
+  return pPage->GetPageObjectList()->GetPageObjectByIndex(index);
 }
 
 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) {
diff --git a/fpdfsdk/src/fxedit/fxet_pageobjs.cpp b/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
index d54e464..c3bd797 100644
--- a/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
+++ b/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
@@ -409,10 +409,10 @@
   pDevice->RestoreState();
 }
 
-static void AddRectToPageObjects(CPDF_PageObjectHolder* pPageObjs,
+static void AddRectToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
                                  FX_COLORREF crFill,
                                  const CPDF_Rect& rcFill) {
-  CPDF_PathObject* pPathObj = new CPDF_PathObject;
+  std::unique_ptr<CPDF_PathObject> pPathObj(new CPDF_PathObject);
   CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();
   pPathData->AppendRect(rcFill.left, rcFill.bottom, rcFill.right, rcFill.top);
 
@@ -425,12 +425,11 @@
 
   pPathObj->m_FillType = FXFILL_ALTERNATE;
   pPathObj->m_bStroke = FALSE;
-  pPageObjs->GetPageObjectList()->InsertObject(
-      pPageObjs->GetPageObjectList()->GetTailPosition(), pPathObj);
+  pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj));
 }
 
 static CPDF_TextObject* AddTextObjToPageObjects(
-    CPDF_PageObjectHolder* pPageObjs,
+    CPDF_PageObjectHolder* pObjectHolder,
     FX_COLORREF crText,
     CPDF_Font* pFont,
     FX_FLOAT fFontSize,
@@ -438,8 +437,7 @@
     int32_t nHorzScale,
     const CPDF_Point& point,
     const CFX_ByteString& text) {
-  CPDF_TextObject* pTxtObj = new CPDF_TextObject;
-
+  std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject);
   CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
   pTextStateData->m_pFont = pFont;
   pTextStateData->m_FontSize = fFontSize;
@@ -462,14 +460,14 @@
 
   pTxtObj->SetPosition(point.x, point.y);
   pTxtObj->SetText(text);
-  pPageObjs->GetPageObjectList()->InsertObject(
-      pPageObjs->GetPageObjectList()->GetTailPosition(), pTxtObj);
 
-  return pTxtObj;
+  CPDF_TextObject* pRet = pTxtObj.get();
+  pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj));
+  return pRet;
 }
 
 void IFX_Edit::GeneratePageObjects(
-    CPDF_PageObjectHolder* pPageObjects,
+    CPDF_PageObjectHolder* pObjectHolder,
     IFX_Edit* pEdit,
     const CPDF_Point& ptOffset,
     const CPVT_WordRange* pRange,
@@ -504,7 +502,7 @@
               nOldFontIndex != word.nFontIndex) {
             if (sTextBuf.GetLength() > 0) {
               ObjArray.Add(AddTextObjToPageObjects(
-                  pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex),
+                  pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
                   fFontSize, 0.0f, 100,
                   CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
                   sTextBuf.GetByteString()));
@@ -523,7 +521,7 @@
 
       if (sTextBuf.GetLength() > 0) {
         ObjArray.Add(AddTextObjToPageObjects(
-            pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex),
+            pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
             fFontSize, 0.0f, 100,
             CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
             sTextBuf.GetByteString()));
@@ -533,7 +531,7 @@
 }
 
 void IFX_Edit::GenerateRichPageObjects(
-    CPDF_PageObjectHolder* pPageObjects,
+    CPDF_PageObjectHolder* pObjectHolder,
     IFX_Edit* pEdit,
     const CPDF_Point& ptOffset,
     const CPVT_WordRange* pRange,
@@ -574,7 +572,7 @@
               crOld != crCurText) {
             if (sTextBuf.GetLength() > 0) {
               ObjArray.Add(AddTextObjToPageObjects(
-                  pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
+                  pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
                   wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
                   CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
                   sTextBuf.GetByteString()));
@@ -597,7 +595,7 @@
             rcUnderline.top += ptOffset.y;
             rcUnderline.bottom += ptOffset.y;
 
-            AddRectToPageObjects(pPageObjects, crCurText, rcUnderline);
+            AddRectToPageObjects(pObjectHolder, crCurText, rcUnderline);
           }
 
           if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) {
@@ -607,7 +605,7 @@
             rcCrossout.top += ptOffset.y;
             rcCrossout.bottom += ptOffset.y;
 
-            AddRectToPageObjects(pPageObjects, crCurText, rcCrossout);
+            AddRectToPageObjects(pObjectHolder, crCurText, rcCrossout);
           }
 
           oldplace = place;
@@ -616,7 +614,7 @@
 
       if (sTextBuf.GetLength() > 0) {
         ObjArray.Add(AddTextObjToPageObjects(
-            pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
+            pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
             wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
             CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
             sTextBuf.GetByteString()));
@@ -625,7 +623,7 @@
   }
 }
 
-void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjectHolder* pPageObjects,
+void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjectHolder* pObjectHolder,
                                         IFX_Edit* pEdit,
                                         const CPDF_Point& ptOffset,
                                         const CPVT_WordRange* pRange,
@@ -651,7 +649,7 @@
           rcUnderline.right += ptOffset.x;
           rcUnderline.top += ptOffset.y;
           rcUnderline.bottom += ptOffset.y;
-          AddRectToPageObjects(pPageObjects, color, rcUnderline);
+          AddRectToPageObjects(pObjectHolder, color, rcUnderline);
         }
       }
     }
diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp
index c2638d0..733384a 100644
--- a/fpdfsdk/src/javascript/Document.cpp
+++ b/fpdfsdk/src/javascript/Document.cpp
@@ -1382,20 +1382,15 @@
 
   int nWords = 0;
   CFX_WideString swRet;
-  FX_POSITION pos = page.GetPageObjectList()->GetHeadPosition();
-  while (pos) {
-    if (CPDF_PageObject* pPageObj =
-            page.GetPageObjectList()->GetNextObject(pos)) {
-      if (pPageObj->m_Type == CPDF_PageObject::TEXT) {
-        int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
-
-        if (nWords + nObjWords >= nWordNo) {
-          swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
-          break;
-        }
-
-        nWords += nObjWords;
+  for (auto& pPageObj : *page.GetPageObjectList()) {
+    if (pPageObj->m_Type == CPDF_PageObject::TEXT) {
+      CPDF_TextObject* pTextObj = static_cast<CPDF_TextObject*>(pPageObj.get());
+      int nObjWords = CountWords(pTextObj);
+      if (nWords + nObjWords >= nWordNo) {
+        swRet = GetObjWordStr(pTextObj, nWordNo - nWords);
+        break;
       }
+      nWords += nObjWords;
     }
   }
 
@@ -1442,15 +1437,9 @@
   page.ParseContent(nullptr);
 
   int nWords = 0;
-  FX_POSITION pos = page.GetPageObjectList()->GetHeadPosition();
-  while (pos) {
-    if (CPDF_PageObject* pPageObj =
-            page.GetPageObjectList()->GetNextObject(pos)) {
-      if (pPageObj->m_Type == CPDF_PageObject::TEXT) {
-        CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
-        nWords += CountWords(pTextObj);
-      }
-    }
+  for (auto& pPageObj : *page.GetPageObjectList()) {
+    if (pPageObj->m_Type == CPDF_PageObject::TEXT)
+      nWords += CountWords(static_cast<CPDF_TextObject*>(pPageObj.get()));
   }
 
   vRet = nWords;
diff --git a/fpdfsdk/src/pdfwindow/PWL_Edit.cpp b/fpdfsdk/src/pdfwindow/PWL_Edit.cpp
index 4b3886a..ce9274a 100644
--- a/fpdfsdk/src/pdfwindow/PWL_Edit.cpp
+++ b/fpdfsdk/src/pdfwindow/PWL_Edit.cpp
@@ -1166,20 +1166,20 @@
 }
 
 void CPWL_Edit::GeneratePageObjects(
-    CPDF_PageObjectHolder* pPageObjects,
+    CPDF_PageObjectHolder* pObjectHolder,
     const CPDF_Point& ptOffset,
     CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
   IFX_Edit::GeneratePageObjects(
-      pPageObjects, m_pEdit, ptOffset, NULL,
+      pObjectHolder, m_pEdit, ptOffset, NULL,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
       ObjArray);
 }
 
-void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pPageObjects,
+void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                                     const CPDF_Point& ptOffset) {
   CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
   IFX_Edit::GeneratePageObjects(
-      pPageObjects, m_pEdit, ptOffset, NULL,
+      pObjectHolder, m_pEdit, ptOffset, NULL,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
       ObjArray);
 }