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