Fix CPLW_Wnd ownership model in CFFL_FormFiller.

CFFL_FormFiller::DestroyPDFWindow() might get re-entered, so
do not leave any dangling references in maps. Use unique_ptr
to be more sure that we have it right.

Bug: chromium:898531
Change-Id: I7b61940ff4e88c8a7e3219fefb0479f33bbbfae1
Reviewed-on: https://pdfium-review.googlesource.com/c/44542
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
index 4308c1a..ac55125 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.cpp
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
@@ -6,11 +6,14 @@
 
 #include "fpdfsdk/formfiller/cffl_checkbox.h"
 
+#include <utility>
+
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/pwl/cpwl_special_button.h"
 #include "public/fpdf_fwlevent.h"
+#include "third_party/base/ptr_util.h"
 
 CFFL_CheckBox::CFFL_CheckBox(CPDFSDK_FormFillEnvironment* pApp,
                              CPDFSDK_Widget* pWidget)
@@ -18,11 +21,12 @@
 
 CFFL_CheckBox::~CFFL_CheckBox() {}
 
-CPWL_Wnd* CFFL_CheckBox::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_CheckBox();
+std::unique_ptr<CPWL_Wnd> CFFL_CheckBox::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_CheckBox>();
   pWnd->Create(cp);
   pWnd->SetCheck(m_pWidget->IsChecked());
-  return pWnd;
+  return std::move(pWnd);
 }
 
 bool CFFL_CheckBox::OnKeyDown(CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/formfiller/cffl_checkbox.h b/fpdfsdk/formfiller/cffl_checkbox.h
index b477fe7..2eae222 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.h
+++ b/fpdfsdk/formfiller/cffl_checkbox.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_CHECKBOX_H_
 #define FPDFSDK_FORMFILLER_CFFL_CHECKBOX_H_
 
+#include <memory>
+
 #include "fpdfsdk/formfiller/cffl_button.h"
 
 class CPWL_CheckBox;
@@ -17,7 +19,8 @@
   ~CFFL_CheckBox() override;
 
   // CFFL_Button:
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
   bool OnKeyDown(CPDFSDK_Annot* pAnnot,
                  uint32_t nKeyCode,
                  uint32_t nFlags) override;
diff --git a/fpdfsdk/formfiller/cffl_combobox.cpp b/fpdfsdk/formfiller/cffl_combobox.cpp
index 830e647..69cc66b 100644
--- a/fpdfsdk/formfiller/cffl_combobox.cpp
+++ b/fpdfsdk/formfiller/cffl_combobox.cpp
@@ -6,12 +6,15 @@
 
 #include "fpdfsdk/formfiller/cffl_combobox.h"
 
+#include <utility>
+
 #include "fpdfsdk/cpdfsdk_common.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
 #include "fpdfsdk/pwl/cpwl_combo_box.h"
+#include "third_party/base/ptr_util.h"
 
 CFFL_ComboBox::CFFL_ComboBox(CPDFSDK_FormFillEnvironment* pApp,
                              CPDFSDK_Widget* pWidget)
@@ -41,8 +44,9 @@
   return cp;
 }
 
-CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_ComboBox();
+std::unique_ptr<CPWL_Wnd> CFFL_ComboBox::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_ComboBox>();
   pWnd->AttachFFLData(this);
   pWnd->Create(cp);
 
@@ -57,13 +61,12 @@
   else
     swText = m_pWidget->GetOptionLabel(nCurSel);
 
-  for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
+  for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++)
     pWnd->AddString(m_pWidget->GetOptionLabel(i));
-  }
 
   pWnd->SetSelect(nCurSel);
   pWnd->SetText(swText);
-  return pWnd;
+  return std::move(pWnd);
 }
 
 bool CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/formfiller/cffl_combobox.h b/fpdfsdk/formfiller/cffl_combobox.h
index 2769b53..4ec5a9e 100644
--- a/fpdfsdk/formfiller/cffl_combobox.h
+++ b/fpdfsdk/formfiller/cffl_combobox.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_COMBOBOX_H_
 #define FPDFSDK_FORMFILLER_CFFL_COMBOBOX_H_
 
+#include <memory>
+
 #include "core/fxcrt/fx_string.h"
 #include "fpdfsdk/formfiller/cffl_textobject.h"
 
@@ -27,7 +29,8 @@
 
   // CFFL_TextObject:
   CPWL_Wnd::CreateParams GetCreateParam() override;
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
index 94d80ca..8e9d0c7 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -18,7 +18,7 @@
 
 CFFL_FormFiller::CFFL_FormFiller(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                                  CPDFSDK_Widget* pWidget)
-    : m_pFormFillEnv(pFormFillEnv), m_pWidget(pWidget), m_bValid(false) {
+    : m_pFormFillEnv(pFormFillEnv), m_pWidget(pWidget) {
   ASSERT(m_pFormFillEnv);
 }
 
@@ -27,15 +27,17 @@
 }
 
 void CFFL_FormFiller::DestroyWindows() {
-  for (const auto& it : m_Maps) {
-    CPWL_Wnd* pWnd = it.second;
-    auto* pData = static_cast<CFFL_PrivateData*>(pWnd->GetAttachedData());
-    pWnd->InvalidateProvider(this);
-    pWnd->Destroy();
-    delete pWnd;
-    delete pData;
+  while (!m_Maps.empty()) {
+    std::unique_ptr<CFFL_PrivateData> pData;
+    {
+      auto it = m_Maps.begin();
+      std::unique_ptr<CPWL_Wnd> pWnd = std::move(it->second);
+      pData.reset(static_cast<CFFL_PrivateData*>(pWnd->GetAttachedData()));
+      m_Maps.erase(it);
+      pWnd->InvalidateProvider(this);
+      pWnd->Destroy();
+    }
   }
-  m_Maps.clear();
 }
 
 FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
@@ -380,28 +382,28 @@
 CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
                                         bool bNew) {
   ASSERT(pPageView);
-
   auto it = m_Maps.find(pPageView);
-  const bool found = it != m_Maps.end();
-  CPWL_Wnd* pWnd = found ? it->second : nullptr;
-  if (!bNew)
-    return pWnd;
+  if (it == m_Maps.end()) {
+    if (!bNew)
+      return nullptr;
 
-  if (!found) {
     CPWL_Wnd::CreateParams cp = GetCreateParam();
     cp.pAttachedWidget.Reset(m_pWidget.Get());
 
-    auto* pPrivateData = new CFFL_PrivateData;
+    auto pPrivateData = pdfium::MakeUnique<CFFL_PrivateData>();
     pPrivateData->pWidget = m_pWidget.Get();
     pPrivateData->pPageView = pPageView;
     pPrivateData->nWidgetAppearanceAge = m_pWidget->GetAppearanceAge();
     pPrivateData->nWidgetValueAge = 0;
-    cp.pAttachedData = pPrivateData;
-    CPWL_Wnd* pNewWnd = NewPDFWindow(cp);
-    m_Maps[pPageView] = pNewWnd;
-    return pNewWnd;
+    cp.pAttachedData = pPrivateData.release();
+    m_Maps[pPageView] = NewPDFWindow(cp);
+    return m_Maps[pPageView].get();
   }
 
+  CPWL_Wnd* pWnd = it->second.get();
+  if (!bNew)
+    return pWnd;
+
   auto* pPrivateData = static_cast<CFFL_PrivateData*>(pWnd->GetAttachedData());
   if (pPrivateData->nWidgetAppearanceAge == m_pWidget->GetAppearanceAge())
     return pWnd;
@@ -415,12 +417,13 @@
   if (it == m_Maps.end())
     return;
 
-  CPWL_Wnd* pWnd = it->second;
-  auto* pData = static_cast<CFFL_PrivateData*>(pWnd->GetAttachedData());
-  pWnd->Destroy();
-  delete pWnd;
-  delete pData;
-  m_Maps.erase(it);
+  std::unique_ptr<CFFL_PrivateData> pData;
+  {
+    std::unique_ptr<CPWL_Wnd> pWnd = std::move(it->second);
+    m_Maps.erase(it);
+    pData.reset(static_cast<CFFL_PrivateData*>(pWnd->GetAttachedData()));
+    pWnd->Destroy();
+  }
 }
 
 CFX_Matrix CFFL_FormFiller::GetWindowMatrix(CPWL_Wnd::PrivateData* pAttached) {
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
index 95f5ac8..a6f7cdc 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -8,6 +8,7 @@
 #define FPDFSDK_FORMFILLER_CFFL_FORMFILLER_H_
 
 #include <map>
+#include <memory>
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "fpdfsdk/cpdfsdk_fieldaction.h"
@@ -104,19 +105,20 @@
                                    const CPDFSDK_FieldAction& faOld,
                                    const CPDFSDK_FieldAction& faNew);
 
-  virtual void SaveState(CPDFSDK_PageView* pPageView);
-  virtual void RestoreState(CPDFSDK_PageView* pPageView);
-
+  virtual CPWL_Wnd::CreateParams GetCreateParam();
+  virtual std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) = 0;
   virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
                                    bool bRestoreValue);
+  virtual void SaveState(CPDFSDK_PageView* pPageView);
+  virtual void RestoreState(CPDFSDK_PageView* pPageView);
+  virtual CFX_FloatRect GetFocusBox(CPDFSDK_PageView* pPageView);
 
   CFX_Matrix GetCurMatrix();
-
   CFX_FloatRect FFLtoPWL(const CFX_FloatRect& rect);
   CFX_FloatRect PWLtoFFL(const CFX_FloatRect& rect);
   CFX_PointF FFLtoPWL(const CFX_PointF& point);
   CFX_PointF PWLtoFFL(const CFX_PointF& point);
-
   CFX_PointF WndtoPWL(CPDFSDK_PageView* pPageView, const CFX_PointF& pt);
   CFX_FloatRect FFLtoWnd(CPDFSDK_PageView* pPageView,
                          const CFX_FloatRect& rect);
@@ -133,9 +135,6 @@
   void DestroyPDFWindow(CPDFSDK_PageView* pPageView);
   void EscapeFiller(CPDFSDK_PageView* pPageView, bool bDestroyPDFWindow);
 
-  virtual CPWL_Wnd::CreateParams GetCreateParam();
-  virtual CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) = 0;
-  virtual CFX_FloatRect GetFocusBox(CPDFSDK_PageView* pPageView);
 
   bool IsValid() const;
   CFX_FloatRect GetPDFWindowRect() const;
@@ -146,8 +145,6 @@
   CPDFSDK_Annot* GetSDKAnnot() const { return m_pWidget.Get(); }
 
  protected:
-  using CFFL_PageView2PDFWindow = std::map<CPDFSDK_PageView*, CPWL_Wnd*>;
-
   // If the inheriting widget has its own fontmap and a PWL_Edit widget that
   // access that fontmap then you have to call DestroyWindows before destroying
   // the font map in order to not get a use-after-free.
@@ -158,10 +155,10 @@
 
   void InvalidateRect(const FX_RECT& rect);
 
+  bool m_bValid = false;
   UnownedPtr<CPDFSDK_FormFillEnvironment> const m_pFormFillEnv;
   UnownedPtr<CPDFSDK_Widget> m_pWidget;
-  bool m_bValid;
-  CFFL_PageView2PDFWindow m_Maps;
+  std::map<CPDFSDK_PageView*, std::unique_ptr<CPWL_Wnd>> m_Maps;
 };
 
 #endif  // FPDFSDK_FORMFILLER_CFFL_FORMFILLER_H_
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index 3ca95a8..3c74875 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -6,12 +6,15 @@
 
 #include "fpdfsdk/formfiller/cffl_listbox.h"
 
+#include <utility>
+
 #include "fpdfsdk/cpdfsdk_common.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
 #include "fpdfsdk/pwl/cpwl_list_box.h"
+#include "third_party/base/ptr_util.h"
 
 #define FFL_DEFAULTLISTBOXFONTSIZE 12.0f
 
@@ -36,8 +39,9 @@
   return cp;
 }
 
-CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_ListBox();
+std::unique_ptr<CPWL_Wnd> CFFL_ListBox::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_ListBox>();
   pWnd->AttachFFLData(this);
   pWnd->Create(cp);
   pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller());
@@ -69,8 +73,7 @@
   }
 
   pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
-
-  return pWnd;
+  return std::move(pWnd);
 }
 
 bool CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/formfiller/cffl_listbox.h b/fpdfsdk/formfiller/cffl_listbox.h
index eda9561..eed542f 100644
--- a/fpdfsdk/formfiller/cffl_listbox.h
+++ b/fpdfsdk/formfiller/cffl_listbox.h
@@ -7,6 +7,7 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_
 #define FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_
 
+#include <memory>
 #include <set>
 #include <vector>
 
@@ -21,7 +22,8 @@
 
   // CFFL_TextObject:
   CPWL_Wnd::CreateParams GetCreateParam() override;
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.cpp b/fpdfsdk/formfiller/cffl_pushbutton.cpp
index 7310da6..b57c911 100644
--- a/fpdfsdk/formfiller/cffl_pushbutton.cpp
+++ b/fpdfsdk/formfiller/cffl_pushbutton.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/formfiller/cffl_pushbutton.h"
 
+#include <utility>
+
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/pwl/cpwl_special_button.h"
 
@@ -15,8 +17,9 @@
 
 CFFL_PushButton::~CFFL_PushButton() {}
 
-CPWL_Wnd* CFFL_PushButton::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_PushButton();
+std::unique_ptr<CPWL_Wnd> CFFL_PushButton::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_PushButton>();
   pWnd->Create(cp);
-  return pWnd;
+  return std::move(pWnd);
 }
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.h b/fpdfsdk/formfiller/cffl_pushbutton.h
index e2acfdc..cc2ff89 100644
--- a/fpdfsdk/formfiller/cffl_pushbutton.h
+++ b/fpdfsdk/formfiller/cffl_pushbutton.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
 #define FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
 
+#include <memory>
+
 #include "fpdfsdk/formfiller/cffl_button.h"
 
 class CFFL_PushButton final : public CFFL_Button {
@@ -15,7 +17,8 @@
   ~CFFL_PushButton() override;
 
   // CFFL_Button:
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
 };
 
 #endif  // FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.cpp b/fpdfsdk/formfiller/cffl_radiobutton.cpp
index 8105b0c..6ce4a0a 100644
--- a/fpdfsdk/formfiller/cffl_radiobutton.cpp
+++ b/fpdfsdk/formfiller/cffl_radiobutton.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/formfiller/cffl_radiobutton.h"
 
+#include <utility>
+
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
@@ -18,11 +20,12 @@
 
 CFFL_RadioButton::~CFFL_RadioButton() {}
 
-CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_RadioButton();
+std::unique_ptr<CPWL_Wnd> CFFL_RadioButton::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_RadioButton>();
   pWnd->Create(cp);
   pWnd->SetCheck(m_pWidget->IsChecked());
-  return pWnd;
+  return std::move(pWnd);
 }
 
 bool CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.h b/fpdfsdk/formfiller/cffl_radiobutton.h
index 3c20be6..4702a27 100644
--- a/fpdfsdk/formfiller/cffl_radiobutton.h
+++ b/fpdfsdk/formfiller/cffl_radiobutton.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_RADIOBUTTON_H_
 #define FPDFSDK_FORMFILLER_CFFL_RADIOBUTTON_H_
 
+#include <memory>
+
 #include "fpdfsdk/formfiller/cffl_button.h"
 
 class CPWL_RadioButton;
@@ -17,7 +19,8 @@
   ~CFFL_RadioButton() override;
 
   // CFFL_Button:
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
   bool OnKeyDown(CPDFSDK_Annot* pAnnot,
                  uint32_t nKeyCode,
                  uint32_t nFlags) override;
diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
index 65f28fe..ae3cb06 100644
--- a/fpdfsdk/formfiller/cffl_textfield.cpp
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
@@ -6,10 +6,13 @@
 
 #include "fpdfsdk/formfiller/cffl_textfield.h"
 
+#include <utility>
+
 #include "fpdfsdk/cpdfsdk_common.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "third_party/base/ptr_util.h"
 
 CFFL_TextField::CFFL_TextField(CPDFSDK_FormFillEnvironment* pApp,
                                CPDFSDK_Widget* pWidget)
@@ -66,15 +69,15 @@
   return cp;
 }
 
-CPWL_Wnd* CFFL_TextField::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
-  auto* pWnd = new CPWL_Edit();
+std::unique_ptr<CPWL_Wnd> CFFL_TextField::NewPDFWindow(
+    const CPWL_Wnd::CreateParams& cp) {
+  auto pWnd = pdfium::MakeUnique<CPWL_Edit>();
   pWnd->AttachFFLData(this);
   pWnd->Create(cp);
   pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller());
 
   int32_t nMaxLen = m_pWidget->GetMaxLen();
   WideString swValue = m_pWidget->GetValue();
-
   if (nMaxLen > 0) {
     if (pWnd->HasFlag(PES_CHARARRAY)) {
       pWnd->SetCharArray(nMaxLen);
@@ -83,9 +86,8 @@
       pWnd->SetLimitChar(nMaxLen);
     }
   }
-
   pWnd->SetText(swValue);
-  return pWnd;
+  return std::move(pWnd);
 }
 
 bool CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/formfiller/cffl_textfield.h b/fpdfsdk/formfiller/cffl_textfield.h
index a1e48b6..3be0095 100644
--- a/fpdfsdk/formfiller/cffl_textfield.h
+++ b/fpdfsdk/formfiller/cffl_textfield.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_FORMFILLER_CFFL_TEXTFIELD_H_
 #define FPDFSDK_FORMFILLER_CFFL_TEXTFIELD_H_
 
+#include <memory>
+
 #include "fpdfsdk/formfiller/cffl_textobject.h"
 
 #define BF_ALIGN_LEFT 0
@@ -32,7 +34,8 @@
 
   // CFFL_TextObject:
   CPWL_Wnd::CreateParams GetCreateParam() override;
-  CPWL_Wnd* NewPDFWindow(const CPWL_Wnd::CreateParams& cp) override;
+  std::unique_ptr<CPWL_Wnd> NewPDFWindow(
+      const CPWL_Wnd::CreateParams& cp) override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;