xref: /aosp_15_r20/external/pdfium/fxjs/xfa/cfxjse_resolveprocessor.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_resolveprocessor.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
10*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
11*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
12*3ac0a46fSAndroid Build Coastguard Worker 
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_extension.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_engine.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_nodehelper.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_value.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cjx_object.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check_op.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_localemgr.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_object.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_occur.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_utils.h"
27*3ac0a46fSAndroid Build Coastguard Worker 
CFXJSE_ResolveProcessor(CFXJSE_Engine * pEngine,CFXJSE_NodeHelper * pHelper)28*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_ResolveProcessor::CFXJSE_ResolveProcessor(CFXJSE_Engine* pEngine,
29*3ac0a46fSAndroid Build Coastguard Worker                                                  CFXJSE_NodeHelper* pHelper)
30*3ac0a46fSAndroid Build Coastguard Worker     : m_pEngine(pEngine), m_pNodeHelper(pHelper) {}
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_ResolveProcessor::~CFXJSE_ResolveProcessor() = default;
33*3ac0a46fSAndroid Build Coastguard Worker 
Resolve(v8::Isolate * pIsolate,NodeData & rnd)34*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::Resolve(v8::Isolate* pIsolate, NodeData& rnd) {
35*3ac0a46fSAndroid Build Coastguard Worker   if (!rnd.m_CurObject)
36*3ac0a46fSAndroid Build Coastguard Worker     return false;
37*3ac0a46fSAndroid Build Coastguard Worker 
38*3ac0a46fSAndroid Build Coastguard Worker   if (!rnd.m_CurObject->IsNode()) {
39*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) {
40*3ac0a46fSAndroid Build Coastguard Worker       return ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
41*3ac0a46fSAndroid Build Coastguard Worker                                    rnd.m_wsName.AsStringView());
42*3ac0a46fSAndroid Build Coastguard Worker     }
43*3ac0a46fSAndroid Build Coastguard Worker     return false;
44*3ac0a46fSAndroid Build Coastguard Worker   }
45*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_dwStyles & XFA_ResolveFlag::kAnyChild)
46*3ac0a46fSAndroid Build Coastguard Worker     return ResolveAnyChild(pIsolate, rnd);
47*3ac0a46fSAndroid Build Coastguard Worker 
48*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_wsName.GetLength()) {
49*3ac0a46fSAndroid Build Coastguard Worker     wchar_t wch = rnd.m_wsName[0];
50*3ac0a46fSAndroid Build Coastguard Worker     switch (wch) {
51*3ac0a46fSAndroid Build Coastguard Worker       case '$':
52*3ac0a46fSAndroid Build Coastguard Worker         return ResolveDollar(pIsolate, rnd);
53*3ac0a46fSAndroid Build Coastguard Worker       case '!':
54*3ac0a46fSAndroid Build Coastguard Worker         return ResolveExcalmatory(pIsolate, rnd);
55*3ac0a46fSAndroid Build Coastguard Worker       case '#':
56*3ac0a46fSAndroid Build Coastguard Worker         return ResolveNumberSign(pIsolate, rnd);
57*3ac0a46fSAndroid Build Coastguard Worker       case '*':
58*3ac0a46fSAndroid Build Coastguard Worker         return ResolveAsterisk(rnd);
59*3ac0a46fSAndroid Build Coastguard Worker       // TODO(dsinclair): We could probably remove this.
60*3ac0a46fSAndroid Build Coastguard Worker       case '.':
61*3ac0a46fSAndroid Build Coastguard Worker         return ResolveAnyChild(pIsolate, rnd);
62*3ac0a46fSAndroid Build Coastguard Worker       default:
63*3ac0a46fSAndroid Build Coastguard Worker         break;
64*3ac0a46fSAndroid Build Coastguard Worker     }
65*3ac0a46fSAndroid Build Coastguard Worker   }
66*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
67*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(m_pEngine->GetThisObject());
68*3ac0a46fSAndroid Build Coastguard Worker     return true;
69*3ac0a46fSAndroid Build Coastguard Worker   }
70*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_CurObject->GetElementType() == XFA_Element::Xfa) {
71*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Object* pObjNode =
72*3ac0a46fSAndroid Build Coastguard Worker         m_pEngine->GetDocument()->GetXFAObject(rnd.m_uHashName);
73*3ac0a46fSAndroid Build Coastguard Worker     if (pObjNode) {
74*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(pObjNode);
75*3ac0a46fSAndroid Build Coastguard Worker     } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
76*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
77*3ac0a46fSAndroid Build Coastguard Worker     } else if ((rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) &&
78*3ac0a46fSAndroid Build Coastguard Worker                ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
79*3ac0a46fSAndroid Build Coastguard Worker                                      rnd.m_wsName.AsStringView())) {
80*3ac0a46fSAndroid Build Coastguard Worker       return true;
81*3ac0a46fSAndroid Build Coastguard Worker     }
82*3ac0a46fSAndroid Build Coastguard Worker     if (!rnd.m_Result.objects.empty())
83*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, rnd.m_wsCondition, &rnd);
84*3ac0a46fSAndroid Build Coastguard Worker 
85*3ac0a46fSAndroid Build Coastguard Worker     return !rnd.m_Result.objects.empty();
86*3ac0a46fSAndroid Build Coastguard Worker   }
87*3ac0a46fSAndroid Build Coastguard Worker   if (!ResolveNormal(pIsolate, rnd) && rnd.m_uHashName == XFA_HASHCODE_Xfa)
88*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(m_pEngine->GetDocument()->GetRoot());
89*3ac0a46fSAndroid Build Coastguard Worker 
90*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
91*3ac0a46fSAndroid Build Coastguard Worker }
92*3ac0a46fSAndroid Build Coastguard Worker 
ResolveAnyChild(v8::Isolate * pIsolate,NodeData & rnd)93*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveAnyChild(v8::Isolate* pIsolate,
94*3ac0a46fSAndroid Build Coastguard Worker                                               NodeData& rnd) {
95*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pParent = ToNode(rnd.m_CurObject);
96*3ac0a46fSAndroid Build Coastguard Worker   if (!pParent)
97*3ac0a46fSAndroid Build Coastguard Worker     return false;
98*3ac0a46fSAndroid Build Coastguard Worker 
99*3ac0a46fSAndroid Build Coastguard Worker   WideStringView wsName = rnd.m_wsName.AsStringView();
100*3ac0a46fSAndroid Build Coastguard Worker   WideString wsCondition = rnd.m_wsCondition;
101*3ac0a46fSAndroid Build Coastguard Worker   const bool bClassName = !wsName.IsEmpty() && wsName[0] == '#';
102*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* const pChild =
103*3ac0a46fSAndroid Build Coastguard Worker       bClassName
104*3ac0a46fSAndroid Build Coastguard Worker           ? pParent->GetOneChildOfClass(wsName.Last(wsName.GetLength() - 1))
105*3ac0a46fSAndroid Build Coastguard Worker           : pParent->GetOneChildNamed(wsName);
106*3ac0a46fSAndroid Build Coastguard Worker   if (!pChild)
107*3ac0a46fSAndroid Build Coastguard Worker     return false;
108*3ac0a46fSAndroid Build Coastguard Worker 
109*3ac0a46fSAndroid Build Coastguard Worker   if (wsCondition.IsEmpty()) {
110*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(pChild);
111*3ac0a46fSAndroid Build Coastguard Worker     return true;
112*3ac0a46fSAndroid Build Coastguard Worker   }
113*3ac0a46fSAndroid Build Coastguard Worker 
114*3ac0a46fSAndroid Build Coastguard Worker   std::vector<CXFA_Node*> nodes;
115*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& pObject : rnd.m_Result.objects)
116*3ac0a46fSAndroid Build Coastguard Worker     nodes.push_back(pObject->AsNode());
117*3ac0a46fSAndroid Build Coastguard Worker 
118*3ac0a46fSAndroid Build Coastguard Worker   std::vector<CXFA_Node*> siblings = pChild->GetSiblings(bClassName);
119*3ac0a46fSAndroid Build Coastguard Worker   nodes.insert(nodes.end(), siblings.begin(), siblings.end());
120*3ac0a46fSAndroid Build Coastguard Worker   rnd.m_Result.objects =
121*3ac0a46fSAndroid Build Coastguard Worker       std::vector<cppgc::Member<CXFA_Object>>(nodes.begin(), nodes.end());
122*3ac0a46fSAndroid Build Coastguard Worker   FilterCondition(pIsolate, wsCondition, &rnd);
123*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
124*3ac0a46fSAndroid Build Coastguard Worker }
125*3ac0a46fSAndroid Build Coastguard Worker 
ResolveDollar(v8::Isolate * pIsolate,NodeData & rnd)126*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveDollar(v8::Isolate* pIsolate,
127*3ac0a46fSAndroid Build Coastguard Worker                                             NodeData& rnd) {
128*3ac0a46fSAndroid Build Coastguard Worker   WideString wsName = rnd.m_wsName;
129*3ac0a46fSAndroid Build Coastguard Worker   WideString wsCondition = rnd.m_wsCondition;
130*3ac0a46fSAndroid Build Coastguard Worker   size_t nNameLen = wsName.GetLength();
131*3ac0a46fSAndroid Build Coastguard Worker   if (nNameLen == 1) {
132*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
133*3ac0a46fSAndroid Build Coastguard Worker     return true;
134*3ac0a46fSAndroid Build Coastguard Worker   }
135*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_nLevel > 0)
136*3ac0a46fSAndroid Build Coastguard Worker     return false;
137*3ac0a46fSAndroid Build Coastguard Worker 
138*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Document* pDocument = m_pEngine->GetDocument();
139*3ac0a46fSAndroid Build Coastguard Worker   XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(
140*3ac0a46fSAndroid Build Coastguard Worker       FX_HashCode_GetW(wsName.AsStringView().Last(nNameLen - 1)));
141*3ac0a46fSAndroid Build Coastguard Worker   if (dwNameHash == XFA_HASHCODE_Xfa) {
142*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(pDocument->GetRoot());
143*3ac0a46fSAndroid Build Coastguard Worker   } else {
144*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Object* pObjNode = pDocument->GetXFAObject(dwNameHash);
145*3ac0a46fSAndroid Build Coastguard Worker     if (pObjNode)
146*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(pObjNode);
147*3ac0a46fSAndroid Build Coastguard Worker   }
148*3ac0a46fSAndroid Build Coastguard Worker   if (!rnd.m_Result.objects.empty())
149*3ac0a46fSAndroid Build Coastguard Worker     FilterCondition(pIsolate, wsCondition, &rnd);
150*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
151*3ac0a46fSAndroid Build Coastguard Worker }
152*3ac0a46fSAndroid Build Coastguard Worker 
ResolveExcalmatory(v8::Isolate * pIsolate,NodeData & rnd)153*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveExcalmatory(v8::Isolate* pIsolate,
154*3ac0a46fSAndroid Build Coastguard Worker                                                  NodeData& rnd) {
155*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_nLevel > 0)
156*3ac0a46fSAndroid Build Coastguard Worker     return false;
157*3ac0a46fSAndroid Build Coastguard Worker 
158*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* datasets =
159*3ac0a46fSAndroid Build Coastguard Worker       ToNode(m_pEngine->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
160*3ac0a46fSAndroid Build Coastguard Worker   if (!datasets)
161*3ac0a46fSAndroid Build Coastguard Worker     return false;
162*3ac0a46fSAndroid Build Coastguard Worker 
163*3ac0a46fSAndroid Build Coastguard Worker   NodeData rndFind;
164*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_CurObject = datasets;
165*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
166*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_uHashName = static_cast<XFA_HashCode>(
167*3ac0a46fSAndroid Build Coastguard Worker       FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
168*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_nLevel = rnd.m_nLevel + 1;
169*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_dwStyles = XFA_ResolveFlag::kChildren;
170*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsCondition = rnd.m_wsCondition;
171*3ac0a46fSAndroid Build Coastguard Worker   Resolve(pIsolate, rndFind);
172*3ac0a46fSAndroid Build Coastguard Worker 
173*3ac0a46fSAndroid Build Coastguard Worker   rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
174*3ac0a46fSAndroid Build Coastguard Worker                               rndFind.m_Result.objects.begin(),
175*3ac0a46fSAndroid Build Coastguard Worker                               rndFind.m_Result.objects.end());
176*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
177*3ac0a46fSAndroid Build Coastguard Worker }
178*3ac0a46fSAndroid Build Coastguard Worker 
ResolveNumberSign(v8::Isolate * pIsolate,NodeData & rnd)179*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveNumberSign(v8::Isolate* pIsolate,
180*3ac0a46fSAndroid Build Coastguard Worker                                                 NodeData& rnd) {
181*3ac0a46fSAndroid Build Coastguard Worker   WideString wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
182*3ac0a46fSAndroid Build Coastguard Worker   WideString wsCondition = rnd.m_wsCondition;
183*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* curNode = ToNode(rnd.m_CurObject);
184*3ac0a46fSAndroid Build Coastguard Worker   if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
185*3ac0a46fSAndroid Build Coastguard Worker     return true;
186*3ac0a46fSAndroid Build Coastguard Worker 
187*3ac0a46fSAndroid Build Coastguard Worker   NodeData rndFind;
188*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_nLevel = rnd.m_nLevel + 1;
189*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_dwStyles = rnd.m_dwStyles;
190*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_dwStyles |= XFA_ResolveFlag::kTagName;
191*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_dwStyles.Clear(XFA_ResolveFlag::kAttributes);
192*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsName = std::move(wsName);
193*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_uHashName = static_cast<XFA_HashCode>(
194*3ac0a46fSAndroid Build Coastguard Worker       FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
195*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsCondition = wsCondition;
196*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_CurObject = curNode;
197*3ac0a46fSAndroid Build Coastguard Worker   ResolveNormal(pIsolate, rndFind);
198*3ac0a46fSAndroid Build Coastguard Worker   if (rndFind.m_Result.objects.empty())
199*3ac0a46fSAndroid Build Coastguard Worker     return false;
200*3ac0a46fSAndroid Build Coastguard Worker 
201*3ac0a46fSAndroid Build Coastguard Worker   if (wsCondition.IsEmpty() &&
202*3ac0a46fSAndroid Build Coastguard Worker       pdfium::Contains(rndFind.m_Result.objects, curNode)) {
203*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.emplace_back(curNode);
204*3ac0a46fSAndroid Build Coastguard Worker   } else {
205*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
206*3ac0a46fSAndroid Build Coastguard Worker                                 rndFind.m_Result.objects.begin(),
207*3ac0a46fSAndroid Build Coastguard Worker                                 rndFind.m_Result.objects.end());
208*3ac0a46fSAndroid Build Coastguard Worker   }
209*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
210*3ac0a46fSAndroid Build Coastguard Worker }
211*3ac0a46fSAndroid Build Coastguard Worker 
ResolveForAttributeRs(CXFA_Object * curNode,CFXJSE_Engine::ResolveResult * rnd,WideStringView strAttr)212*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveForAttributeRs(
213*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Object* curNode,
214*3ac0a46fSAndroid Build Coastguard Worker     CFXJSE_Engine::ResolveResult* rnd,
215*3ac0a46fSAndroid Build Coastguard Worker     WideStringView strAttr) {
216*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<XFA_SCRIPTATTRIBUTEINFO> info =
217*3ac0a46fSAndroid Build Coastguard Worker       XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr);
218*3ac0a46fSAndroid Build Coastguard Worker   if (!info.has_value())
219*3ac0a46fSAndroid Build Coastguard Worker     return false;
220*3ac0a46fSAndroid Build Coastguard Worker 
221*3ac0a46fSAndroid Build Coastguard Worker   rnd->type = CFXJSE_Engine::ResolveResult::Type::kAttribute;
222*3ac0a46fSAndroid Build Coastguard Worker   rnd->script_attribute = info.value();
223*3ac0a46fSAndroid Build Coastguard Worker   rnd->objects.emplace_back(curNode);
224*3ac0a46fSAndroid Build Coastguard Worker   return true;
225*3ac0a46fSAndroid Build Coastguard Worker }
226*3ac0a46fSAndroid Build Coastguard Worker 
ResolveNormal(v8::Isolate * pIsolate,NodeData & rnd)227*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveNormal(v8::Isolate* pIsolate,
228*3ac0a46fSAndroid Build Coastguard Worker                                             NodeData& rnd) {
229*3ac0a46fSAndroid Build Coastguard Worker   if (rnd.m_nLevel > 32 || !rnd.m_CurObject->IsNode())
230*3ac0a46fSAndroid Build Coastguard Worker     return false;
231*3ac0a46fSAndroid Build Coastguard Worker 
232*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* curNode = rnd.m_CurObject->AsNode();
233*3ac0a46fSAndroid Build Coastguard Worker   size_t nNum = rnd.m_Result.objects.size();
234*3ac0a46fSAndroid Build Coastguard Worker   Mask<XFA_ResolveFlag> dwStyles = rnd.m_dwStyles;
235*3ac0a46fSAndroid Build Coastguard Worker   WideString& wsName = rnd.m_wsName;
236*3ac0a46fSAndroid Build Coastguard Worker   XFA_HashCode uNameHash = rnd.m_uHashName;
237*3ac0a46fSAndroid Build Coastguard Worker   WideString& wsCondition = rnd.m_wsCondition;
238*3ac0a46fSAndroid Build Coastguard Worker 
239*3ac0a46fSAndroid Build Coastguard Worker   NodeData rndFind;
240*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsName = rnd.m_wsName;
241*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_wsCondition = rnd.m_wsCondition;
242*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_nLevel = rnd.m_nLevel + 1;
243*3ac0a46fSAndroid Build Coastguard Worker   rndFind.m_uHashName = uNameHash;
244*3ac0a46fSAndroid Build Coastguard Worker 
245*3ac0a46fSAndroid Build Coastguard Worker   std::vector<CXFA_Node*> children;
246*3ac0a46fSAndroid Build Coastguard Worker   std::vector<CXFA_Node*> properties;
247*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pVariablesNode = nullptr;
248*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pPageSetNode = nullptr;
249*3ac0a46fSAndroid Build Coastguard Worker   for (CXFA_Node* pChild = curNode->GetFirstChild(); pChild;
250*3ac0a46fSAndroid Build Coastguard Worker        pChild = pChild->GetNextSibling()) {
251*3ac0a46fSAndroid Build Coastguard Worker     if (pChild->GetElementType() == XFA_Element::Variables) {
252*3ac0a46fSAndroid Build Coastguard Worker       pVariablesNode = pChild;
253*3ac0a46fSAndroid Build Coastguard Worker       continue;
254*3ac0a46fSAndroid Build Coastguard Worker     }
255*3ac0a46fSAndroid Build Coastguard Worker     if (pChild->GetElementType() == XFA_Element::PageSet) {
256*3ac0a46fSAndroid Build Coastguard Worker       pPageSetNode = pChild;
257*3ac0a46fSAndroid Build Coastguard Worker       continue;
258*3ac0a46fSAndroid Build Coastguard Worker     }
259*3ac0a46fSAndroid Build Coastguard Worker     if (curNode->HasProperty(pChild->GetElementType()))
260*3ac0a46fSAndroid Build Coastguard Worker       properties.push_back(pChild);
261*3ac0a46fSAndroid Build Coastguard Worker     else
262*3ac0a46fSAndroid Build Coastguard Worker       children.push_back(pChild);
263*3ac0a46fSAndroid Build Coastguard Worker   }
264*3ac0a46fSAndroid Build Coastguard Worker   if ((dwStyles & XFA_ResolveFlag::kProperties) && pVariablesNode) {
265*3ac0a46fSAndroid Build Coastguard Worker     if (pVariablesNode->GetClassHashCode() == uNameHash) {
266*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(pVariablesNode);
267*3ac0a46fSAndroid Build Coastguard Worker     } else {
268*3ac0a46fSAndroid Build Coastguard Worker       rndFind.m_CurObject = pVariablesNode;
269*3ac0a46fSAndroid Build Coastguard Worker       SetStylesForChild(dwStyles, rndFind);
270*3ac0a46fSAndroid Build Coastguard Worker       WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
271*3ac0a46fSAndroid Build Coastguard Worker       ResolveNormal(pIsolate, rndFind);
272*3ac0a46fSAndroid Build Coastguard Worker       rndFind.m_wsCondition = std::move(wsSaveCondition);
273*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
274*3ac0a46fSAndroid Build Coastguard Worker                                   rndFind.m_Result.objects.begin(),
275*3ac0a46fSAndroid Build Coastguard Worker                                   rndFind.m_Result.objects.end());
276*3ac0a46fSAndroid Build Coastguard Worker       rndFind.m_Result.objects.clear();
277*3ac0a46fSAndroid Build Coastguard Worker     }
278*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_Result.objects.size() > nNum) {
279*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, wsCondition, &rnd);
280*3ac0a46fSAndroid Build Coastguard Worker       return !rnd.m_Result.objects.empty();
281*3ac0a46fSAndroid Build Coastguard Worker     }
282*3ac0a46fSAndroid Build Coastguard Worker   }
283*3ac0a46fSAndroid Build Coastguard Worker 
284*3ac0a46fSAndroid Build Coastguard Worker   if (dwStyles & XFA_ResolveFlag::kChildren) {
285*3ac0a46fSAndroid Build Coastguard Worker     bool bSetFlag = false;
286*3ac0a46fSAndroid Build Coastguard Worker     if (pPageSetNode && (dwStyles & XFA_ResolveFlag::kProperties))
287*3ac0a46fSAndroid Build Coastguard Worker       children.push_back(pPageSetNode);
288*3ac0a46fSAndroid Build Coastguard Worker 
289*3ac0a46fSAndroid Build Coastguard Worker     for (CXFA_Node* child : children) {
290*3ac0a46fSAndroid Build Coastguard Worker       if (dwStyles & XFA_ResolveFlag::kTagName) {
291*3ac0a46fSAndroid Build Coastguard Worker         if (child->GetClassHashCode() == uNameHash)
292*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects.emplace_back(child);
293*3ac0a46fSAndroid Build Coastguard Worker       } else if (child->GetNameHash() == uNameHash) {
294*3ac0a46fSAndroid Build Coastguard Worker         rnd.m_Result.objects.emplace_back(child);
295*3ac0a46fSAndroid Build Coastguard Worker       }
296*3ac0a46fSAndroid Build Coastguard Worker 
297*3ac0a46fSAndroid Build Coastguard Worker       if (child->GetElementType() != XFA_Element::PageSet &&
298*3ac0a46fSAndroid Build Coastguard Worker           child->IsTransparent()) {
299*3ac0a46fSAndroid Build Coastguard Worker         if (!bSetFlag) {
300*3ac0a46fSAndroid Build Coastguard Worker           SetStylesForChild(dwStyles, rndFind);
301*3ac0a46fSAndroid Build Coastguard Worker           bSetFlag = true;
302*3ac0a46fSAndroid Build Coastguard Worker         }
303*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_CurObject = child;
304*3ac0a46fSAndroid Build Coastguard Worker 
305*3ac0a46fSAndroid Build Coastguard Worker         WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
306*3ac0a46fSAndroid Build Coastguard Worker         ResolveNormal(pIsolate, rndFind);
307*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_wsCondition = std::move(wsSaveCondition);
308*3ac0a46fSAndroid Build Coastguard Worker         rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
309*3ac0a46fSAndroid Build Coastguard Worker                                     rndFind.m_Result.objects.begin(),
310*3ac0a46fSAndroid Build Coastguard Worker                                     rndFind.m_Result.objects.end());
311*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_Result.objects.clear();
312*3ac0a46fSAndroid Build Coastguard Worker       }
313*3ac0a46fSAndroid Build Coastguard Worker     }
314*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_Result.objects.size() > nNum) {
315*3ac0a46fSAndroid Build Coastguard Worker       if (!(dwStyles & XFA_ResolveFlag::kALL)) {
316*3ac0a46fSAndroid Build Coastguard Worker         std::vector<CXFA_Node*> upArrayNodes;
317*3ac0a46fSAndroid Build Coastguard Worker         if (curNode->IsTransparent()) {
318*3ac0a46fSAndroid Build Coastguard Worker           CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
319*3ac0a46fSAndroid Build Coastguard Worker           if (pCurrent) {
320*3ac0a46fSAndroid Build Coastguard Worker             upArrayNodes =
321*3ac0a46fSAndroid Build Coastguard Worker                 pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
322*3ac0a46fSAndroid Build Coastguard Worker           }
323*3ac0a46fSAndroid Build Coastguard Worker         }
324*3ac0a46fSAndroid Build Coastguard Worker         if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
325*3ac0a46fSAndroid Build Coastguard Worker           CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
326*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
327*3ac0a46fSAndroid Build Coastguard Worker               upArrayNodes.begin(), upArrayNodes.end());
328*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects.front() = pSaveObject;
329*3ac0a46fSAndroid Build Coastguard Worker         }
330*3ac0a46fSAndroid Build Coastguard Worker       }
331*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, wsCondition, &rnd);
332*3ac0a46fSAndroid Build Coastguard Worker       return !rnd.m_Result.objects.empty();
333*3ac0a46fSAndroid Build Coastguard Worker     }
334*3ac0a46fSAndroid Build Coastguard Worker   }
335*3ac0a46fSAndroid Build Coastguard Worker   if (dwStyles & XFA_ResolveFlag::kAttributes) {
336*3ac0a46fSAndroid Build Coastguard Worker     if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
337*3ac0a46fSAndroid Build Coastguard Worker       return true;
338*3ac0a46fSAndroid Build Coastguard Worker   }
339*3ac0a46fSAndroid Build Coastguard Worker   if (dwStyles & XFA_ResolveFlag::kProperties) {
340*3ac0a46fSAndroid Build Coastguard Worker     for (CXFA_Node* pChildProperty : properties) {
341*3ac0a46fSAndroid Build Coastguard Worker       if (pChildProperty->IsUnnamed()) {
342*3ac0a46fSAndroid Build Coastguard Worker         if (pChildProperty->GetClassHashCode() == uNameHash)
343*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects.emplace_back(pChildProperty);
344*3ac0a46fSAndroid Build Coastguard Worker         continue;
345*3ac0a46fSAndroid Build Coastguard Worker       }
346*3ac0a46fSAndroid Build Coastguard Worker       if (pChildProperty->GetNameHash() == uNameHash &&
347*3ac0a46fSAndroid Build Coastguard Worker           pChildProperty->GetElementType() != XFA_Element::Extras &&
348*3ac0a46fSAndroid Build Coastguard Worker           pChildProperty->GetElementType() != XFA_Element::Items) {
349*3ac0a46fSAndroid Build Coastguard Worker         rnd.m_Result.objects.emplace_back(pChildProperty);
350*3ac0a46fSAndroid Build Coastguard Worker       }
351*3ac0a46fSAndroid Build Coastguard Worker     }
352*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_Result.objects.size() > nNum) {
353*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, wsCondition, &rnd);
354*3ac0a46fSAndroid Build Coastguard Worker       return !rnd.m_Result.objects.empty();
355*3ac0a46fSAndroid Build Coastguard Worker     }
356*3ac0a46fSAndroid Build Coastguard Worker 
357*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Node* pProp = nullptr;
358*3ac0a46fSAndroid Build Coastguard Worker     if (XFA_Element::Subform == curNode->GetElementType() &&
359*3ac0a46fSAndroid Build Coastguard Worker         XFA_HASHCODE_Occur == uNameHash) {
360*3ac0a46fSAndroid Build Coastguard Worker       CXFA_Node* pInstanceManager = curNode->GetInstanceMgrOfSubform();
361*3ac0a46fSAndroid Build Coastguard Worker       if (pInstanceManager) {
362*3ac0a46fSAndroid Build Coastguard Worker         pProp = pInstanceManager->JSObject()->GetOrCreateProperty<CXFA_Occur>(
363*3ac0a46fSAndroid Build Coastguard Worker             0, XFA_Element::Occur);
364*3ac0a46fSAndroid Build Coastguard Worker       }
365*3ac0a46fSAndroid Build Coastguard Worker     } else {
366*3ac0a46fSAndroid Build Coastguard Worker       XFA_Element eType = XFA_GetElementByName(wsName.AsStringView());
367*3ac0a46fSAndroid Build Coastguard Worker       if (eType == XFA_Element::PageSet) {
368*3ac0a46fSAndroid Build Coastguard Worker         pProp = curNode->JSObject()->GetProperty<CXFA_Node>(0, eType);
369*3ac0a46fSAndroid Build Coastguard Worker       } else if (eType != XFA_Element::Unknown) {
370*3ac0a46fSAndroid Build Coastguard Worker         pProp = curNode->JSObject()->GetOrCreateProperty<CXFA_Node>(0, eType);
371*3ac0a46fSAndroid Build Coastguard Worker       }
372*3ac0a46fSAndroid Build Coastguard Worker     }
373*3ac0a46fSAndroid Build Coastguard Worker     if (pProp) {
374*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(pProp);
375*3ac0a46fSAndroid Build Coastguard Worker       return !rnd.m_Result.objects.empty();
376*3ac0a46fSAndroid Build Coastguard Worker     }
377*3ac0a46fSAndroid Build Coastguard Worker   }
378*3ac0a46fSAndroid Build Coastguard Worker 
379*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* const parentNode = curNode->GetParent();
380*3ac0a46fSAndroid Build Coastguard Worker   uint32_t uCurClassHash = curNode->GetClassHashCode();
381*3ac0a46fSAndroid Build Coastguard Worker   if (!parentNode) {
382*3ac0a46fSAndroid Build Coastguard Worker     if (uCurClassHash == uNameHash) {
383*3ac0a46fSAndroid Build Coastguard Worker       rnd.m_Result.objects.emplace_back(curNode);
384*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, wsCondition, &rnd);
385*3ac0a46fSAndroid Build Coastguard Worker       if (!rnd.m_Result.objects.empty())
386*3ac0a46fSAndroid Build Coastguard Worker         return true;
387*3ac0a46fSAndroid Build Coastguard Worker     }
388*3ac0a46fSAndroid Build Coastguard Worker     return false;
389*3ac0a46fSAndroid Build Coastguard Worker   }
390*3ac0a46fSAndroid Build Coastguard Worker 
391*3ac0a46fSAndroid Build Coastguard Worker   if (dwStyles & XFA_ResolveFlag::kSiblings) {
392*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Node* child = parentNode->GetFirstChild();
393*3ac0a46fSAndroid Build Coastguard Worker     Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
394*3ac0a46fSAndroid Build Coastguard Worker                                          XFA_ResolveFlag::kProperties};
395*3ac0a46fSAndroid Build Coastguard Worker     if (dwStyles & XFA_ResolveFlag::kTagName)
396*3ac0a46fSAndroid Build Coastguard Worker       dwSubStyles |= XFA_ResolveFlag::kTagName;
397*3ac0a46fSAndroid Build Coastguard Worker     if (dwStyles & XFA_ResolveFlag::kALL)
398*3ac0a46fSAndroid Build Coastguard Worker       dwSubStyles |= XFA_ResolveFlag::kALL;
399*3ac0a46fSAndroid Build Coastguard Worker 
400*3ac0a46fSAndroid Build Coastguard Worker     rndFind.m_dwStyles = dwSubStyles;
401*3ac0a46fSAndroid Build Coastguard Worker     while (child) {
402*3ac0a46fSAndroid Build Coastguard Worker       if (child == curNode) {
403*3ac0a46fSAndroid Build Coastguard Worker         if (dwStyles & XFA_ResolveFlag::kTagName) {
404*3ac0a46fSAndroid Build Coastguard Worker           if (uCurClassHash == uNameHash)
405*3ac0a46fSAndroid Build Coastguard Worker             rnd.m_Result.objects.emplace_back(curNode);
406*3ac0a46fSAndroid Build Coastguard Worker         } else {
407*3ac0a46fSAndroid Build Coastguard Worker           if (child->GetNameHash() == uNameHash) {
408*3ac0a46fSAndroid Build Coastguard Worker             rnd.m_Result.objects.emplace_back(curNode);
409*3ac0a46fSAndroid Build Coastguard Worker             if (rnd.m_nLevel == 0 && wsCondition.IsEmpty()) {
410*3ac0a46fSAndroid Build Coastguard Worker               rnd.m_Result.objects.clear();
411*3ac0a46fSAndroid Build Coastguard Worker               rnd.m_Result.objects.emplace_back(curNode);
412*3ac0a46fSAndroid Build Coastguard Worker               return true;
413*3ac0a46fSAndroid Build Coastguard Worker             }
414*3ac0a46fSAndroid Build Coastguard Worker           }
415*3ac0a46fSAndroid Build Coastguard Worker         }
416*3ac0a46fSAndroid Build Coastguard Worker         child = child->GetNextSibling();
417*3ac0a46fSAndroid Build Coastguard Worker         continue;
418*3ac0a46fSAndroid Build Coastguard Worker       }
419*3ac0a46fSAndroid Build Coastguard Worker 
420*3ac0a46fSAndroid Build Coastguard Worker       if (dwStyles & XFA_ResolveFlag::kTagName) {
421*3ac0a46fSAndroid Build Coastguard Worker         if (child->GetClassHashCode() == uNameHash)
422*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects.emplace_back(child);
423*3ac0a46fSAndroid Build Coastguard Worker       } else if (child->GetNameHash() == uNameHash) {
424*3ac0a46fSAndroid Build Coastguard Worker         rnd.m_Result.objects.emplace_back(child);
425*3ac0a46fSAndroid Build Coastguard Worker       }
426*3ac0a46fSAndroid Build Coastguard Worker 
427*3ac0a46fSAndroid Build Coastguard Worker       bool bInnerSearch = false;
428*3ac0a46fSAndroid Build Coastguard Worker       if (parentNode->HasProperty(child->GetElementType())) {
429*3ac0a46fSAndroid Build Coastguard Worker         if ((child->GetElementType() == XFA_Element::Variables ||
430*3ac0a46fSAndroid Build Coastguard Worker              child->GetElementType() == XFA_Element::PageSet)) {
431*3ac0a46fSAndroid Build Coastguard Worker           bInnerSearch = true;
432*3ac0a46fSAndroid Build Coastguard Worker         }
433*3ac0a46fSAndroid Build Coastguard Worker       } else if (child->IsTransparent()) {
434*3ac0a46fSAndroid Build Coastguard Worker         bInnerSearch = true;
435*3ac0a46fSAndroid Build Coastguard Worker       }
436*3ac0a46fSAndroid Build Coastguard Worker       if (bInnerSearch) {
437*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_CurObject = child;
438*3ac0a46fSAndroid Build Coastguard Worker         WideString wsOriginCondition = std::move(rndFind.m_wsCondition);
439*3ac0a46fSAndroid Build Coastguard Worker         Mask<XFA_ResolveFlag> dwOriginStyle = rndFind.m_dwStyles;
440*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_dwStyles = dwOriginStyle | XFA_ResolveFlag::kALL;
441*3ac0a46fSAndroid Build Coastguard Worker         ResolveNormal(pIsolate, rndFind);
442*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_dwStyles = dwOriginStyle;
443*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_wsCondition = std::move(wsOriginCondition);
444*3ac0a46fSAndroid Build Coastguard Worker         rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
445*3ac0a46fSAndroid Build Coastguard Worker                                     rndFind.m_Result.objects.begin(),
446*3ac0a46fSAndroid Build Coastguard Worker                                     rndFind.m_Result.objects.end());
447*3ac0a46fSAndroid Build Coastguard Worker         rndFind.m_Result.objects.clear();
448*3ac0a46fSAndroid Build Coastguard Worker       }
449*3ac0a46fSAndroid Build Coastguard Worker       child = child->GetNextSibling();
450*3ac0a46fSAndroid Build Coastguard Worker     }
451*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_Result.objects.size() > nNum) {
452*3ac0a46fSAndroid Build Coastguard Worker       if (parentNode->IsTransparent()) {
453*3ac0a46fSAndroid Build Coastguard Worker         std::vector<CXFA_Node*> upArrayNodes;
454*3ac0a46fSAndroid Build Coastguard Worker         CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
455*3ac0a46fSAndroid Build Coastguard Worker         if (pCurrent) {
456*3ac0a46fSAndroid Build Coastguard Worker           upArrayNodes =
457*3ac0a46fSAndroid Build Coastguard Worker               pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
458*3ac0a46fSAndroid Build Coastguard Worker         }
459*3ac0a46fSAndroid Build Coastguard Worker         if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
460*3ac0a46fSAndroid Build Coastguard Worker           CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
461*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
462*3ac0a46fSAndroid Build Coastguard Worker               upArrayNodes.begin(), upArrayNodes.end());
463*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_Result.objects.front() = pSaveObject;
464*3ac0a46fSAndroid Build Coastguard Worker         }
465*3ac0a46fSAndroid Build Coastguard Worker       }
466*3ac0a46fSAndroid Build Coastguard Worker       FilterCondition(pIsolate, wsCondition, &rnd);
467*3ac0a46fSAndroid Build Coastguard Worker       return !rnd.m_Result.objects.empty();
468*3ac0a46fSAndroid Build Coastguard Worker     }
469*3ac0a46fSAndroid Build Coastguard Worker   }
470*3ac0a46fSAndroid Build Coastguard Worker 
471*3ac0a46fSAndroid Build Coastguard Worker   if (dwStyles & XFA_ResolveFlag::kParent) {
472*3ac0a46fSAndroid Build Coastguard Worker     Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kSiblings,
473*3ac0a46fSAndroid Build Coastguard Worker                                          XFA_ResolveFlag::kParent,
474*3ac0a46fSAndroid Build Coastguard Worker                                          XFA_ResolveFlag::kProperties};
475*3ac0a46fSAndroid Build Coastguard Worker     if (dwStyles & XFA_ResolveFlag::kTagName)
476*3ac0a46fSAndroid Build Coastguard Worker       dwSubStyles |= XFA_ResolveFlag::kTagName;
477*3ac0a46fSAndroid Build Coastguard Worker     if (dwStyles & XFA_ResolveFlag::kALL)
478*3ac0a46fSAndroid Build Coastguard Worker       dwSubStyles |= XFA_ResolveFlag::kALL;
479*3ac0a46fSAndroid Build Coastguard Worker 
480*3ac0a46fSAndroid Build Coastguard Worker     m_pEngine->AddObjectToUpArray(parentNode);
481*3ac0a46fSAndroid Build Coastguard Worker     rndFind.m_dwStyles = dwSubStyles;
482*3ac0a46fSAndroid Build Coastguard Worker     rndFind.m_CurObject = parentNode;
483*3ac0a46fSAndroid Build Coastguard Worker     ResolveNormal(pIsolate, rndFind);
484*3ac0a46fSAndroid Build Coastguard Worker     rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
485*3ac0a46fSAndroid Build Coastguard Worker                                 rndFind.m_Result.objects.begin(),
486*3ac0a46fSAndroid Build Coastguard Worker                                 rndFind.m_Result.objects.end());
487*3ac0a46fSAndroid Build Coastguard Worker     rndFind.m_Result.objects.clear();
488*3ac0a46fSAndroid Build Coastguard Worker     if (rnd.m_Result.objects.size() > nNum)
489*3ac0a46fSAndroid Build Coastguard Worker       return true;
490*3ac0a46fSAndroid Build Coastguard Worker   }
491*3ac0a46fSAndroid Build Coastguard Worker   return false;
492*3ac0a46fSAndroid Build Coastguard Worker }
493*3ac0a46fSAndroid Build Coastguard Worker 
ResolveAsterisk(NodeData & rnd)494*3ac0a46fSAndroid Build Coastguard Worker bool CFXJSE_ResolveProcessor::ResolveAsterisk(NodeData& rnd) {
495*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* curNode = ToNode(rnd.m_CurObject);
496*3ac0a46fSAndroid Build Coastguard Worker   std::vector<CXFA_Node*> array = curNode->GetNodeListWithFilter(
497*3ac0a46fSAndroid Build Coastguard Worker       {XFA_NodeFilter::kChildren, XFA_NodeFilter::kProperties});
498*3ac0a46fSAndroid Build Coastguard Worker   rnd.m_Result.objects.insert(rnd.m_Result.objects.end(), array.begin(),
499*3ac0a46fSAndroid Build Coastguard Worker                               array.end());
500*3ac0a46fSAndroid Build Coastguard Worker   return !rnd.m_Result.objects.empty();
501*3ac0a46fSAndroid Build Coastguard Worker }
502*3ac0a46fSAndroid Build Coastguard Worker 
GetFilter(WideStringView wsExpression,int32_t nStart,NodeData & rnd)503*3ac0a46fSAndroid Build Coastguard Worker int32_t CFXJSE_ResolveProcessor::GetFilter(WideStringView wsExpression,
504*3ac0a46fSAndroid Build Coastguard Worker                                            int32_t nStart,
505*3ac0a46fSAndroid Build Coastguard Worker                                            NodeData& rnd) {
506*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(nStart > -1);
507*3ac0a46fSAndroid Build Coastguard Worker 
508*3ac0a46fSAndroid Build Coastguard Worker   int32_t iLength = wsExpression.GetLength();
509*3ac0a46fSAndroid Build Coastguard Worker   if (nStart >= iLength)
510*3ac0a46fSAndroid Build Coastguard Worker     return 0;
511*3ac0a46fSAndroid Build Coastguard Worker 
512*3ac0a46fSAndroid Build Coastguard Worker   WideString& wsName = rnd.m_wsName;
513*3ac0a46fSAndroid Build Coastguard Worker   WideString& wsCondition = rnd.m_wsCondition;
514*3ac0a46fSAndroid Build Coastguard Worker   int32_t nNameCount = 0;
515*3ac0a46fSAndroid Build Coastguard Worker   int32_t nConditionCount = 0;
516*3ac0a46fSAndroid Build Coastguard Worker   {
517*3ac0a46fSAndroid Build Coastguard Worker     // Span's lifetime must end before ReleaseBuffer() below.
518*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<wchar_t> pNameBuf = wsName.GetBuffer(iLength - nStart);
519*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<wchar_t> pConditionBuf =
520*3ac0a46fSAndroid Build Coastguard Worker         wsCondition.GetBuffer(iLength - nStart);
521*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<const wchar_t> pSrc = wsExpression.span();
522*3ac0a46fSAndroid Build Coastguard Worker     std::vector<int32_t> stack;
523*3ac0a46fSAndroid Build Coastguard Worker     int32_t nType = -1;
524*3ac0a46fSAndroid Build Coastguard Worker     wchar_t wPrev = 0;
525*3ac0a46fSAndroid Build Coastguard Worker     wchar_t wCur;
526*3ac0a46fSAndroid Build Coastguard Worker     bool bIsCondition = false;
527*3ac0a46fSAndroid Build Coastguard Worker     while (nStart < iLength) {
528*3ac0a46fSAndroid Build Coastguard Worker       wCur = pSrc[nStart++];
529*3ac0a46fSAndroid Build Coastguard Worker       if (wCur == '.') {
530*3ac0a46fSAndroid Build Coastguard Worker         if (nNameCount == 0) {
531*3ac0a46fSAndroid Build Coastguard Worker           rnd.m_dwStyles |= XFA_ResolveFlag::kAnyChild;
532*3ac0a46fSAndroid Build Coastguard Worker           continue;
533*3ac0a46fSAndroid Build Coastguard Worker         }
534*3ac0a46fSAndroid Build Coastguard Worker         if (wPrev == '\\') {
535*3ac0a46fSAndroid Build Coastguard Worker           pNameBuf[nNameCount - 1] = wPrev = '.';
536*3ac0a46fSAndroid Build Coastguard Worker           continue;
537*3ac0a46fSAndroid Build Coastguard Worker         }
538*3ac0a46fSAndroid Build Coastguard Worker 
539*3ac0a46fSAndroid Build Coastguard Worker         wchar_t wLookahead = nStart < iLength ? pSrc[nStart] : 0;
540*3ac0a46fSAndroid Build Coastguard Worker         if (wLookahead != '[' && wLookahead != '(' && nType < 0)
541*3ac0a46fSAndroid Build Coastguard Worker           break;
542*3ac0a46fSAndroid Build Coastguard Worker       }
543*3ac0a46fSAndroid Build Coastguard Worker       if (wCur == '[' || wCur == '(') {
544*3ac0a46fSAndroid Build Coastguard Worker         bIsCondition = true;
545*3ac0a46fSAndroid Build Coastguard Worker       } else if (wCur == '.' && nStart < iLength &&
546*3ac0a46fSAndroid Build Coastguard Worker                  (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
547*3ac0a46fSAndroid Build Coastguard Worker         bIsCondition = true;
548*3ac0a46fSAndroid Build Coastguard Worker       }
549*3ac0a46fSAndroid Build Coastguard Worker       if (bIsCondition)
550*3ac0a46fSAndroid Build Coastguard Worker         pConditionBuf[nConditionCount++] = wCur;
551*3ac0a46fSAndroid Build Coastguard Worker       else
552*3ac0a46fSAndroid Build Coastguard Worker         pNameBuf[nNameCount++] = wCur;
553*3ac0a46fSAndroid Build Coastguard Worker 
554*3ac0a46fSAndroid Build Coastguard Worker       if ((nType == 0 && wCur == ']') || (nType == 1 && wCur == ')') ||
555*3ac0a46fSAndroid Build Coastguard Worker           (nType == 2 && wCur == '"')) {
556*3ac0a46fSAndroid Build Coastguard Worker         nType = stack.empty() ? -1 : stack.back();
557*3ac0a46fSAndroid Build Coastguard Worker         if (!stack.empty())
558*3ac0a46fSAndroid Build Coastguard Worker           stack.pop_back();
559*3ac0a46fSAndroid Build Coastguard Worker       } else if (wCur == '[') {
560*3ac0a46fSAndroid Build Coastguard Worker         stack.push_back(nType);
561*3ac0a46fSAndroid Build Coastguard Worker         nType = 0;
562*3ac0a46fSAndroid Build Coastguard Worker       } else if (wCur == '(') {
563*3ac0a46fSAndroid Build Coastguard Worker         stack.push_back(nType);
564*3ac0a46fSAndroid Build Coastguard Worker         nType = 1;
565*3ac0a46fSAndroid Build Coastguard Worker       } else if (wCur == '"') {
566*3ac0a46fSAndroid Build Coastguard Worker         stack.push_back(nType);
567*3ac0a46fSAndroid Build Coastguard Worker         nType = 2;
568*3ac0a46fSAndroid Build Coastguard Worker       }
569*3ac0a46fSAndroid Build Coastguard Worker       wPrev = wCur;
570*3ac0a46fSAndroid Build Coastguard Worker     }
571*3ac0a46fSAndroid Build Coastguard Worker     if (!stack.empty())
572*3ac0a46fSAndroid Build Coastguard Worker       return -1;
573*3ac0a46fSAndroid Build Coastguard Worker   }
574*3ac0a46fSAndroid Build Coastguard Worker   wsName.ReleaseBuffer(nNameCount);
575*3ac0a46fSAndroid Build Coastguard Worker   wsCondition.ReleaseBuffer(nConditionCount);
576*3ac0a46fSAndroid Build Coastguard Worker   wsName.Trim();
577*3ac0a46fSAndroid Build Coastguard Worker   wsCondition.Trim();
578*3ac0a46fSAndroid Build Coastguard Worker   rnd.m_uHashName =
579*3ac0a46fSAndroid Build Coastguard Worker       static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringView()));
580*3ac0a46fSAndroid Build Coastguard Worker   return nStart;
581*3ac0a46fSAndroid Build Coastguard Worker }
582*3ac0a46fSAndroid Build Coastguard Worker 
ConditionArray(size_t iCurIndex,WideString wsCondition,size_t iFoundCount,NodeData * pRnd)583*3ac0a46fSAndroid Build Coastguard Worker void CFXJSE_ResolveProcessor::ConditionArray(size_t iCurIndex,
584*3ac0a46fSAndroid Build Coastguard Worker                                              WideString wsCondition,
585*3ac0a46fSAndroid Build Coastguard Worker                                              size_t iFoundCount,
586*3ac0a46fSAndroid Build Coastguard Worker                                              NodeData* pRnd) {
587*3ac0a46fSAndroid Build Coastguard Worker   size_t iLen = wsCondition.GetLength();
588*3ac0a46fSAndroid Build Coastguard Worker   bool bRelative = false;
589*3ac0a46fSAndroid Build Coastguard Worker   bool bAll = false;
590*3ac0a46fSAndroid Build Coastguard Worker   size_t i = 1;
591*3ac0a46fSAndroid Build Coastguard Worker   for (; i < iLen; ++i) {
592*3ac0a46fSAndroid Build Coastguard Worker     wchar_t ch = wsCondition[i];
593*3ac0a46fSAndroid Build Coastguard Worker     if (ch == ' ')
594*3ac0a46fSAndroid Build Coastguard Worker       continue;
595*3ac0a46fSAndroid Build Coastguard Worker     if (ch == '+' || ch == '-')
596*3ac0a46fSAndroid Build Coastguard Worker       bRelative = true;
597*3ac0a46fSAndroid Build Coastguard Worker     else if (ch == '*')
598*3ac0a46fSAndroid Build Coastguard Worker       bAll = true;
599*3ac0a46fSAndroid Build Coastguard Worker 
600*3ac0a46fSAndroid Build Coastguard Worker     break;
601*3ac0a46fSAndroid Build Coastguard Worker   }
602*3ac0a46fSAndroid Build Coastguard Worker   if (bAll) {
603*3ac0a46fSAndroid Build Coastguard Worker     if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
604*3ac0a46fSAndroid Build Coastguard Worker       if (pRnd->m_dwStyles & XFA_ResolveFlag::kBind) {
605*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
606*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_iCreateCount = 1;
607*3ac0a46fSAndroid Build Coastguard Worker         pRnd->m_Result.objects.clear();
608*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_iCurAllStart = -1;
609*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_pAllStartParent = nullptr;
610*3ac0a46fSAndroid Build Coastguard Worker       } else if (m_pNodeHelper->m_iCurAllStart == -1) {
611*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
612*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_pAllStartParent = ToNode(pRnd->m_CurObject);
613*3ac0a46fSAndroid Build Coastguard Worker       }
614*3ac0a46fSAndroid Build Coastguard Worker     } else if (pRnd->m_dwStyles & XFA_ResolveFlag::kBindNew) {
615*3ac0a46fSAndroid Build Coastguard Worker       if (m_pNodeHelper->m_iCurAllStart == -1)
616*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
617*3ac0a46fSAndroid Build Coastguard Worker     }
618*3ac0a46fSAndroid Build Coastguard Worker     return;
619*3ac0a46fSAndroid Build Coastguard Worker   }
620*3ac0a46fSAndroid Build Coastguard Worker   if (iFoundCount == 1 && !iLen)
621*3ac0a46fSAndroid Build Coastguard Worker     return;
622*3ac0a46fSAndroid Build Coastguard Worker 
623*3ac0a46fSAndroid Build Coastguard Worker   int32_t iIndex = wsCondition.Substr(i, iLen - 1 - i).GetInteger();
624*3ac0a46fSAndroid Build Coastguard Worker   if (bRelative)
625*3ac0a46fSAndroid Build Coastguard Worker     iIndex += iCurIndex;
626*3ac0a46fSAndroid Build Coastguard Worker 
627*3ac0a46fSAndroid Build Coastguard Worker   if (iIndex < 0 || static_cast<size_t>(iIndex) >= iFoundCount) {
628*3ac0a46fSAndroid Build Coastguard Worker     if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
629*3ac0a46fSAndroid Build Coastguard Worker       m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
630*3ac0a46fSAndroid Build Coastguard Worker       m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
631*3ac0a46fSAndroid Build Coastguard Worker     }
632*3ac0a46fSAndroid Build Coastguard Worker     pRnd->m_Result.objects.clear();
633*3ac0a46fSAndroid Build Coastguard Worker   } else {
634*3ac0a46fSAndroid Build Coastguard Worker     pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
635*3ac0a46fSAndroid Build Coastguard Worker         1, pRnd->m_Result.objects[iIndex]);
636*3ac0a46fSAndroid Build Coastguard Worker   }
637*3ac0a46fSAndroid Build Coastguard Worker }
638*3ac0a46fSAndroid Build Coastguard Worker 
FilterCondition(v8::Isolate * pIsolate,WideString wsCondition,NodeData * pRnd)639*3ac0a46fSAndroid Build Coastguard Worker void CFXJSE_ResolveProcessor::FilterCondition(v8::Isolate* pIsolate,
640*3ac0a46fSAndroid Build Coastguard Worker                                               WideString wsCondition,
641*3ac0a46fSAndroid Build Coastguard Worker                                               NodeData* pRnd) {
642*3ac0a46fSAndroid Build Coastguard Worker   size_t iCurIndex = 0;
643*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pNode = m_pEngine->LastObjectFromUpArray();
644*3ac0a46fSAndroid Build Coastguard Worker   if (pNode) {
645*3ac0a46fSAndroid Build Coastguard Worker     const bool bIsProperty = pNode->IsProperty();
646*3ac0a46fSAndroid Build Coastguard Worker     const bool bIsClassIndex =
647*3ac0a46fSAndroid Build Coastguard Worker         pNode->IsUnnamed() ||
648*3ac0a46fSAndroid Build Coastguard Worker         (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
649*3ac0a46fSAndroid Build Coastguard Worker     iCurIndex = pNode->GetIndex(bIsProperty, bIsClassIndex);
650*3ac0a46fSAndroid Build Coastguard Worker   }
651*3ac0a46fSAndroid Build Coastguard Worker 
652*3ac0a46fSAndroid Build Coastguard Worker   size_t iFoundCount = pRnd->m_Result.objects.size();
653*3ac0a46fSAndroid Build Coastguard Worker   wsCondition.Trim();
654*3ac0a46fSAndroid Build Coastguard Worker 
655*3ac0a46fSAndroid Build Coastguard Worker   const size_t nLen = wsCondition.GetLength();
656*3ac0a46fSAndroid Build Coastguard Worker   if (nLen == 0) {
657*3ac0a46fSAndroid Build Coastguard Worker     if (pRnd->m_dwStyles & XFA_ResolveFlag::kALL)
658*3ac0a46fSAndroid Build Coastguard Worker       return;
659*3ac0a46fSAndroid Build Coastguard Worker     if (iFoundCount == 1)
660*3ac0a46fSAndroid Build Coastguard Worker       return;
661*3ac0a46fSAndroid Build Coastguard Worker 
662*3ac0a46fSAndroid Build Coastguard Worker     if (iFoundCount <= iCurIndex) {
663*3ac0a46fSAndroid Build Coastguard Worker       if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
664*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
665*3ac0a46fSAndroid Build Coastguard Worker         m_pNodeHelper->m_iCreateCount = iCurIndex - iFoundCount + 1;
666*3ac0a46fSAndroid Build Coastguard Worker       }
667*3ac0a46fSAndroid Build Coastguard Worker       pRnd->m_Result.objects.clear();
668*3ac0a46fSAndroid Build Coastguard Worker       return;
669*3ac0a46fSAndroid Build Coastguard Worker     }
670*3ac0a46fSAndroid Build Coastguard Worker 
671*3ac0a46fSAndroid Build Coastguard Worker     pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
672*3ac0a46fSAndroid Build Coastguard Worker         1, pRnd->m_Result.objects[iCurIndex]);
673*3ac0a46fSAndroid Build Coastguard Worker     return;
674*3ac0a46fSAndroid Build Coastguard Worker   }
675*3ac0a46fSAndroid Build Coastguard Worker 
676*3ac0a46fSAndroid Build Coastguard Worker   wchar_t wTypeChar = wsCondition[0];
677*3ac0a46fSAndroid Build Coastguard Worker   switch (wTypeChar) {
678*3ac0a46fSAndroid Build Coastguard Worker     case '[':
679*3ac0a46fSAndroid Build Coastguard Worker       ConditionArray(iCurIndex, wsCondition, iFoundCount, pRnd);
680*3ac0a46fSAndroid Build Coastguard Worker       return;
681*3ac0a46fSAndroid Build Coastguard Worker     case '.':
682*3ac0a46fSAndroid Build Coastguard Worker       if (nLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '('))
683*3ac0a46fSAndroid Build Coastguard Worker         DoPredicateFilter(pIsolate, wsCondition, iFoundCount, pRnd);
684*3ac0a46fSAndroid Build Coastguard Worker       return;
685*3ac0a46fSAndroid Build Coastguard Worker     case '(':
686*3ac0a46fSAndroid Build Coastguard Worker     case '"':
687*3ac0a46fSAndroid Build Coastguard Worker     default:
688*3ac0a46fSAndroid Build Coastguard Worker       return;
689*3ac0a46fSAndroid Build Coastguard Worker   }
690*3ac0a46fSAndroid Build Coastguard Worker }
691*3ac0a46fSAndroid Build Coastguard Worker 
SetStylesForChild(Mask<XFA_ResolveFlag> dwParentStyles,NodeData & rnd)692*3ac0a46fSAndroid Build Coastguard Worker void CFXJSE_ResolveProcessor::SetStylesForChild(
693*3ac0a46fSAndroid Build Coastguard Worker     Mask<XFA_ResolveFlag> dwParentStyles,
694*3ac0a46fSAndroid Build Coastguard Worker     NodeData& rnd) {
695*3ac0a46fSAndroid Build Coastguard Worker   Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
696*3ac0a46fSAndroid Build Coastguard Worker                                        XFA_ResolveFlag::kALL};
697*3ac0a46fSAndroid Build Coastguard Worker   if (dwParentStyles & XFA_ResolveFlag::kTagName)
698*3ac0a46fSAndroid Build Coastguard Worker     dwSubStyles |= XFA_ResolveFlag::kTagName;
699*3ac0a46fSAndroid Build Coastguard Worker   rnd.m_dwStyles = dwSubStyles;
700*3ac0a46fSAndroid Build Coastguard Worker }
701*3ac0a46fSAndroid Build Coastguard Worker 
IndexForDataBind(const WideString & wsNextCondition,int32_t iCount)702*3ac0a46fSAndroid Build Coastguard Worker int32_t CFXJSE_ResolveProcessor::IndexForDataBind(
703*3ac0a46fSAndroid Build Coastguard Worker     const WideString& wsNextCondition,
704*3ac0a46fSAndroid Build Coastguard Worker     int32_t iCount) {
705*3ac0a46fSAndroid Build Coastguard Worker   if (m_pNodeHelper->CreateNodeForCondition(wsNextCondition) &&
706*3ac0a46fSAndroid Build Coastguard Worker       m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) {
707*3ac0a46fSAndroid Build Coastguard Worker     return 0;
708*3ac0a46fSAndroid Build Coastguard Worker   }
709*3ac0a46fSAndroid Build Coastguard Worker   return iCount - 1;
710*3ac0a46fSAndroid Build Coastguard Worker }
711*3ac0a46fSAndroid Build Coastguard Worker 
DoPredicateFilter(v8::Isolate * pIsolate,WideString wsCondition,size_t iFoundCount,NodeData * pRnd)712*3ac0a46fSAndroid Build Coastguard Worker void CFXJSE_ResolveProcessor::DoPredicateFilter(v8::Isolate* pIsolate,
713*3ac0a46fSAndroid Build Coastguard Worker                                                 WideString wsCondition,
714*3ac0a46fSAndroid Build Coastguard Worker                                                 size_t iFoundCount,
715*3ac0a46fSAndroid Build Coastguard Worker                                                 NodeData* pRnd) {
716*3ac0a46fSAndroid Build Coastguard Worker   DCHECK_EQ(iFoundCount, pRnd->m_Result.objects.size());
717*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
718*3ac0a46fSAndroid Build Coastguard Worker   if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
719*3ac0a46fSAndroid Build Coastguard Worker     eLangType = CXFA_Script::Type::Formcalc;
720*3ac0a46fSAndroid Build Coastguard Worker   else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
721*3ac0a46fSAndroid Build Coastguard Worker     eLangType = CXFA_Script::Type::Javascript;
722*3ac0a46fSAndroid Build Coastguard Worker   else
723*3ac0a46fSAndroid Build Coastguard Worker     return;
724*3ac0a46fSAndroid Build Coastguard Worker 
725*3ac0a46fSAndroid Build Coastguard Worker   WideString wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
726*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = iFoundCount; i > 0; --i) {
727*3ac0a46fSAndroid Build Coastguard Worker     auto pRetValue = std::make_unique<CFXJSE_Value>();
728*3ac0a46fSAndroid Build Coastguard Worker     bool bRet = m_pEngine->RunScript(eLangType, wsExpression.AsStringView(),
729*3ac0a46fSAndroid Build Coastguard Worker                                      pRetValue.get(),
730*3ac0a46fSAndroid Build Coastguard Worker                                      pRnd->m_Result.objects[i - 1].Get());
731*3ac0a46fSAndroid Build Coastguard Worker     if (!bRet || !pRetValue->ToBoolean(pIsolate))
732*3ac0a46fSAndroid Build Coastguard Worker       pRnd->m_Result.objects.erase(pRnd->m_Result.objects.begin() + i - 1);
733*3ac0a46fSAndroid Build Coastguard Worker   }
734*3ac0a46fSAndroid Build Coastguard Worker }
735*3ac0a46fSAndroid Build Coastguard Worker 
736*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_ResolveProcessor::NodeData::NodeData() = default;
737*3ac0a46fSAndroid Build Coastguard Worker 
738*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_ResolveProcessor::NodeData::~NodeData() = default;
739