cxfa_resolveprocessor.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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 18CXFA_ResolveProcessor::CXFA_ResolveProcessor() 19 : m_iCurStart(0), m_pNodeHelper(new CXFA_NodeHelper) {} 20 21CXFA_ResolveProcessor::~CXFA_ResolveProcessor() {} 22 23int32_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} 79int32_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} 103int32_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} 130int32_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} 155int32_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} 184int32_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} 198int32_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} 491int32_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} 500int32_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} 510int32_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} 610void 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} 676void 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 706void 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} 766void 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} 778int32_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} 794void 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 808CXFA_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 820CXFA_ResolveNodesData::~CXFA_ResolveNodesData() { 821 m_Nodes.RemoveAll(); 822} 823