Cleanup memory in CFDE_CSSStyleSelector

This CL fixes up the bare new calls in CFDE_CSSStyleSelector and replaces
them with unique_ptrs. Code massaged to work correclty with new types.

Change-Id: I90fce1ed7486da97fe7b5e597e9d423748c069c0
Reviewed-on: https://pdfium-review.googlesource.com/2353
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fde/css/cfde_cssstyleselector.cpp b/xfa/fde/css/cfde_cssstyleselector.cpp
index 1b4aa0e..e09f79c 100644
--- a/xfa/fde/css/cfde_cssstyleselector.cpp
+++ b/xfa/fde/css/cfde_cssstyleselector.cpp
@@ -73,44 +73,26 @@
   m_UARules.AddRulesFrom(m_UAStyles.get(), m_pFontMgr);
 }
 
-int32_t CFDE_CSSStyleSelector::MatchDeclarations(
-    CXFA_CSSTagProvider* pTag,
-    CFX_ArrayTemplate<CFDE_CSSDeclaration*>& matchedDecls) {
+std::vector<const CFDE_CSSDeclaration*>
+CFDE_CSSStyleSelector::MatchDeclarations(CXFA_CSSTagProvider* pTag) {
   ASSERT(pTag);
 
   CFDE_CSSTagCache* pCache = m_pAccelerator->top();
   ASSERT(pCache && pCache->GetTag() == pTag);
 
-  matchedDecls.RemoveAt(0, matchedDecls.GetSize());
+  std::vector<const CFDE_CSSDeclaration*> matchedDecls;
+  if (m_UARules.CountSelectors() == 0 || !pCache->HashTag())
+    return matchedDecls;
 
-  if (m_UARules.CountSelectors() == 0)
-    return 0;
+  auto rules = m_UARules.GetTagRuleData(pCache->HashTag());
+  if (!rules)
+    return matchedDecls;
 
-  // The ::Data is owned by the m_RuleCollection.
-  std::vector<CFDE_CSSRuleCollection::Data*> matchedRules;
-
-  if (pCache->HashTag()) {
-    MatchRules(&matchedRules, pCache,
-               m_UARules.GetTagRuleData(pCache->HashTag()));
-  }
-
-  for (const auto& rule : matchedRules)
-    matchedDecls.Add(rule->pDeclaration);
-
-  return matchedDecls.GetSize();
-}
-
-void CFDE_CSSStyleSelector::MatchRules(
-    std::vector<CFDE_CSSRuleCollection::Data*>* matchedRules,
-    CFDE_CSSTagCache* pCache,
-    const std::vector<std::unique_ptr<CFDE_CSSRuleCollection::Data>>* pList) {
-  if (!pList)
-    return;
-
-  for (const auto& d : *pList) {
+  for (const auto& d : *rules) {
     if (MatchSelector(pCache, d->pSelector))
-      matchedRules->push_back(d.get());
+      matchedDecls.push_back(d->pDeclaration);
   }
+  return matchedDecls;
 }
 
 bool CFDE_CSSStyleSelector::MatchSelector(CFDE_CSSTagCache* pCache,
@@ -143,29 +125,27 @@
 
 void CFDE_CSSStyleSelector::ComputeStyle(
     CXFA_CSSTagProvider* pTag,
-    const CFDE_CSSDeclaration** ppDeclArray,
-    int32_t iDeclCount,
+    const std::vector<const CFDE_CSSDeclaration*>& declArray,
     CFDE_CSSComputedStyle* pDestStyle) {
-  ASSERT(iDeclCount >= 0);
   ASSERT(pDestStyle);
 
   static const uint32_t s_dwStyleHash = FX_HashCode_GetW(L"style", true);
   static const uint32_t s_dwAlignHash = FX_HashCode_GetW(L"align", true);
 
   if (!pTag->empty()) {
-    CFDE_CSSDeclaration* pDecl = nullptr;
+    std::unique_ptr<CFDE_CSSDeclaration> pDecl;
     for (auto it : *pTag) {
       CFX_WideString wsAttri = it.first;
       CFX_WideString wsValue = it.second;
       uint32_t dwAttriHash = FX_HashCode_GetW(wsAttri.AsStringC(), true);
       if (dwAttriHash == s_dwStyleHash) {
         if (!pDecl)
-          pDecl = new CFDE_CSSDeclaration;
+          pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();
 
-        AppendInlineStyle(pDecl, wsValue.c_str(), wsValue.GetLength());
+        AppendInlineStyle(pDecl.get(), wsValue.c_str(), wsValue.GetLength());
       } else if (dwAttriHash == s_dwAlignHash) {
         if (!pDecl)
-          pDecl = new CFDE_CSSDeclaration;
+          pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();
 
         FDE_CSSPropertyArgs args;
         args.pStringCache = nullptr;
@@ -175,89 +155,53 @@
     }
 
     if (pDecl) {
-      CFX_ArrayTemplate<CFDE_CSSDeclaration*> decls;
-      decls.SetSize(iDeclCount + 1);
-      CFDE_CSSDeclaration** ppInline = decls.GetData();
-      FXSYS_memcpy(ppInline, ppDeclArray,
-                   iDeclCount * sizeof(CFDE_CSSDeclaration*));
-      ppInline[iDeclCount++] = pDecl;
-      ApplyDeclarations(true, const_cast<const CFDE_CSSDeclaration**>(ppInline),
-                        iDeclCount, pDestStyle);
-      ApplyDeclarations(false,
-                        const_cast<const CFDE_CSSDeclaration**>(ppInline),
-                        iDeclCount, pDestStyle);
+      ApplyDeclarations(declArray, pDecl.get(), pDestStyle);
       return;
     }
   }
 
-  if (iDeclCount > 0) {
-    ASSERT(ppDeclArray);
+  if (declArray.empty())
+    return;
 
-    ApplyDeclarations(true, ppDeclArray, iDeclCount, pDestStyle);
-    ApplyDeclarations(false, ppDeclArray, iDeclCount, pDestStyle);
-  }
+  ApplyDeclarations(declArray, nullptr, pDestStyle);
 }
 
 void CFDE_CSSStyleSelector::ApplyDeclarations(
-    bool bPriority,
-    const CFDE_CSSDeclaration** ppDeclArray,
-    int32_t iDeclCount,
+    const std::vector<const CFDE_CSSDeclaration*>& declArray,
+    const CFDE_CSSDeclaration* extraDecl,
     CFDE_CSSComputedStyle* pDestStyle) {
   CFDE_CSSComputedStyle* pComputedStyle = pDestStyle;
 
-  int32_t i;
-  if (bPriority) {
-    CFDE_CSSValue* pLastest = nullptr;
-    CFDE_CSSValue* pImportant = nullptr;
-    for (i = 0; i < iDeclCount; ++i) {
-      bool bImportant;
-      CFDE_CSSValue* pVal =
-          ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant);
-      if (!pVal)
-        continue;
+  std::vector<const CFDE_CSSPropertyHolder*> importants;
+  std::vector<const CFDE_CSSPropertyHolder*> normals;
+  std::vector<const CFDE_CSSCustomProperty*> customs;
 
-      if (bImportant)
-        pImportant = pVal;
-      else
-        pLastest = pVal;
-    }
-    if (pImportant) {
-      ApplyProperty(FDE_CSSProperty::FontSize, pImportant, pComputedStyle);
-    } else if (pLastest) {
-      ApplyProperty(FDE_CSSProperty::FontSize, pLastest, pComputedStyle);
-    }
-  } else {
-    CFX_ArrayTemplate<CFDE_CSSDeclaration*> importants;
-    const CFDE_CSSDeclaration* pDecl = nullptr;
+  for (auto& decl : declArray)
+    ExtractValues(decl, &importants, &normals, &customs);
+  if (extraDecl)
+    ExtractValues(extraDecl, &importants, &normals, &customs);
 
-    for (i = 0; i < iDeclCount; ++i) {
-      pDecl = ppDeclArray[i];
-      for (auto it = pDecl->begin(); it != pDecl->end(); it++) {
-        if ((*it)->eProperty == FDE_CSSProperty::FontSize)
-          continue;
-        if (!(*it)->bImportant) {
-          ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle);
-        } else if (importants.GetSize() == 0 ||
-                   importants[importants.GetUpperBound()] != pDecl) {
-          importants.Add(const_cast<CFDE_CSSDeclaration*>(pDecl));
-        }
-      }
-    }
+  for (auto& prop : normals)
+    ApplyProperty(prop->eProperty, prop->pValue.Get(), pComputedStyle);
+  for (auto& prop : customs)
+    pComputedStyle->AddCustomStyle(prop->pwsName, prop->pwsValue);
+  for (auto& prop : importants)
+    ApplyProperty(prop->eProperty, prop->pValue.Get(), pComputedStyle);
+}
 
-    iDeclCount = importants.GetSize();
-    for (i = 0; i < iDeclCount; ++i) {
-      pDecl = importants[i];
-
-      for (auto it = pDecl->begin(); it != pDecl->end(); it++) {
-        if ((*it)->bImportant && (*it)->eProperty != FDE_CSSProperty::FontSize)
-          ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle);
-      }
-    }
-
-    for (auto it = pDecl->custom_begin(); it != pDecl->custom_end(); it++) {
-      pComputedStyle->AddCustomStyle((*it)->pwsName, (*it)->pwsValue);
-    }
+void CFDE_CSSStyleSelector::ExtractValues(
+    const CFDE_CSSDeclaration* decl,
+    std::vector<const CFDE_CSSPropertyHolder*>* importants,
+    std::vector<const CFDE_CSSPropertyHolder*>* normals,
+    std::vector<const CFDE_CSSCustomProperty*>* custom) {
+  for (const auto& holder : *decl) {
+    if (holder->bImportant)
+      importants->push_back(holder.get());
+    else
+      normals->push_back(holder.get());
   }
+  for (auto it = decl->custom_begin(); it != decl->custom_end(); it++)
+    custom->push_back(it->get());
 }
 
 void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
diff --git a/xfa/fde/css/cfde_cssstyleselector.h b/xfa/fde/css/cfde_cssstyleselector.h
index c2262d7..15bce93 100644
--- a/xfa/fde/css/cfde_cssstyleselector.h
+++ b/xfa/fde/css/cfde_cssstyleselector.h
@@ -17,7 +17,9 @@
 
 class CFDE_CSSAccelerator;
 class CFDE_CSSComputedStyle;
+class CFDE_CSSCustomProperty;
 class CFDE_CSSDeclaration;
+class CFDE_CSSPropertyHolder;
 class CFDE_CSSSelector;
 class CFDE_CSSStyleSheet;
 class CFDE_CSSTagCache;
@@ -31,38 +33,38 @@
   explicit CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr);
   ~CFDE_CSSStyleSelector();
 
-  void SetDefFontSize(FX_FLOAT fFontSize);
-
-  void SetUAStyleSheet(std::unique_ptr<CFDE_CSSStyleSheet> pSheet);
-
-  void UpdateStyleIndex();
   CFDE_CSSAccelerator* InitAccelerator();
+
+  void SetDefFontSize(FX_FLOAT fFontSize);
+  void SetUAStyleSheet(std::unique_ptr<CFDE_CSSStyleSheet> pSheet);
+  void UpdateStyleIndex();
+
   CFX_RetainPtr<CFDE_CSSComputedStyle> CreateComputedStyle(
       CFDE_CSSComputedStyle* pParentStyle);
-  int32_t MatchDeclarations(
-      CXFA_CSSTagProvider* pTag,
-      CFX_ArrayTemplate<CFDE_CSSDeclaration*>& matchedDecls);
   void ComputeStyle(CXFA_CSSTagProvider* pTag,
-                    const CFDE_CSSDeclaration** ppDeclArray,
-                    int32_t iDeclCount,
+                    const std::vector<const CFDE_CSSDeclaration*>& declArray,
                     CFDE_CSSComputedStyle* pDestStyle);
 
+  std::vector<const CFDE_CSSDeclaration*> MatchDeclarations(
+      CXFA_CSSTagProvider* pTag);
+
  private:
-  void MatchRules(
-      std::vector<CFDE_CSSRuleCollection::Data*>* matchedRules,
-      CFDE_CSSTagCache* pCache,
-      const std::vector<std::unique_ptr<CFDE_CSSRuleCollection::Data>>* pList);
   bool MatchSelector(CFDE_CSSTagCache* pCache, CFDE_CSSSelector* pSel);
+
   void AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
                          const FX_WCHAR* psz,
                          int32_t iLen);
-  void ApplyDeclarations(bool bPriority,
-                         const CFDE_CSSDeclaration** ppDeclArray,
-                         int32_t iDeclCount,
-                         CFDE_CSSComputedStyle* pDestStyle);
+  void ApplyDeclarations(
+      const std::vector<const CFDE_CSSDeclaration*>& declArray,
+      const CFDE_CSSDeclaration* extraDecl,
+      CFDE_CSSComputedStyle* pDestStyle);
   void ApplyProperty(FDE_CSSProperty eProperty,
                      CFDE_CSSValue* pValue,
                      CFDE_CSSComputedStyle* pComputedStyle);
+  void ExtractValues(const CFDE_CSSDeclaration* decl,
+                     std::vector<const CFDE_CSSPropertyHolder*>* importants,
+                     std::vector<const CFDE_CSSPropertyHolder*>* normals,
+                     std::vector<const CFDE_CSSCustomProperty*>* custom);
 
   bool SetLengthWithPercent(FDE_CSSLength& width,
                             FDE_CSSPrimitiveType eType,
diff --git a/xfa/fxfa/app/cxfa_textparsecontext.cpp b/xfa/fxfa/app/cxfa_textparsecontext.cpp
index e4beb1f..851d844 100644
--- a/xfa/fxfa/app/cxfa_textparsecontext.cpp
+++ b/xfa/fxfa/app/cxfa_textparsecontext.cpp
@@ -12,21 +12,6 @@
 
 CXFA_TextParseContext::CXFA_TextParseContext()
     : m_pParentStyle(nullptr),
-      m_ppMatchedDecls(nullptr),
-      m_dwMatchedDecls(0),
       m_eDisplay(FDE_CSSDisplay::None) {}
 
-CXFA_TextParseContext::~CXFA_TextParseContext() {
-  FX_Free(m_ppMatchedDecls);
-}
-
-void CXFA_TextParseContext::SetDecls(const CFDE_CSSDeclaration** ppDeclArray,
-                                     int32_t iDeclCount) {
-  if (iDeclCount <= 0 || !ppDeclArray)
-    return;
-
-  m_dwMatchedDecls = iDeclCount;
-  m_ppMatchedDecls = FX_Alloc(CFDE_CSSDeclaration*, iDeclCount);
-  FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
-               iDeclCount * sizeof(CFDE_CSSDeclaration*));
-}
+CXFA_TextParseContext::~CXFA_TextParseContext() {}
diff --git a/xfa/fxfa/app/cxfa_textparsecontext.h b/xfa/fxfa/app/cxfa_textparsecontext.h
index d13f35b..5ea68e9 100644
--- a/xfa/fxfa/app/cxfa_textparsecontext.h
+++ b/xfa/fxfa/app/cxfa_textparsecontext.h
@@ -7,9 +7,13 @@
 #ifndef XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_
 #define XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_
 
+#include <utility>
+#include <vector>
+
+#include "third_party/base/stl_util.h"
+#include "xfa/fde/css/cfde_cssdeclaration.h"
 #include "xfa/fde/css/fde_css.h"
 
-class CFDE_CSSDeclaration;
 class CFDE_CSSComputedStyle;
 
 class CXFA_TextParseContext {
@@ -20,17 +24,15 @@
   void SetDisplay(FDE_CSSDisplay eDisplay) { m_eDisplay = eDisplay; }
   FDE_CSSDisplay GetDisplay() const { return m_eDisplay; }
 
-  void SetDecls(const CFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount);
-  const CFDE_CSSDeclaration** GetDecls() {
-    return const_cast<const CFDE_CSSDeclaration**>(m_ppMatchedDecls);
+  void SetDecls(std::vector<const CFDE_CSSDeclaration*>&& decl) {
+    decls_ = std::move(decl);
   }
-  uint32_t CountDecls() const { return m_dwMatchedDecls; }
+  const std::vector<const CFDE_CSSDeclaration*>& GetDecls() { return decls_; }
 
   CFX_RetainPtr<CFDE_CSSComputedStyle> m_pParentStyle;
 
  protected:
-  CFDE_CSSDeclaration** m_ppMatchedDecls;
-  uint32_t m_dwMatchedDecls;
+  std::vector<const CFDE_CSSDeclaration*> decls_;
   FDE_CSSDisplay m_eDisplay;
 };
 
diff --git a/xfa/fxfa/app/cxfa_textparser.cpp b/xfa/fxfa/app/cxfa_textparser.cpp
index 9bf033f..2a724cc 100644
--- a/xfa/fxfa/app/cxfa_textparser.cpp
+++ b/xfa/fxfa/app/cxfa_textparser.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <utility>
+#include <vector>
 
 #include "third_party/base/ptr_util.h"
 #include "xfa/fde/css/cfde_cssaccelerator.h"
@@ -205,8 +206,8 @@
   auto pStyle = CreateStyle(pParentStyle);
   CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
   pCSSAccel->OnEnterTag(&tagProvider);
-  m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(),
-                            pContext->CountDecls(), pStyle.Get());
+
+  m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(), pStyle.Get());
   pCSSAccel->OnLeaveTag(&tagProvider);
   return pStyle;
 }
@@ -241,16 +242,13 @@
       pNewStyle = CreateStyle(pParentStyle);
       CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
       pCSSAccel->OnEnterTag(&tagProvider);
-      CFX_ArrayTemplate<CFDE_CSSDeclaration*> DeclArray;
-      int32_t iMatchedDecls =
-          m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
-      const CFDE_CSSDeclaration** ppMatchDecls =
-          const_cast<const CFDE_CSSDeclaration**>(DeclArray.GetData());
-      m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls,
-                                pNewStyle.Get());
+
+      auto declArray = m_pSelector->MatchDeclarations(&tagProvider);
+      m_pSelector->ComputeStyle(&tagProvider, declArray, pNewStyle.Get());
+
       pCSSAccel->OnLeaveTag(&tagProvider);
-      if (iMatchedDecls > 0)
-        pTextContext->SetDecls(ppMatchDecls, iMatchedDecls);
+      if (!declArray.empty())
+        pTextContext->SetDecls(std::move(declArray));
 
       eDisplay = pNewStyle->GetDisplay();
     }