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" 20 CXFA_ResolveProcessor::CXFA_ResolveProcessor(void) 21 : m_pNodeHelper(NULL), m_iCurStart(0) { 22 m_pNodeHelper = new CXFA_NodeHelper; 23 } 24 CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void) { 25 if (m_pNodeHelper) { 26 delete m_pNodeHelper; 27 m_pNodeHelper = NULL; 28 } 29 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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