• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/parser/cxfa_resolveprocessor.h"
8 
9 #include "core/fxcrt/fx_ext.h"
10 #include "xfa/fxfa/parser/cxfa_document.h"
11 #include "xfa/fxfa/parser/cxfa_nodehelper.h"
12 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
13 #include "xfa/fxfa/parser/xfa_localemgr.h"
14 #include "xfa/fxfa/parser/xfa_object.h"
15 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
16 #include "xfa/fxfa/parser/xfa_utils.h"
17 
CXFA_ResolveProcessor()18 CXFA_ResolveProcessor::CXFA_ResolveProcessor()
19     : m_iCurStart(0), m_pNodeHelper(new CXFA_NodeHelper) {}
20 
~CXFA_ResolveProcessor()21 CXFA_ResolveProcessor::~CXFA_ResolveProcessor() {}
22 
Resolve(CXFA_ResolveNodesData & rnd)23 int32_t CXFA_ResolveProcessor::Resolve(CXFA_ResolveNodesData& rnd) {
24   if (!rnd.m_CurNode) {
25     return -1;
26   }
27   if (!rnd.m_CurNode->IsNode()) {
28     if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
29       return ResolveForAttributeRs(rnd.m_CurNode, rnd,
30                                    rnd.m_wsName.AsStringC());
31     }
32     return 0;
33   }
34   if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) {
35     return ResolveAnyChild(rnd);
36   }
37   FX_WCHAR wch = rnd.m_wsName.GetAt(0);
38   switch (wch) {
39     case '$':
40       return ResolveDollar(rnd);
41     case '!':
42       return ResolveExcalmatory(rnd);
43     case '#':
44       return ResolveNumberSign(rnd);
45     case '*':
46       return ResolveAsterisk(rnd);
47     // TODO(dsinclair): We could probably remove this.
48     case '.':
49       return ResolveAnyChild(rnd);
50     default:
51       break;
52   }
53   if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
54     rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject());
55     return 1;
56   } else if (rnd.m_CurNode->GetElementType() == XFA_Element::Xfa) {
57     CXFA_Object* pObjNode =
58         rnd.m_pSC->GetDocument()->GetXFAObject(rnd.m_uHashName);
59     if (pObjNode) {
60       rnd.m_Nodes.Add(pObjNode);
61     } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
62       rnd.m_Nodes.Add(rnd.m_CurNode);
63     } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
64                ResolveForAttributeRs(rnd.m_CurNode, rnd,
65                                      rnd.m_wsName.AsStringC())) {
66       return 1;
67     }
68     if (rnd.m_Nodes.GetSize() > 0) {
69       FilterCondition(rnd, rnd.m_wsCondition);
70     }
71     return rnd.m_Nodes.GetSize();
72   }
73   int32_t nRet = ResolveNormal(rnd);
74   if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) {
75     rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
76   }
77   return rnd.m_Nodes.GetSize();
78 }
ResolveAnyChild(CXFA_ResolveNodesData & rnd)79 int32_t CXFA_ResolveProcessor::ResolveAnyChild(CXFA_ResolveNodesData& rnd) {
80   CFX_WideString wsName = rnd.m_wsName;
81   CFX_WideString wsCondition = rnd.m_wsCondition;
82   CXFA_Node* findNode = nullptr;
83   CXFA_NodeArray siblings;
84   bool bClassName = false;
85   if (wsName.GetAt(0) == '#') {
86     bClassName = true;
87     wsName = wsName.Right(wsName.GetLength() - 1);
88   }
89   findNode = m_pNodeHelper->ResolveNodes_GetOneChild(
90       ToNode(rnd.m_CurNode), wsName.c_str(), bClassName);
91   if (!findNode) {
92     return 0;
93   }
94   if (wsCondition.IsEmpty()) {
95     rnd.m_Nodes.Add(findNode);
96     return rnd.m_Nodes.GetSize();
97   }
98   m_pNodeHelper->CountSiblings(findNode, XFA_LOGIC_Transparent,
99                                (CXFA_NodeArray*)&rnd.m_Nodes, bClassName);
100   FilterCondition(rnd, wsCondition);
101   return rnd.m_Nodes.GetSize();
102 }
ResolveDollar(CXFA_ResolveNodesData & rnd)103 int32_t CXFA_ResolveProcessor::ResolveDollar(CXFA_ResolveNodesData& rnd) {
104   CXFA_ObjArray& nodes = rnd.m_Nodes;
105   CFX_WideString wsName = rnd.m_wsName;
106   CFX_WideString wsCondition = rnd.m_wsCondition;
107   int32_t iNameLen = wsName.GetLength();
108   if (iNameLen == 1) {
109     nodes.Add(rnd.m_CurNode);
110     return 1;
111   }
112   if (rnd.m_nLevel > 0) {
113     return -1;
114   }
115   XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(FX_HashCode_GetW(
116       CFX_WideStringC(wsName.c_str() + 1, iNameLen - 1), false));
117   if (dwNameHash == XFA_HASHCODE_Xfa) {
118     nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
119   } else {
120     CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFAObject(dwNameHash);
121     if (pObjNode) {
122       rnd.m_Nodes.Add(pObjNode);
123     }
124   }
125   if (rnd.m_Nodes.GetSize() > 0) {
126     FilterCondition(rnd, wsCondition);
127   }
128   return rnd.m_Nodes.GetSize();
129 }
ResolveExcalmatory(CXFA_ResolveNodesData & rnd)130 int32_t CXFA_ResolveProcessor::ResolveExcalmatory(CXFA_ResolveNodesData& rnd) {
131   if (rnd.m_nLevel > 0) {
132     return 0;
133   }
134   CXFA_Node* datasets =
135       ToNode(rnd.m_pSC->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
136   if (!datasets) {
137     return 0;
138   }
139   CXFA_ResolveNodesData rndFind;
140   rndFind.m_pSC = rnd.m_pSC;
141   rndFind.m_CurNode = datasets;
142   rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
143   rndFind.m_uHashName = static_cast<XFA_HashCode>(
144       FX_HashCode_GetW(rndFind.m_wsName.AsStringC(), false));
145   rndFind.m_nLevel = rnd.m_nLevel + 1;
146   rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
147   rndFind.m_wsCondition = rnd.m_wsCondition;
148   Resolve(rndFind);
149   if (rndFind.m_Nodes.GetSize() > 0) {
150     rnd.m_Nodes.Append(rndFind.m_Nodes);
151     rndFind.m_Nodes.RemoveAll();
152   }
153   return rnd.m_Nodes.GetSize();
154 }
ResolveNumberSign(CXFA_ResolveNodesData & rnd)155 int32_t CXFA_ResolveProcessor::ResolveNumberSign(CXFA_ResolveNodesData& rnd) {
156   CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
157   CFX_WideString wsCondition = rnd.m_wsCondition;
158   CXFA_Node* curNode = ToNode(rnd.m_CurNode);
159   if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringC())) {
160     return 1;
161   }
162   CXFA_ResolveNodesData rndFind;
163   rndFind.m_pSC = rnd.m_pSC;
164   rndFind.m_nLevel = rnd.m_nLevel + 1;
165   rndFind.m_dwStyles = rnd.m_dwStyles;
166   rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
167   rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
168   rndFind.m_wsName = wsName;
169   rndFind.m_uHashName = static_cast<XFA_HashCode>(
170       FX_HashCode_GetW(rndFind.m_wsName.AsStringC(), false));
171   rndFind.m_wsCondition = wsCondition;
172   rndFind.m_CurNode = curNode;
173   ResolveNormal(rndFind);
174   if (rndFind.m_Nodes.GetSize() > 0) {
175     if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) {
176       rnd.m_Nodes.Add(curNode);
177     } else {
178       rnd.m_Nodes.Append(rndFind.m_Nodes);
179       rndFind.m_Nodes.RemoveAll();
180     }
181   }
182   return rnd.m_Nodes.GetSize();
183 }
ResolveForAttributeRs(CXFA_Object * curNode,CXFA_ResolveNodesData & rnd,const CFX_WideStringC & strAttr)184 int32_t CXFA_ResolveProcessor::ResolveForAttributeRs(
185     CXFA_Object* curNode,
186     CXFA_ResolveNodesData& rnd,
187     const CFX_WideStringC& strAttr) {
188   const XFA_SCRIPTATTRIBUTEINFO* lpScriptAttribute =
189       XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr);
190   if (lpScriptAttribute) {
191     rnd.m_pScriptAttribute = lpScriptAttribute;
192     rnd.m_Nodes.Add(curNode);
193     rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute;
194     return 1;
195   }
196   return 0;
197 }
ResolveNormal(CXFA_ResolveNodesData & rnd)198 int32_t CXFA_ResolveProcessor::ResolveNormal(CXFA_ResolveNodesData& rnd) {
199   if (rnd.m_nLevel > 32) {
200     return 0;
201   }
202   if (!rnd.m_CurNode->IsNode()) {
203     return 0;
204   }
205   CXFA_Node* curNode = ToNode(rnd.m_CurNode);
206   CXFA_ObjArray& nodes = rnd.m_Nodes;
207   int32_t nNum = nodes.GetSize();
208   uint32_t dwStyles = rnd.m_dwStyles;
209   CFX_WideString& wsName = rnd.m_wsName;
210   XFA_HashCode uNameHash = rnd.m_uHashName;
211   CFX_WideString& wsCondition = rnd.m_wsCondition;
212   CXFA_ResolveNodesData rndFind;
213   rndFind.m_wsName = rnd.m_wsName;
214   rndFind.m_wsCondition = rnd.m_wsCondition;
215   rndFind.m_pSC = rnd.m_pSC;
216   rndFind.m_nLevel = rnd.m_nLevel + 1;
217   rndFind.m_uHashName = uNameHash;
218   CXFA_NodeArray children;
219   CXFA_NodeArray properties;
220   CXFA_Node* pVariablesNode = nullptr;
221   CXFA_Node* pPageSetNode = nullptr;
222   CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild);
223   while (pChild) {
224     if (pChild->GetElementType() == XFA_Element::Variables) {
225       pVariablesNode = pChild;
226       pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
227       continue;
228     } else if (pChild->GetElementType() == XFA_Element::PageSet) {
229       pPageSetNode = pChild;
230       pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
231       continue;
232     } else {
233       const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement(
234           curNode->GetElementType(), pChild->GetElementType(),
235           XFA_XDPPACKET_UNKNOWN);
236       if (pPropert) {
237         properties.Add(pChild);
238       } else {
239         children.Add(pChild);
240       }
241     }
242     pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
243   }
244   if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
245     uint32_t uPropHash = pVariablesNode->GetClassHashCode();
246     if (uPropHash == uNameHash) {
247       nodes.Add(pVariablesNode);
248     } else {
249       rndFind.m_CurNode = pVariablesNode;
250       SetStylesForChild(dwStyles, rndFind);
251       CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
252       rndFind.m_wsCondition.clear();
253       ResolveNormal(rndFind);
254       rndFind.m_wsCondition = wsSaveCondition;
255       if (rndFind.m_Nodes.GetSize() > 0) {
256         nodes.Append(rndFind.m_Nodes);
257         rndFind.m_Nodes.RemoveAll();
258       }
259     }
260     if (nodes.GetSize() > nNum) {
261       FilterCondition(rnd, wsCondition);
262       if (nodes.GetSize() > 0) {
263         return 1;
264       }
265       return 0;
266     }
267   }
268   if (dwStyles & XFA_RESOLVENODE_Children) {
269     bool bSetFlag = false;
270     if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) {
271       children.Add(pPageSetNode);
272     }
273     for (int32_t i = 0; i < children.GetSize(); i++) {
274       CXFA_Node* child = children[i];
275       if (dwStyles & XFA_RESOLVENODE_TagName) {
276         if (child->GetClassHashCode() == uNameHash) {
277           nodes.Add(child);
278         }
279       } else if (child->GetNameHash() == uNameHash) {
280         nodes.Add(child);
281       }
282       if (m_pNodeHelper->NodeIsTransparent(child) &&
283           child->GetElementType() != XFA_Element::PageSet) {
284         if (!bSetFlag) {
285           SetStylesForChild(dwStyles, rndFind);
286           bSetFlag = true;
287         }
288         rndFind.m_CurNode = child;
289         CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
290         rndFind.m_wsCondition.clear();
291         ResolveNormal(rndFind);
292         rndFind.m_wsCondition = wsSaveCondition;
293         if (rndFind.m_Nodes.GetSize() > 0) {
294           nodes.Append(rndFind.m_Nodes);
295           rndFind.m_Nodes.RemoveAll();
296         }
297       }
298     }
299     if (nodes.GetSize() > nNum) {
300       if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
301         CXFA_NodeArray upArrayNodes;
302         if (m_pNodeHelper->NodeIsTransparent(ToNode(curNode))) {
303           m_pNodeHelper->CountSiblings(ToNode(nodes[0]), XFA_LOGIC_Transparent,
304                                        &upArrayNodes,
305                                        !!(dwStyles & XFA_RESOLVENODE_TagName));
306         }
307         if (upArrayNodes.GetSize() > nodes.GetSize()) {
308           upArrayNodes[0] = ToNode(nodes[0]);
309           nodes.RemoveAll();
310           nodes.Append((CXFA_ObjArray&)upArrayNodes);
311           upArrayNodes.RemoveAll();
312         }
313       }
314       FilterCondition(rnd, wsCondition);
315       if (nodes.GetSize() > 0) {
316         return 1;
317       }
318       return 0;
319     }
320   }
321   if (dwStyles & XFA_RESOLVENODE_Attributes) {
322     if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringC())) {
323       return 1;
324     }
325   }
326   if (dwStyles & XFA_RESOLVENODE_Properties) {
327     for (int32_t i = 0; i < properties.GetSize(); i++) {
328       CXFA_Node* childProperty = properties[i];
329       if (childProperty->IsUnnamed()) {
330         uint32_t uPropHash = childProperty->GetClassHashCode();
331         if (uPropHash == uNameHash) {
332           nodes.Add(childProperty);
333         }
334       } else if (childProperty->GetNameHash() == uNameHash &&
335                  childProperty->GetElementType() != XFA_Element::Extras &&
336                  childProperty->GetElementType() != XFA_Element::Items) {
337         nodes.Add(childProperty);
338       }
339     }
340     if (nodes.GetSize() > nNum) {
341       FilterCondition(rnd, wsCondition);
342       if (nodes.GetSize() > 0) {
343         return 1;
344       }
345       return 0;
346     }
347     CXFA_Node* pProp = nullptr;
348     if (XFA_Element::Subform == curNode->GetElementType() &&
349         XFA_HASHCODE_Occur == uNameHash) {
350       CXFA_Node* pInstanceManager =
351           curNode->AsNode()->GetInstanceMgrOfSubform();
352       if (pInstanceManager) {
353         pProp = pInstanceManager->GetProperty(0, XFA_Element::Occur, true);
354       }
355     } else {
356       XFA_Element eType = XFA_GetElementTypeForName(wsName.AsStringC());
357       if (eType != XFA_Element::Unknown) {
358         pProp = curNode->AsNode()->GetProperty(0, eType,
359                                                eType != XFA_Element::PageSet);
360       }
361     }
362     if (pProp) {
363       nodes.Add(pProp);
364       return nodes.GetSize();
365     }
366   }
367   CXFA_Node* parentNode = m_pNodeHelper->ResolveNodes_GetParent(
368       curNode->AsNode(), XFA_LOGIC_NoTransparent);
369   uint32_t uCurClassHash = curNode->GetClassHashCode();
370   if (!parentNode) {
371     if (uCurClassHash == uNameHash) {
372       nodes.Add(curNode->AsNode());
373       FilterCondition(rnd, wsCondition);
374       if (nodes.GetSize() > 0) {
375         return 1;
376       }
377     }
378     return 0;
379   }
380   if (dwStyles & XFA_RESOLVENODE_Siblings) {
381     CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
382     uint32_t dwSubStyles =
383         XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
384     if (dwStyles & XFA_RESOLVENODE_TagName) {
385       dwSubStyles |= XFA_RESOLVENODE_TagName;
386     }
387     if (dwStyles & XFA_RESOLVENODE_ALL) {
388       dwSubStyles |= XFA_RESOLVENODE_ALL;
389     }
390     rndFind.m_dwStyles = dwSubStyles;
391     while (child) {
392       if (child == curNode) {
393         if (dwStyles & XFA_RESOLVENODE_TagName) {
394           if (uCurClassHash == uNameHash) {
395             nodes.Add(curNode);
396           }
397         } else {
398           if (child->GetNameHash() == uNameHash) {
399             nodes.Add(curNode);
400             if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) {
401               nodes.RemoveAll();
402               nodes.Add(curNode);
403               return 1;
404             }
405           }
406         }
407         child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
408         continue;
409       }
410       if (dwStyles & XFA_RESOLVENODE_TagName) {
411         if (child->GetClassHashCode() == uNameHash) {
412           nodes.Add(child);
413         }
414       } else if (child->GetNameHash() == uNameHash) {
415         nodes.Add(child);
416       }
417       const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement(
418           parentNode->GetElementType(), child->GetElementType(),
419           XFA_XDPPACKET_UNKNOWN);
420       bool bInnerSearch = false;
421       if (pPropert) {
422         if ((child->GetElementType() == XFA_Element::Variables ||
423              child->GetElementType() == XFA_Element::PageSet)) {
424           bInnerSearch = true;
425         }
426       } else {
427         if (m_pNodeHelper->NodeIsTransparent(child)) {
428           bInnerSearch = true;
429         }
430       }
431       if (bInnerSearch) {
432         rndFind.m_CurNode = child;
433         CFX_WideString wsOriginCondition = rndFind.m_wsCondition;
434         rndFind.m_wsCondition.clear();
435         uint32_t dwOriginStyle = rndFind.m_dwStyles;
436         rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
437         ResolveNormal(rndFind);
438         rndFind.m_dwStyles = dwOriginStyle;
439         rndFind.m_wsCondition = wsOriginCondition;
440         if (rndFind.m_Nodes.GetSize() > 0) {
441           nodes.Append(rndFind.m_Nodes);
442           rndFind.m_Nodes.RemoveAll();
443         }
444       }
445       child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
446     }
447     if (nodes.GetSize() > nNum) {
448       if (m_pNodeHelper->NodeIsTransparent(parentNode)) {
449         CXFA_NodeArray upArrayNodes;
450         m_pNodeHelper->CountSiblings(ToNode(nodes[0]), XFA_LOGIC_Transparent,
451                                      &upArrayNodes,
452                                      !!(dwStyles & XFA_RESOLVENODE_TagName));
453         if (upArrayNodes.GetSize() > nodes.GetSize()) {
454           upArrayNodes[0] = ToNode(nodes[0]);
455           nodes.RemoveAll();
456           nodes.Append((CXFA_ObjArray&)upArrayNodes);
457           upArrayNodes.RemoveAll();
458         }
459       }
460       FilterCondition(rnd, wsCondition);
461       if (nodes.GetSize() > 0) {
462         return 1;
463       }
464       return 0;
465     }
466   }
467   if (dwStyles & XFA_RESOLVENODE_Parent) {
468     uint32_t dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
469                            XFA_RESOLVENODE_Properties;
470     if (dwStyles & XFA_RESOLVENODE_TagName) {
471       dwSubStyles |= XFA_RESOLVENODE_TagName;
472     }
473     if (dwStyles & XFA_RESOLVENODE_ALL) {
474       dwSubStyles |= XFA_RESOLVENODE_ALL;
475     }
476     rndFind.m_dwStyles = dwSubStyles;
477     rndFind.m_CurNode = parentNode;
478     CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
479     array.Add(parentNode);
480     ResolveNormal(rndFind);
481     if (rndFind.m_Nodes.GetSize() > 0) {
482       nodes.Append(rndFind.m_Nodes);
483       rndFind.m_Nodes.RemoveAll();
484     }
485     if (nodes.GetSize() > nNum) {
486       return 1;
487     }
488   }
489   return 0;
490 }
ResolveAsterisk(CXFA_ResolveNodesData & rnd)491 int32_t CXFA_ResolveProcessor::ResolveAsterisk(CXFA_ResolveNodesData& rnd) {
492   CXFA_Node* curNode = ToNode(rnd.m_CurNode);
493   CXFA_ObjArray& nodes = rnd.m_Nodes;
494   CXFA_NodeArray array;
495   curNode->GetNodeList(array,
496                        XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
497   nodes.Append((CXFA_ObjArray&)array);
498   return nodes.GetSize();
499 }
ResolvePopStack(CFX_ArrayTemplate<int32_t> & stack)500 int32_t CXFA_ResolveProcessor::ResolvePopStack(
501     CFX_ArrayTemplate<int32_t>& stack) {
502   int32_t nType = -1;
503   int32_t iSize = stack.GetSize() - 1;
504   if (iSize > -1) {
505     nType = stack[iSize];
506     stack.RemoveAt(iSize, 1);
507   }
508   return nType;
509 }
GetFilter(const CFX_WideStringC & wsExpression,int32_t nStart,CXFA_ResolveNodesData & rnd)510 int32_t CXFA_ResolveProcessor::GetFilter(const CFX_WideStringC& wsExpression,
511                                          int32_t nStart,
512                                          CXFA_ResolveNodesData& rnd) {
513   ASSERT(nStart > -1);
514   int32_t iLength = wsExpression.GetLength();
515   if (nStart >= iLength) {
516     return 0;
517   }
518   CFX_WideString& wsName = rnd.m_wsName;
519   CFX_WideString& wsCondition = rnd.m_wsCondition;
520   FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart);
521   FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart);
522   int32_t nNameCount = 0;
523   int32_t nConditionCount = 0;
524   CFX_ArrayTemplate<int32_t> stack;
525   int32_t nType = -1;
526   const FX_WCHAR* pSrc = wsExpression.c_str();
527   FX_WCHAR wPrev = 0, wCur;
528   bool bIsCondition = false;
529   while (nStart < iLength) {
530     wCur = pSrc[nStart++];
531     if (wCur == '.') {
532       if (wPrev == '\\') {
533         pNameBuf[nNameCount - 1] = wPrev = '.';
534         continue;
535       }
536       if (nNameCount == 0) {
537         rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild;
538         continue;
539       }
540       FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0;
541       if (wLookahead != '[' && wLookahead != '(') {
542         if (nType < 0) {
543           break;
544         }
545       }
546     }
547     if (wCur == '[' || wCur == '(') {
548       bIsCondition = true;
549     } else if (wCur == '.' && nStart < iLength &&
550                (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
551       bIsCondition = true;
552     }
553     if (bIsCondition) {
554       pConditionBuf[nConditionCount++] = wCur;
555     } else {
556       pNameBuf[nNameCount++] = wCur;
557     }
558     bool bRecursive = true;
559     switch (nType) {
560       case 0:
561         if (wCur == ']') {
562           nType = ResolvePopStack(stack);
563           bRecursive = false;
564         }
565         break;
566       case 1:
567         if (wCur == ')') {
568           nType = ResolvePopStack(stack);
569           bRecursive = false;
570         }
571         break;
572       case 2:
573         if (wCur == '"') {
574           nType = ResolvePopStack(stack);
575           bRecursive = false;
576         }
577         break;
578     }
579     if (bRecursive) {
580       switch (wCur) {
581         case '[':
582           stack.Add(nType);
583           nType = 0;
584           break;
585         case '(':
586           stack.Add(nType);
587           nType = 1;
588           break;
589         case '"':
590           stack.Add(nType);
591           nType = 2;
592           break;
593       }
594     }
595     wPrev = wCur;
596   }
597   if (stack.GetSize() > 0) {
598     return -1;
599   }
600   wsName.ReleaseBuffer(nNameCount);
601   wsName.TrimLeft();
602   wsName.TrimRight();
603   wsCondition.ReleaseBuffer(nConditionCount);
604   wsCondition.TrimLeft();
605   wsCondition.TrimRight();
606   rnd.m_uHashName =
607       static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringC(), false));
608   return nStart;
609 }
ConditionArray(int32_t iCurIndex,CFX_WideString wsCondition,int32_t iFoundCount,CXFA_ResolveNodesData & rnd)610 void CXFA_ResolveProcessor::ConditionArray(int32_t iCurIndex,
611                                            CFX_WideString wsCondition,
612                                            int32_t iFoundCount,
613                                            CXFA_ResolveNodesData& rnd) {
614   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
615   int32_t iLen = wsCondition.GetLength();
616   bool bRelative = false;
617   bool bAll = false;
618   int32_t i = 1;
619   for (; i < iLen; ++i) {
620     FX_WCHAR ch = wsCondition[i];
621     if (ch == ' ') {
622       continue;
623     }
624     if (ch == '+' || ch == '-') {
625       bRelative = true;
626       break;
627     } else if (ch == '*') {
628       bAll = true;
629       break;
630     } else {
631       break;
632     }
633   }
634   if (bAll) {
635     if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
636       if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) {
637         m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
638         m_pNodeHelper->m_iCreateCount = 1;
639         findNodes.RemoveAll();
640         m_pNodeHelper->m_iCurAllStart = -1;
641         m_pNodeHelper->m_pAllStartParent = nullptr;
642       } else {
643         if (m_pNodeHelper->m_iCurAllStart == -1) {
644           m_pNodeHelper->m_iCurAllStart = m_iCurStart;
645           m_pNodeHelper->m_pAllStartParent = ToNode(rnd.m_CurNode);
646         }
647       }
648     } else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) {
649       if (m_pNodeHelper->m_iCurAllStart == -1) {
650         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
651       }
652     }
653     return;
654   }
655   if (iFoundCount == 1 && !iLen) {
656     return;
657   }
658   CFX_WideString wsIndex;
659   wsIndex = wsCondition.Mid(i, iLen - 1 - i);
660   int32_t iIndex = wsIndex.GetInteger();
661   if (bRelative) {
662     iIndex += iCurIndex;
663   }
664   if (iFoundCount <= iIndex || iIndex < 0) {
665     if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
666       m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
667       m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
668     }
669     findNodes.RemoveAll();
670   } else {
671     CXFA_Node* ret = findNodes[iIndex];
672     findNodes.RemoveAll();
673     findNodes.Add(ret);
674   }
675 }
DoPredicateFilter(int32_t iCurIndex,CFX_WideString wsCondition,int32_t iFoundCount,CXFA_ResolveNodesData & rnd)676 void CXFA_ResolveProcessor::DoPredicateFilter(int32_t iCurIndex,
677                                               CFX_WideString wsCondition,
678                                               int32_t iFoundCount,
679                                               CXFA_ResolveNodesData& rnd) {
680   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
681   ASSERT(iFoundCount == findNodes.GetSize());
682   CFX_WideString wsExpression;
683   XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown;
684   if (wsCondition.Left(2) == L".[" && wsCondition.Right(1) == L"]") {
685     eLangType = XFA_SCRIPTLANGTYPE_Formcalc;
686   } else if (wsCondition.Left(2) == L".(" && wsCondition.Right(1) == L")") {
687     eLangType = XFA_SCRIPTLANGTYPE_Javascript;
688   } else {
689     return;
690   }
691 
692   CXFA_ScriptContext* pContext = rnd.m_pSC;
693   wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3);
694   for (int32_t i = iFoundCount - 1; i >= 0; i--) {
695     CXFA_Object* node = findNodes[i];
696     bool bRet = false;
697     std::unique_ptr<CFXJSE_Value> pRetValue(
698         new CFXJSE_Value(rnd.m_pSC->GetRuntime()));
699     bRet = pContext->RunScript(eLangType, wsExpression.AsStringC(),
700                                pRetValue.get(), node);
701     if (!bRet || !pRetValue->ToBoolean())
702       findNodes.RemoveAt(i);
703   }
704 }
705 
FilterCondition(CXFA_ResolveNodesData & rnd,CFX_WideString wsCondition)706 void CXFA_ResolveProcessor::FilterCondition(CXFA_ResolveNodesData& rnd,
707                                             CFX_WideString wsCondition) {
708   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
709   int32_t iCurrIndex = 0;
710   const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
711   int32_t iSize = array.GetSize();
712   if (iSize) {
713     CXFA_Node* curNode = array[iSize - 1];
714     bool bIsProperty = m_pNodeHelper->NodeIsProperty(curNode);
715     if (curNode->IsUnnamed() ||
716         (bIsProperty && curNode->GetElementType() != XFA_Element::PageSet)) {
717       iCurrIndex = m_pNodeHelper->GetIndex(curNode, XFA_LOGIC_Transparent,
718                                            bIsProperty, true);
719     } else {
720       iCurrIndex = m_pNodeHelper->GetIndex(curNode, XFA_LOGIC_Transparent,
721                                            bIsProperty, false);
722     }
723   }
724   int32_t iFoundCount = findNodes.GetSize();
725   wsCondition.TrimLeft();
726   wsCondition.TrimRight();
727   int32_t iLen = wsCondition.GetLength();
728   if (!iLen) {
729     if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) {
730       return;
731     }
732     if (iFoundCount == 1) {
733       return;
734     }
735     if (iFoundCount <= iCurrIndex) {
736       if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
737         m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
738         m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1;
739       }
740       findNodes.RemoveAll();
741       return;
742     } else {
743       CXFA_Node* ret = findNodes[iCurrIndex];
744       findNodes.RemoveAll();
745       findNodes.Add(ret);
746       return;
747     }
748   }
749   FX_WCHAR wTypeChar = wsCondition[0];
750   switch (wTypeChar) {
751     case '[':
752       ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd);
753       return;
754     case '(':
755       return;
756     case '"':
757       return;
758     case '.':
759       if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) {
760         DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount, rnd);
761       }
762     default:
763       return;
764   }
765 }
SetStylesForChild(uint32_t dwParentStyles,CXFA_ResolveNodesData & rnd)766 void CXFA_ResolveProcessor::SetStylesForChild(uint32_t dwParentStyles,
767                                               CXFA_ResolveNodesData& rnd) {
768   uint32_t dwSubStyles = XFA_RESOLVENODE_Children;
769   if (dwParentStyles & XFA_RESOLVENODE_TagName) {
770     dwSubStyles |= XFA_RESOLVENODE_TagName;
771   }
772   dwSubStyles &= ~XFA_RESOLVENODE_Parent;
773   dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
774   dwSubStyles &= ~XFA_RESOLVENODE_Properties;
775   dwSubStyles |= XFA_RESOLVENODE_ALL;
776   rnd.m_dwStyles = dwSubStyles;
777 }
SetResultCreateNode(XFA_RESOLVENODE_RS & resolveNodeRS,CFX_WideString & wsLastCondition)778 int32_t CXFA_ResolveProcessor::SetResultCreateNode(
779     XFA_RESOLVENODE_RS& resolveNodeRS,
780     CFX_WideString& wsLastCondition) {
781   if (m_pNodeHelper->m_pCreateParent) {
782     resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent);
783   } else {
784     m_pNodeHelper->CreateNode_ForCondition(wsLastCondition);
785   }
786   resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag;
787   if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
788     if (m_pNodeHelper->m_iCurAllStart != -1) {
789       resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll;
790     }
791   }
792   return resolveNodeRS.nodes.GetSize();
793 }
SetIndexDataBind(CFX_WideString & wsNextCondition,int32_t & iIndex,int32_t iCount)794 void CXFA_ResolveProcessor::SetIndexDataBind(CFX_WideString& wsNextCondition,
795                                              int32_t& iIndex,
796                                              int32_t iCount) {
797   if (m_pNodeHelper->CreateNode_ForCondition(wsNextCondition)) {
798     if (m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) {
799       iIndex = 0;
800     } else {
801       iIndex = iCount - 1;
802     }
803   } else {
804     iIndex = iCount - 1;
805   }
806 }
807 
CXFA_ResolveNodesData(CXFA_ScriptContext * pSC)808 CXFA_ResolveNodesData::CXFA_ResolveNodesData(CXFA_ScriptContext* pSC)
809     : m_pSC(pSC),
810       m_CurNode(nullptr),
811       m_wsName(),
812       m_uHashName(XFA_HASHCODE_None),
813       m_wsCondition(),
814       m_nLevel(0),
815       m_Nodes(),
816       m_dwStyles(XFA_RESOLVENODE_Children),
817       m_pScriptAttribute(nullptr),
818       m_dwFlag(XFA_RESOVENODE_RSTYPE_Nodes) {}
819 
~CXFA_ResolveNodesData()820 CXFA_ResolveNodesData::~CXFA_ResolveNodesData() {
821   m_Nodes.RemoveAll();
822 }
823