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