Make CXFA_NodeHelper::GetIndex() a member of CXFA_Node. Do the same for GetSiblings(). Also move CFXJSE_Engine::GetIndexByName() and CFXJSE_Engine::GetIndexByClassName() in CXFA_Node. Change-Id: Ia5e1c686f64160dc3b67d57486c37bb6ad9f8bac Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52376 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp index b5c7a78..8c20211 100644 --- a/fxjs/xfa/cfxjse_engine.cpp +++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -757,18 +757,6 @@ return pValue; } -size_t CFXJSE_Engine::GetIndexByName(CXFA_Node* refNode) { - if (!refNode) - return 0; - return CXFA_NodeHelper::GetIndex(refNode, refNode->IsProperty(), false); -} - -size_t CFXJSE_Engine::GetIndexByClassName(CXFA_Node* refNode) { - if (!refNode) - return 0; - return CXFA_NodeHelper::GetIndex(refNode, refNode->IsProperty(), true); -} - void CFXJSE_Engine::SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray) { m_pScriptNodeArray = pArray; }
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h index cacf09f..d96eaee 100644 --- a/fxjs/xfa/cfxjse_engine.h +++ b/fxjs/xfa/cfxjse_engine.h
@@ -84,9 +84,6 @@ void AddToCacheList(std::unique_ptr<CXFA_List> pList); CXFA_Object* GetThisObject() const { return m_pThisObject.Get(); } - size_t GetIndexByName(CXFA_Node* refNode); - size_t GetIndexByClassName(CXFA_Node* refNode); - void SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray); void AddNodesOfRunScript(CXFA_Node* pNode); CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass.Get(); }
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp index 9829a2b..a9b9634 100644 --- a/fxjs/xfa/cfxjse_resolveprocessor.cpp +++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -126,7 +126,7 @@ WideStringView wsName = rnd.m_wsName.AsStringView(); WideString wsCondition = rnd.m_wsCondition; const bool bClassName = !wsName.IsEmpty() && wsName[0] == '#'; - CXFA_Node* pChild = + CXFA_Node* const pChild = bClassName ? pParent->GetOneChildOfClass(wsName.Right(wsName.GetLength() - 1)) : pParent->GetOneChildNamed(wsName); @@ -142,8 +142,7 @@ for (const auto& pObject : rnd.m_Objects) nodes.push_back(pObject->AsNode()); - std::vector<CXFA_Node*> siblings = - CXFA_NodeHelper::GetSiblings(pChild, bClassName); + std::vector<CXFA_Node*> siblings = pChild->GetSiblings(bClassName); nodes.insert(nodes.end(), siblings.begin(), siblings.end()); rnd.m_Objects = std::vector<UnownedPtr<CXFA_Object>>(nodes.begin(), nodes.end()); @@ -333,9 +332,11 @@ if (!(dwStyles & XFA_RESOLVENODE_ALL)) { std::vector<CXFA_Node*> upArrayNodes; if (curNode->IsTransparent()) { - upArrayNodes = CXFA_NodeHelper::GetSiblings( - ToNode(rnd.m_Objects.front().Get()), - !!(dwStyles & XFA_RESOLVENODE_TagName)); + CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get()); + if (pCurrent) { + upArrayNodes = + pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName)); + } } if (upArrayNodes.size() > rnd.m_Objects.size()) { CXFA_Object* pSaveObject = rnd.m_Objects.front().Get(); @@ -465,9 +466,12 @@ } if (rnd.m_Objects.size() > nNum) { if (parentNode->IsTransparent()) { - std::vector<CXFA_Node*> upArrayNodes = CXFA_NodeHelper::GetSiblings( - ToNode(rnd.m_Objects.front().Get()), - !!(dwStyles & XFA_RESOLVENODE_TagName)); + std::vector<CXFA_Node*> upArrayNodes; + CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get()); + if (pCurrent) { + upArrayNodes = + pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName)); + } if (upArrayNodes.size() > rnd.m_Objects.size()) { CXFA_Object* pSaveObject = rnd.m_Objects.front().Get(); rnd.m_Objects = std::vector<UnownedPtr<CXFA_Object>>( @@ -651,12 +655,12 @@ size_t iCurIndex = 0; const std::vector<CXFA_Node*>* pArray = pRnd->m_pSC->GetUpObjectArray(); if (!pArray->empty()) { - CXFA_Node* curNode = pArray->back(); - bool bIsProperty = curNode->IsProperty(); + CXFA_Node* pNode = pArray->back(); + bool bIsProperty = pNode->IsProperty(); bool bIsClassIndex = - curNode->IsUnnamed() || - (bIsProperty && curNode->GetElementType() != XFA_Element::PageSet); - iCurIndex = CXFA_NodeHelper::GetIndex(curNode, bIsProperty, bIsClassIndex); + pNode->IsUnnamed() || + (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet); + iCurIndex = pNode->GetIndex(bIsProperty, bIsClassIndex); } size_t iFoundCount = pRnd->m_Objects.size();
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp index 62ce3f4..c036ab9 100644 --- a/fxjs/xfa/cjx_tree.cpp +++ b/fxjs/xfa/cjx_tree.cpp
@@ -167,9 +167,9 @@ return; } - CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - pValue->SetInteger(pdfium::base::checked_cast<int32_t>( - pScriptContext->GetIndexByName(ToNode(GetXFAObject())))); + CXFA_Node* pNode = ToNode(GetXFAObject()); + size_t iIndex = pNode ? pNode->GetIndexByName() : 0; + pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex)); } void CJX_Tree::classIndex(CFXJSE_Value* pValue, @@ -180,9 +180,9 @@ return; } - CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - pValue->SetInteger(pdfium::base::checked_cast<int32_t>( - pScriptContext->GetIndexByClassName(ToNode(GetXFAObject())))); + CXFA_Node* pNode = ToNode(GetXFAObject()); + size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0; + pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex)); } void CJX_Tree::somExpression(CFXJSE_Value* pValue,
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index 1e636bf..9f19a49 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -218,7 +218,6 @@ #include "xfa/fxfa/parser/cxfa_msgid.h" #include "xfa/fxfa/parser/cxfa_nameattr.h" #include "xfa/fxfa/parser/cxfa_neverembed.h" -#include "xfa/fxfa/parser/cxfa_nodehelper.h" #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h" #include "xfa/fxfa/parser/cxfa_numberofcopies.h" #include "xfa/fxfa/parser/cxfa_numberpattern.h" @@ -767,9 +766,59 @@ ws.Replace(L".", L"\\."); } - return WideString::Format( - pszFormat, ws.c_str(), - CXFA_NodeHelper::GetIndex(pNode, bIsProperty, bIsClassIndex)); + return WideString::Format(pszFormat, ws.c_str(), + pNode->GetIndex(bIsProperty, bIsClassIndex)); +} + +void TraverseSiblings(CXFA_Node* parent, + uint32_t dwNameHash, + std::vector<CXFA_Node*>* pSiblings, + bool bIsClassName, + bool bIsFindProperty) { + ASSERT(parent); + ASSERT(pSiblings); + + if (bIsFindProperty) { + for (CXFA_Node* child : + parent->GetNodeList(XFA_NODEFILTER_Properties, XFA_Element::Unknown)) { + if (bIsClassName) { + if (child->GetClassHashCode() == dwNameHash) + pSiblings->push_back(child); + } else { + if (child->GetNameHash() == dwNameHash) { + if (child->GetElementType() != XFA_Element::PageSet && + child->GetElementType() != XFA_Element::Extras && + child->GetElementType() != XFA_Element::Items) { + pSiblings->push_back(child); + } + } + } + if (child->IsUnnamed() && + child->GetElementType() == XFA_Element::PageSet) { + TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false); + } + } + if (!pSiblings->empty()) + return; + } + for (CXFA_Node* child : + parent->GetNodeList(XFA_NODEFILTER_Children, XFA_Element::Unknown)) { + if (child->GetElementType() == XFA_Element::Variables) + continue; + + if (bIsClassName) { + if (child->GetClassHashCode() == dwNameHash) + pSiblings->push_back(child); + } else { + if (child->GetNameHash() == dwNameHash) + pSiblings->push_back(child); + } + + if (child->IsTransparent() && + child->GetElementType() != XFA_Element::PageSet) { + TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false); + } + } } } // namespace @@ -1664,6 +1713,50 @@ return FindFirstSiblingOfClass(this, element); } +std::vector<CXFA_Node*> CXFA_Node::GetSiblings(bool bIsClassName) { + std::vector<CXFA_Node*> siblings; + CXFA_Node* parent = GetParent(); + if (!parent) + return siblings; + if (!parent->HasProperty(GetElementType())) { + parent = GetTransparentParent(); + if (!parent) + return siblings; + } + + uint32_t dwNameHash = bIsClassName ? GetClassHashCode() : GetNameHash(); + TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true); + return siblings; +} + +size_t CXFA_Node::GetIndex(bool bIsProperty, bool bIsClassIndex) { + CXFA_Node* parent = GetParent(); + if (!parent) + return 0; + + if (!bIsProperty) { + parent = GetTransparentParent(); + if (!parent) + return 0; + } + uint32_t dwHashName = bIsClassIndex ? GetClassHashCode() : GetNameHash(); + std::vector<CXFA_Node*> siblings; + TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true); + for (size_t i = 0; i < siblings.size(); ++i) { + if (siblings[i] == this) + return i; + } + return 0; +} + +size_t CXFA_Node::GetIndexByName() { + return GetIndex(IsProperty(), /*bIsClassIndex=*/false); +} + +size_t CXFA_Node::GetIndexByClassName() { + return GetIndex(IsProperty(), /*bIsClassIndex=*/true); +} + CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() { CXFA_Node* pInstanceMgr = nullptr; if (m_ePacket == XFA_PacketType::Form) { @@ -5067,6 +5160,19 @@ } } +CXFA_Node* CXFA_Node::GetTransparentParent() { + CXFA_Node* parent = GetParent(); + while (parent) { + XFA_Element type = parent->GetElementType(); + if (type == XFA_Element::Variables || + (type != XFA_Element::SubformSet && !parent->IsUnnamed())) { + return parent; + } + parent = parent->GetParent(); + } + return nullptr; +} + // static std::unique_ptr<CXFA_Node> CXFA_Node::Create(CXFA_Document* doc, XFA_Element element,
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h index 106050f..e962fe9 100644 --- a/xfa/fxfa/parser/cxfa_node.h +++ b/xfa/fxfa/parser/cxfa_node.h
@@ -218,6 +218,11 @@ CXFA_Node* GetOneChildNamed(WideStringView wsName); CXFA_Node* GetOneChildOfClass(WideStringView wsClass); + std::vector<CXFA_Node*> GetSiblings(bool bIsClassName); + size_t GetIndex(bool bIsProperty, bool bIsClassIndex); + size_t GetIndexByName(); + size_t GetIndexByClassName(); + CXFA_Node* GetInstanceMgrOfSubform(); Optional<bool> GetDefaultBoolean(XFA_Attribute attr) const; @@ -467,6 +472,7 @@ Optional<XFA_AttributeValue> GetIntactFromKeep( const CXFA_Keep* pKeep, XFA_AttributeValue eLayoutType) const; + CXFA_Node* GetTransparentParent(); Optional<float> TryHeight(); Optional<float> TryMinWidth();
diff --git a/xfa/fxfa/parser/cxfa_nodehelper.cpp b/xfa/fxfa/parser/cxfa_nodehelper.cpp index 9d76d54..7d65e0d 100644 --- a/xfa/fxfa/parser/cxfa_nodehelper.cpp +++ b/xfa/fxfa/parser/cxfa_nodehelper.cpp
@@ -18,121 +18,10 @@ #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" #include "xfa/fxfa/parser/xfa_utils.h" -namespace { - -void TraverseSiblings(CXFA_Node* parent, - uint32_t dwNameHash, - std::vector<CXFA_Node*>* pSiblings, - bool bIsClassName, - bool bIsFindProperty) { - ASSERT(parent); - ASSERT(pSiblings); - - if (bIsFindProperty) { - for (CXFA_Node* child : - parent->GetNodeList(XFA_NODEFILTER_Properties, XFA_Element::Unknown)) { - if (bIsClassName) { - if (child->GetClassHashCode() == dwNameHash) - pSiblings->push_back(child); - } else { - if (child->GetNameHash() == dwNameHash) { - if (child->GetElementType() != XFA_Element::PageSet && - child->GetElementType() != XFA_Element::Extras && - child->GetElementType() != XFA_Element::Items) { - pSiblings->push_back(child); - } - } - } - if (child->IsUnnamed() && - child->GetElementType() == XFA_Element::PageSet) { - TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false); - } - } - if (!pSiblings->empty()) - return; - } - for (CXFA_Node* child : - parent->GetNodeList(XFA_NODEFILTER_Children, XFA_Element::Unknown)) { - if (child->GetElementType() == XFA_Element::Variables) - continue; - - if (bIsClassName) { - if (child->GetClassHashCode() == dwNameHash) - pSiblings->push_back(child); - } else { - if (child->GetNameHash() == dwNameHash) - pSiblings->push_back(child); - } - - if (child->IsTransparent() && - child->GetElementType() != XFA_Element::PageSet) { - TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false); - } - } -} - -CXFA_Node* GetTransparentParent(CXFA_Node* pNode) { - CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr; - while (parent) { - XFA_Element type = parent->GetElementType(); - if (type == XFA_Element::Variables || - (type != XFA_Element::SubformSet && !parent->IsUnnamed())) { - return parent; - } - parent = parent->GetParent(); - } - return nullptr; -} - -} // namespace - CXFA_NodeHelper::CXFA_NodeHelper() = default; CXFA_NodeHelper::~CXFA_NodeHelper() = default; -// static -std::vector<CXFA_Node*> CXFA_NodeHelper::GetSiblings(CXFA_Node* pNode, - bool bIsClassName) { - std::vector<CXFA_Node*> siblings; - CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr; - if (!parent) - return siblings; - if (!parent->HasProperty(pNode->GetElementType())) { - parent = GetTransparentParent(pNode); - if (!parent) - return siblings; - } - - uint32_t dwNameHash = - bIsClassName ? pNode->GetClassHashCode() : pNode->GetNameHash(); - TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true); - return siblings; -} - -// static -size_t CXFA_NodeHelper::GetIndex(CXFA_Node* pNode, - bool bIsProperty, - bool bIsClassIndex) { - CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr; - if (!parent) - return 0; - - if (!bIsProperty) { - parent = GetTransparentParent(pNode); - if (!parent) - return 0; - } - uint32_t dwHashName = - bIsClassIndex ? pNode->GetClassHashCode() : pNode->GetNameHash(); - std::vector<CXFA_Node*> siblings; - TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true); - for (size_t i = 0; i < siblings.size(); ++i) { - if (siblings[i] == pNode) - return i; - } - return 0; -} - bool CXFA_NodeHelper::CreateNodeForCondition(const WideString& wsCondition) { size_t szLen = wsCondition.GetLength(); WideString wsIndex(L"0");
diff --git a/xfa/fxfa/parser/cxfa_nodehelper.h b/xfa/fxfa/parser/cxfa_nodehelper.h index fca64cf..66e7e66 100644 --- a/xfa/fxfa/parser/cxfa_nodehelper.h +++ b/xfa/fxfa/parser/cxfa_nodehelper.h
@@ -21,12 +21,6 @@ CXFA_NodeHelper(); ~CXFA_NodeHelper(); - static std::vector<CXFA_Node*> GetSiblings(CXFA_Node* pNode, - bool bIsClassName); - static size_t GetIndex(CXFA_Node* pNode, - bool bIsProperty, - bool bIsClassIndex); - bool CreateNode(const WideString& wsName, const WideString& wsCondition, bool bLastNode,