• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/xfa_object.h"
8 
9 #include <map>
10 #include <memory>
11 #include <utility>
12 #include <vector>
13 
14 #include "core/fxcrt/fx_ext.h"
15 #include "fxjs/cfxjse_value.h"
16 #include "third_party/base/ptr_util.h"
17 #include "third_party/base/stl_util.h"
18 #include "xfa/fde/xml/fde_xml_imp.h"
19 #include "xfa/fgas/crt/fgas_codepage.h"
20 #include "xfa/fxfa/app/xfa_ffnotify.h"
21 #include "xfa/fxfa/cxfa_eventparam.h"
22 #include "xfa/fxfa/parser/cxfa_document.h"
23 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
24 #include "xfa/fxfa/parser/cxfa_measurement.h"
25 #include "xfa/fxfa/parser/cxfa_occur.h"
26 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
27 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
28 #include "xfa/fxfa/parser/xfa_basic_data.h"
29 
30 namespace {
31 
XFA_DeleteWideString(void * pData)32 void XFA_DeleteWideString(void* pData) {
33   delete static_cast<CFX_WideString*>(pData);
34 }
35 
XFA_CopyWideString(void * & pData)36 void XFA_CopyWideString(void*& pData) {
37   if (pData) {
38     CFX_WideString* pNewData = new CFX_WideString(*(CFX_WideString*)pData);
39     pData = pNewData;
40   }
41 }
42 
43 XFA_MAPDATABLOCKCALLBACKINFO deleteWideStringCallBack = {XFA_DeleteWideString,
44                                                          XFA_CopyWideString};
45 
XFA_DataNodeDeleteBindItem(void * pData)46 void XFA_DataNodeDeleteBindItem(void* pData) {
47   delete static_cast<CXFA_NodeArray*>(pData);
48 }
49 
50 XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {
51     XFA_DataNodeDeleteBindItem, nullptr};
52 
GetCount(CXFA_Node * pInstMgrNode)53 int32_t GetCount(CXFA_Node* pInstMgrNode) {
54   ASSERT(pInstMgrNode);
55   int32_t iCount = 0;
56   uint32_t dwNameHash = 0;
57   for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
58        pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
59     XFA_Element eCurType = pNode->GetElementType();
60     if (eCurType == XFA_Element::InstanceManager)
61       break;
62     if ((eCurType != XFA_Element::Subform) &&
63         (eCurType != XFA_Element::SubformSet)) {
64       continue;
65     }
66     if (iCount == 0) {
67       CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
68       CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
69       if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
70           wsInstName.Mid(1) != wsName) {
71         return iCount;
72       }
73       dwNameHash = pNode->GetNameHash();
74     }
75     if (dwNameHash != pNode->GetNameHash())
76       break;
77 
78     iCount++;
79   }
80   return iCount;
81 }
82 
SortNodeArrayByDocumentIdx(const CXFA_NodeSet & rgNodeSet,CXFA_NodeArray & rgNodeArray,CFX_ArrayTemplate<int32_t> & rgIdxArray)83 void SortNodeArrayByDocumentIdx(const CXFA_NodeSet& rgNodeSet,
84                                 CXFA_NodeArray& rgNodeArray,
85                                 CFX_ArrayTemplate<int32_t>& rgIdxArray) {
86   int32_t iCount = pdfium::CollectionSize<int32_t>(rgNodeSet);
87   rgNodeArray.SetSize(iCount);
88   rgIdxArray.SetSize(iCount);
89   if (iCount == 0)
90     return;
91 
92   int32_t iIndex = -1;
93   int32_t iTotalIndex = -1;
94   CXFA_Node* pCommonParent =
95       (*rgNodeSet.begin())->GetNodeItem(XFA_NODEITEM_Parent);
96   for (CXFA_Node* pNode = pCommonParent->GetNodeItem(XFA_NODEITEM_FirstChild);
97        pNode && iIndex < iCount;
98        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
99     iTotalIndex++;
100     if (pdfium::ContainsValue(rgNodeSet, pNode)) {
101       iIndex++;
102       rgNodeArray[iIndex] = pNode;
103       rgIdxArray[iIndex] = iTotalIndex;
104     }
105   }
106 }
107 
108 using CXFA_NodeSetPair = std::pair<CXFA_NodeSet, CXFA_NodeSet>;
109 using CXFA_NodeSetPairMap =
110     std::map<uint32_t, std::unique_ptr<CXFA_NodeSetPair>>;
111 using CXFA_NodeSetPairMapMap =
112     std::map<CXFA_Node*, std::unique_ptr<CXFA_NodeSetPairMap>>;
113 
NodeSetPairForNode(CXFA_Node * pNode,CXFA_NodeSetPairMapMap * pMap)114 CXFA_NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode,
115                                      CXFA_NodeSetPairMapMap* pMap) {
116   CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
117   uint32_t dwNameHash = pNode->GetNameHash();
118   if (!pParentNode || !dwNameHash)
119     return nullptr;
120 
121   if (!(*pMap)[pParentNode])
122     (*pMap)[pParentNode] = pdfium::MakeUnique<CXFA_NodeSetPairMap>();
123 
124   CXFA_NodeSetPairMap* pNodeSetPairMap = (*pMap)[pParentNode].get();
125   if (!(*pNodeSetPairMap)[dwNameHash])
126     (*pNodeSetPairMap)[dwNameHash] = pdfium::MakeUnique<CXFA_NodeSetPair>();
127 
128   return (*pNodeSetPairMap)[dwNameHash].get();
129 }
130 
ReorderDataNodes(const CXFA_NodeSet & sSet1,const CXFA_NodeSet & sSet2,bool bInsertBefore)131 void ReorderDataNodes(const CXFA_NodeSet& sSet1,
132                       const CXFA_NodeSet& sSet2,
133                       bool bInsertBefore) {
134   CXFA_NodeSetPairMapMap rgMap;
135   for (CXFA_Node* pNode : sSet1) {
136     CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
137     if (pNodeSetPair)
138       pNodeSetPair->first.insert(pNode);
139   }
140   for (CXFA_Node* pNode : sSet2) {
141     CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
142     if (pNodeSetPair) {
143       if (pdfium::ContainsValue(pNodeSetPair->first, pNode))
144         pNodeSetPair->first.erase(pNode);
145       else
146         pNodeSetPair->second.insert(pNode);
147     }
148   }
149   for (const auto& iter1 : rgMap) {
150     CXFA_NodeSetPairMap* pNodeSetPairMap = iter1.second.get();
151     if (!pNodeSetPairMap)
152       continue;
153 
154     for (const auto& iter2 : *pNodeSetPairMap) {
155       CXFA_NodeSetPair* pNodeSetPair = iter2.second.get();
156       if (!pNodeSetPair)
157         continue;
158       if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) {
159         CXFA_NodeArray rgNodeArray1;
160         CXFA_NodeArray rgNodeArray2;
161         CFX_ArrayTemplate<int32_t> rgIdxArray1;
162         CFX_ArrayTemplate<int32_t> rgIdxArray2;
163         SortNodeArrayByDocumentIdx(pNodeSetPair->first, rgNodeArray1,
164                                    rgIdxArray1);
165         SortNodeArrayByDocumentIdx(pNodeSetPair->second, rgNodeArray2,
166                                    rgIdxArray2);
167         CXFA_Node* pParentNode = nullptr;
168         CXFA_Node* pBeforeNode = nullptr;
169         if (bInsertBefore) {
170           pBeforeNode = rgNodeArray2[0];
171           pParentNode = pBeforeNode->GetNodeItem(XFA_NODEITEM_Parent);
172         } else {
173           CXFA_Node* pLastNode = rgNodeArray2[rgIdxArray2.GetSize() - 1];
174           pParentNode = pLastNode->GetNodeItem(XFA_NODEITEM_Parent);
175           pBeforeNode = pLastNode->GetNodeItem(XFA_NODEITEM_NextSibling);
176         }
177         for (int32_t iIdx = 0; iIdx < rgIdxArray1.GetSize(); iIdx++) {
178           CXFA_Node* pCurNode = rgNodeArray1[iIdx];
179           pParentNode->RemoveChild(pCurNode);
180           pParentNode->InsertChild(pCurNode, pBeforeNode);
181         }
182       }
183     }
184     pNodeSetPairMap->clear();
185   }
186 }
187 
GetItem(CXFA_Node * pInstMgrNode,int32_t iIndex)188 CXFA_Node* GetItem(CXFA_Node* pInstMgrNode, int32_t iIndex) {
189   ASSERT(pInstMgrNode);
190   int32_t iCount = 0;
191   uint32_t dwNameHash = 0;
192   for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
193        pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
194     XFA_Element eCurType = pNode->GetElementType();
195     if (eCurType == XFA_Element::InstanceManager)
196       break;
197     if ((eCurType != XFA_Element::Subform) &&
198         (eCurType != XFA_Element::SubformSet)) {
199       continue;
200     }
201     if (iCount == 0) {
202       CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
203       CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
204       if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
205           wsInstName.Mid(1) != wsName) {
206         return nullptr;
207       }
208       dwNameHash = pNode->GetNameHash();
209     }
210     if (dwNameHash != pNode->GetNameHash())
211       break;
212 
213     iCount++;
214     if (iCount > iIndex)
215       return pNode;
216   }
217   return nullptr;
218 }
219 
InsertItem(CXFA_Node * pInstMgrNode,CXFA_Node * pNewInstance,int32_t iPos,int32_t iCount=-1,bool bMoveDataBindingNodes=true)220 void InsertItem(CXFA_Node* pInstMgrNode,
221                 CXFA_Node* pNewInstance,
222                 int32_t iPos,
223                 int32_t iCount = -1,
224                 bool bMoveDataBindingNodes = true) {
225   if (iCount < 0)
226     iCount = GetCount(pInstMgrNode);
227   if (iPos < 0)
228     iPos = iCount;
229   if (iPos == iCount) {
230     CXFA_Node* pNextSibling =
231         iCount > 0
232             ? GetItem(pInstMgrNode, iCount - 1)
233                   ->GetNodeItem(XFA_NODEITEM_NextSibling)
234             : pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
235     pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
236         ->InsertChild(pNewInstance, pNextSibling);
237     if (bMoveDataBindingNodes) {
238       CXFA_NodeSet sNew;
239       CXFA_NodeSet sAfter;
240       CXFA_NodeIteratorTemplate<CXFA_Node,
241                                 CXFA_TraverseStrategy_XFAContainerNode>
242           sIteratorNew(pNewInstance);
243       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
244            pNode = sIteratorNew.MoveToNext()) {
245         CXFA_Node* pDataNode = pNode->GetBindData();
246         if (!pDataNode)
247           continue;
248 
249         sNew.insert(pDataNode);
250       }
251       CXFA_NodeIteratorTemplate<CXFA_Node,
252                                 CXFA_TraverseStrategy_XFAContainerNode>
253           sIteratorAfter(pNextSibling);
254       for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
255            pNode = sIteratorAfter.MoveToNext()) {
256         CXFA_Node* pDataNode = pNode->GetBindData();
257         if (!pDataNode)
258           continue;
259 
260         sAfter.insert(pDataNode);
261       }
262       ReorderDataNodes(sNew, sAfter, false);
263     }
264   } else {
265     CXFA_Node* pBeforeInstance = GetItem(pInstMgrNode, iPos);
266     pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
267         ->InsertChild(pNewInstance, pBeforeInstance);
268     if (bMoveDataBindingNodes) {
269       CXFA_NodeSet sNew;
270       CXFA_NodeSet sBefore;
271       CXFA_NodeIteratorTemplate<CXFA_Node,
272                                 CXFA_TraverseStrategy_XFAContainerNode>
273           sIteratorNew(pNewInstance);
274       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
275            pNode = sIteratorNew.MoveToNext()) {
276         CXFA_Node* pDataNode = pNode->GetBindData();
277         if (!pDataNode)
278           continue;
279 
280         sNew.insert(pDataNode);
281       }
282       CXFA_NodeIteratorTemplate<CXFA_Node,
283                                 CXFA_TraverseStrategy_XFAContainerNode>
284           sIteratorBefore(pBeforeInstance);
285       for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
286            pNode = sIteratorBefore.MoveToNext()) {
287         CXFA_Node* pDataNode = pNode->GetBindData();
288         if (!pDataNode)
289           continue;
290 
291         sBefore.insert(pDataNode);
292       }
293       ReorderDataNodes(sNew, sBefore, true);
294     }
295   }
296 }
297 
RemoveItem(CXFA_Node * pInstMgrNode,CXFA_Node * pRemoveInstance,bool bRemoveDataBinding=true)298 void RemoveItem(CXFA_Node* pInstMgrNode,
299                 CXFA_Node* pRemoveInstance,
300                 bool bRemoveDataBinding = true) {
301   pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pRemoveInstance);
302   if (!bRemoveDataBinding)
303     return;
304 
305   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
306       sIterator(pRemoveInstance);
307   for (CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode;
308        pFormNode = sIterator.MoveToNext()) {
309     CXFA_Node* pDataNode = pFormNode->GetBindData();
310     if (!pDataNode)
311       continue;
312 
313     if (pDataNode->RemoveBindItem(pFormNode) == 0) {
314       if (CXFA_Node* pDataParent =
315               pDataNode->GetNodeItem(XFA_NODEITEM_Parent)) {
316         pDataParent->RemoveChild(pDataNode);
317       }
318     }
319     pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
320   }
321 }
322 
CreateInstance(CXFA_Node * pInstMgrNode,bool bDataMerge)323 CXFA_Node* CreateInstance(CXFA_Node* pInstMgrNode, bool bDataMerge) {
324   CXFA_Document* pDocument = pInstMgrNode->GetDocument();
325   CXFA_Node* pTemplateNode = pInstMgrNode->GetTemplateNode();
326   CXFA_Node* pFormParent = pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent);
327   CXFA_Node* pDataScope = nullptr;
328   for (CXFA_Node* pRootBoundNode = pFormParent;
329        pRootBoundNode && pRootBoundNode->IsContainerNode();
330        pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
331     pDataScope = pRootBoundNode->GetBindData();
332     if (pDataScope)
333       break;
334   }
335   if (!pDataScope) {
336     pDataScope = ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
337     ASSERT(pDataScope);
338   }
339   CXFA_Node* pInstance = pDocument->DataMerge_CopyContainer(
340       pTemplateNode, pFormParent, pDataScope, true, bDataMerge, true);
341   if (pInstance) {
342     pDocument->DataMerge_UpdateBindingRelations(pInstance);
343     pFormParent->RemoveChild(pInstance);
344   }
345   return pInstance;
346 }
347 
348 struct XFA_ExecEventParaInfo {
349  public:
350   uint32_t m_uHash;
351   const FX_WCHAR* m_lpcEventName;
352   XFA_EVENTTYPE m_eventType;
353   uint32_t m_validFlags;
354 };
355 static const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
356     {0x02a6c55a, L"postSubmit", XFA_EVENT_PostSubmit, 0},
357     {0x0ab466bb, L"preSubmit", XFA_EVENT_PreSubmit, 0},
358     {0x109d7ce7, L"mouseEnter", XFA_EVENT_MouseEnter, 5},
359     {0x17fad373, L"postPrint", XFA_EVENT_PostPrint, 0},
360     {0x1bfc72d9, L"preOpen", XFA_EVENT_PreOpen, 7},
361     {0x2196a452, L"initialize", XFA_EVENT_Initialize, 1},
362     {0x27410f03, L"mouseExit", XFA_EVENT_MouseExit, 5},
363     {0x33c43dec, L"docClose", XFA_EVENT_DocClose, 0},
364     {0x361fa1b6, L"preSave", XFA_EVENT_PreSave, 0},
365     {0x36f1c6d8, L"preSign", XFA_EVENT_PreSign, 6},
366     {0x4731d6ba, L"exit", XFA_EVENT_Exit, 2},
367     {0x56bf456b, L"docReady", XFA_EVENT_DocReady, 0},
368     {0x7233018a, L"validate", XFA_EVENT_Validate, 1},
369     {0x8808385e, L"indexChange", XFA_EVENT_IndexChange, 3},
370     {0x891f4606, L"change", XFA_EVENT_Change, 4},
371     {0x9528a7b4, L"prePrint", XFA_EVENT_PrePrint, 0},
372     {0x9f693b21, L"mouseDown", XFA_EVENT_MouseDown, 5},
373     {0xcdce56b3, L"full", XFA_EVENT_Full, 4},
374     {0xd576d08e, L"mouseUp", XFA_EVENT_MouseUp, 5},
375     {0xd95657a6, L"click", XFA_EVENT_Click, 4},
376     {0xdbfbe02e, L"calculate", XFA_EVENT_Calculate, 1},
377     {0xe25fa7b8, L"postOpen", XFA_EVENT_PostOpen, 7},
378     {0xe28dce7e, L"enter", XFA_EVENT_Enter, 2},
379     {0xfc82d695, L"postSave", XFA_EVENT_PostSave, 0},
380     {0xfd54fbb7, L"postSign", XFA_EVENT_PostSign, 6},
381 };
382 
GetEventParaInfoByName(const CFX_WideStringC & wsEventName)383 const XFA_ExecEventParaInfo* GetEventParaInfoByName(
384     const CFX_WideStringC& wsEventName) {
385   uint32_t uHash = FX_HashCode_GetW(wsEventName, false);
386   int32_t iStart = 0;
387   int32_t iEnd = (sizeof(gs_eventParaInfos) / sizeof(gs_eventParaInfos[0])) - 1;
388   do {
389     int32_t iMid = (iStart + iEnd) / 2;
390     const XFA_ExecEventParaInfo* eventParaInfo = &gs_eventParaInfos[iMid];
391     if (uHash == eventParaInfo->m_uHash)
392       return eventParaInfo;
393     if (uHash < eventParaInfo->m_uHash)
394       iEnd = iMid - 1;
395     else
396       iStart = iMid + 1;
397   } while (iStart <= iEnd);
398   return nullptr;
399 }
400 
StrToRGB(const CFX_WideString & strRGB,int32_t & r,int32_t & g,int32_t & b)401 void StrToRGB(const CFX_WideString& strRGB,
402               int32_t& r,
403               int32_t& g,
404               int32_t& b) {
405   r = 0;
406   g = 0;
407   b = 0;
408 
409   FX_WCHAR zero = '0';
410   int32_t iIndex = 0;
411   int32_t iLen = strRGB.GetLength();
412   for (int32_t i = 0; i < iLen; ++i) {
413     FX_WCHAR ch = strRGB.GetAt(i);
414     if (ch == L',')
415       ++iIndex;
416     if (iIndex > 2)
417       break;
418 
419     int32_t iValue = ch - zero;
420     if (iValue >= 0 && iValue <= 9) {
421       switch (iIndex) {
422         case 0:
423           r = r * 10 + iValue;
424           break;
425         case 1:
426           g = g * 10 + iValue;
427           break;
428         default:
429           b = b * 10 + iValue;
430           break;
431       }
432     }
433   }
434 }
435 
436 enum XFA_KEYTYPE {
437   XFA_KEYTYPE_Custom,
438   XFA_KEYTYPE_Element,
439 };
440 
GetMapKey_Custom(const CFX_WideStringC & wsKey)441 void* GetMapKey_Custom(const CFX_WideStringC& wsKey) {
442   uint32_t dwKey = FX_HashCode_GetW(wsKey, false);
443   return (void*)(uintptr_t)((dwKey << 1) | XFA_KEYTYPE_Custom);
444 }
445 
GetMapKey_Element(XFA_Element eType,XFA_ATTRIBUTE eAttribute)446 void* GetMapKey_Element(XFA_Element eType, XFA_ATTRIBUTE eAttribute) {
447   return (void*)(uintptr_t)((static_cast<int32_t>(eType) << 16) |
448                             (eAttribute << 8) | XFA_KEYTYPE_Element);
449 }
450 
GetAttributeOfElement(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,uint32_t dwPacket)451 const XFA_ATTRIBUTEINFO* GetAttributeOfElement(XFA_Element eElement,
452                                                XFA_ATTRIBUTE eAttribute,
453                                                uint32_t dwPacket) {
454   int32_t iCount = 0;
455   const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
456   if (!pAttr || iCount < 1)
457     return nullptr;
458 
459   if (!std::binary_search(pAttr, pAttr + iCount, eAttribute))
460     return nullptr;
461 
462   const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
463   ASSERT(pInfo);
464   if (dwPacket == XFA_XDPPACKET_UNKNOWN)
465     return pInfo;
466   return (dwPacket & pInfo->dwPackets) ? pInfo : nullptr;
467 }
468 
GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName)469 const XFA_ATTRIBUTEENUMINFO* GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
470   return g_XFAEnumData + eName;
471 }
472 
473 }  // namespace
474 
XFA_DefaultFreeData(void * pData)475 static void XFA_DefaultFreeData(void* pData) {}
476 
477 static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADefaultFreeData = {
478     XFA_DefaultFreeData, nullptr};
479 
XFA_MAPMODULEDATA()480 XFA_MAPMODULEDATA::XFA_MAPMODULEDATA() {}
481 
~XFA_MAPMODULEDATA()482 XFA_MAPMODULEDATA::~XFA_MAPMODULEDATA() {}
483 
CXFA_Node(CXFA_Document * pDoc,uint16_t ePacket,XFA_ObjectType oType,XFA_Element eType,const CFX_WideStringC & elementName)484 CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
485                      uint16_t ePacket,
486                      XFA_ObjectType oType,
487                      XFA_Element eType,
488                      const CFX_WideStringC& elementName)
489     : CXFA_Object(pDoc, oType, eType, elementName),
490       m_pNext(nullptr),
491       m_pChild(nullptr),
492       m_pLastChild(nullptr),
493       m_pParent(nullptr),
494       m_pXMLNode(nullptr),
495       m_ePacket(ePacket),
496       m_uNodeFlags(XFA_NodeFlag_None),
497       m_dwNameHash(0),
498       m_pAuxNode(nullptr),
499       m_pMapModuleData(nullptr) {
500   ASSERT(m_pDocument);
501 }
502 
~CXFA_Node()503 CXFA_Node::~CXFA_Node() {
504   ASSERT(!m_pParent);
505   RemoveMapModuleKey();
506   CXFA_Node* pNode = m_pChild;
507   while (pNode) {
508     CXFA_Node* pNext = pNode->m_pNext;
509     pNode->m_pParent = nullptr;
510     delete pNode;
511     pNode = pNext;
512   }
513   if (m_pXMLNode && IsOwnXMLNode())
514     delete m_pXMLNode;
515 }
516 
Clone(bool bRecursive)517 CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
518   CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
519   if (!pClone)
520     return nullptr;
521 
522   MergeAllData(pClone);
523   pClone->UpdateNameHash();
524   if (IsNeedSavingXMLNode()) {
525     CFDE_XMLNode* pCloneXML = nullptr;
526     if (IsAttributeInXML()) {
527       CFX_WideString wsName;
528       GetAttribute(XFA_ATTRIBUTE_Name, wsName, false);
529       CFDE_XMLElement* pCloneXMLElement = new CFDE_XMLElement(wsName);
530       CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
531       if (!wsValue.IsEmpty()) {
532         pCloneXMLElement->SetTextData(CFX_WideString(wsValue));
533       }
534       pCloneXML = pCloneXMLElement;
535       pCloneXMLElement = nullptr;
536       pClone->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
537     } else {
538       pCloneXML = m_pXMLNode->Clone(false);
539     }
540     pClone->SetXMLMappingNode(pCloneXML);
541     pClone->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
542   }
543   if (bRecursive) {
544     for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
545          pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
546       pClone->InsertChild(pChild->Clone(bRecursive));
547     }
548   }
549   pClone->SetFlag(XFA_NodeFlag_Initialized, true);
550   pClone->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
551   return pClone;
552 }
553 
GetNodeItem(XFA_NODEITEM eItem) const554 CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem) const {
555   switch (eItem) {
556     case XFA_NODEITEM_NextSibling:
557       return m_pNext;
558     case XFA_NODEITEM_FirstChild:
559       return m_pChild;
560     case XFA_NODEITEM_Parent:
561       return m_pParent;
562     case XFA_NODEITEM_PrevSibling:
563       if (m_pParent) {
564         CXFA_Node* pSibling = m_pParent->m_pChild;
565         CXFA_Node* pPrev = nullptr;
566         while (pSibling && pSibling != this) {
567           pPrev = pSibling;
568           pSibling = pSibling->m_pNext;
569         }
570         return pPrev;
571       }
572       return nullptr;
573     default:
574       break;
575   }
576   return nullptr;
577 }
578 
GetNodeItem(XFA_NODEITEM eItem,XFA_ObjectType eType) const579 CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem,
580                                   XFA_ObjectType eType) const {
581   CXFA_Node* pNode = nullptr;
582   switch (eItem) {
583     case XFA_NODEITEM_NextSibling:
584       pNode = m_pNext;
585       while (pNode && pNode->GetObjectType() != eType)
586         pNode = pNode->m_pNext;
587       break;
588     case XFA_NODEITEM_FirstChild:
589       pNode = m_pChild;
590       while (pNode && pNode->GetObjectType() != eType)
591         pNode = pNode->m_pNext;
592       break;
593     case XFA_NODEITEM_Parent:
594       pNode = m_pParent;
595       while (pNode && pNode->GetObjectType() != eType)
596         pNode = pNode->m_pParent;
597       break;
598     case XFA_NODEITEM_PrevSibling:
599       if (m_pParent) {
600         CXFA_Node* pSibling = m_pParent->m_pChild;
601         while (pSibling && pSibling != this) {
602           if (eType == pSibling->GetObjectType())
603             pNode = pSibling;
604 
605           pSibling = pSibling->m_pNext;
606         }
607       }
608       break;
609     default:
610       break;
611   }
612   return pNode;
613 }
614 
GetNodeList(CXFA_NodeArray & nodes,uint32_t dwTypeFilter,XFA_Element eTypeFilter,int32_t iLevel)615 int32_t CXFA_Node::GetNodeList(CXFA_NodeArray& nodes,
616                                uint32_t dwTypeFilter,
617                                XFA_Element eTypeFilter,
618                                int32_t iLevel) {
619   if (--iLevel < 0) {
620     return nodes.GetSize();
621   }
622   if (eTypeFilter != XFA_Element::Unknown) {
623     CXFA_Node* pChild = m_pChild;
624     while (pChild) {
625       if (pChild->GetElementType() == eTypeFilter) {
626         nodes.Add(pChild);
627         if (iLevel > 0) {
628           GetNodeList(nodes, dwTypeFilter, eTypeFilter, iLevel);
629         }
630       }
631       pChild = pChild->m_pNext;
632     }
633   } else if (dwTypeFilter ==
634              (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
635     CXFA_Node* pChild = m_pChild;
636     while (pChild) {
637       nodes.Add(pChild);
638       if (iLevel > 0) {
639         GetNodeList(nodes, dwTypeFilter, eTypeFilter, iLevel);
640       }
641       pChild = pChild->m_pNext;
642     }
643   } else if (dwTypeFilter != 0) {
644     bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children);
645     bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties);
646     bool bFilterOneOfProperties =
647         !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty);
648     CXFA_Node* pChild = m_pChild;
649     while (pChild) {
650       const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
651           GetElementType(), pChild->GetElementType(), XFA_XDPPACKET_UNKNOWN);
652       if (pProperty) {
653         if (bFilterProperties) {
654           nodes.Add(pChild);
655         } else if (bFilterOneOfProperties &&
656                    (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
657           nodes.Add(pChild);
658         } else if (bFilterChildren &&
659                    (pChild->GetElementType() == XFA_Element::Variables ||
660                     pChild->GetElementType() == XFA_Element::PageSet)) {
661           nodes.Add(pChild);
662         }
663       } else if (bFilterChildren) {
664         nodes.Add(pChild);
665       }
666       pChild = pChild->m_pNext;
667     }
668     if (bFilterOneOfProperties && nodes.GetSize() < 1) {
669       int32_t iProperties = 0;
670       const XFA_PROPERTY* pProperty =
671           XFA_GetElementProperties(GetElementType(), iProperties);
672       if (!pProperty || iProperties < 1)
673         return 0;
674       for (int32_t i = 0; i < iProperties; i++) {
675         if (pProperty[i].uFlags & XFA_PROPERTYFLAG_DefaultOneOf) {
676           const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(GetPacketID());
677           CXFA_Node* pNewNode =
678               m_pDocument->CreateNode(pPacket, pProperty[i].eName);
679           if (!pNewNode)
680             break;
681           InsertChild(pNewNode, nullptr);
682           pNewNode->SetFlag(XFA_NodeFlag_Initialized, true);
683           nodes.Add(pNewNode);
684           break;
685         }
686       }
687     }
688   }
689   return nodes.GetSize();
690 }
691 
CreateSamePacketNode(XFA_Element eType,uint32_t dwFlags)692 CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_Element eType,
693                                            uint32_t dwFlags) {
694   CXFA_Node* pNode = m_pDocument->CreateNode(m_ePacket, eType);
695   pNode->SetFlag(dwFlags, true);
696   return pNode;
697 }
698 
CloneTemplateToForm(bool bRecursive)699 CXFA_Node* CXFA_Node::CloneTemplateToForm(bool bRecursive) {
700   ASSERT(m_ePacket == XFA_XDPPACKET_Template);
701   CXFA_Node* pClone =
702       m_pDocument->CreateNode(XFA_XDPPACKET_Form, m_elementType);
703   if (!pClone)
704     return nullptr;
705 
706   pClone->SetTemplateNode(this);
707   pClone->UpdateNameHash();
708   pClone->SetXMLMappingNode(GetXMLMappingNode());
709   if (bRecursive) {
710     for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
711          pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
712       pClone->InsertChild(pChild->CloneTemplateToForm(bRecursive));
713     }
714   }
715   pClone->SetFlag(XFA_NodeFlag_Initialized, true);
716   return pClone;
717 }
718 
GetTemplateNode() const719 CXFA_Node* CXFA_Node::GetTemplateNode() const {
720   return m_pAuxNode;
721 }
722 
SetTemplateNode(CXFA_Node * pTemplateNode)723 void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
724   m_pAuxNode = pTemplateNode;
725 }
726 
GetBindData()727 CXFA_Node* CXFA_Node::GetBindData() {
728   ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
729   return static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
730 }
731 
GetBindItems(CXFA_NodeArray & formItems)732 int32_t CXFA_Node::GetBindItems(CXFA_NodeArray& formItems) {
733   if (BindsFormItems()) {
734     CXFA_NodeArray* pItems = nullptr;
735     TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
736     formItems.Copy(*pItems);
737     return formItems.GetSize();
738   }
739   CXFA_Node* pFormNode =
740       static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
741   if (pFormNode)
742     formItems.Add(pFormNode);
743   return formItems.GetSize();
744 }
745 
AddBindItem(CXFA_Node * pFormNode)746 int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
747   ASSERT(pFormNode);
748   if (BindsFormItems()) {
749     CXFA_NodeArray* pItems = nullptr;
750     TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
751     ASSERT(pItems);
752     if (pItems->Find(pFormNode) < 0) {
753       pItems->Add(pFormNode);
754     }
755     return pItems->GetSize();
756   }
757   CXFA_Node* pOldFormItem =
758       static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
759   if (!pOldFormItem) {
760     SetObject(XFA_ATTRIBUTE_BindingNode, pFormNode);
761     return 1;
762   } else if (pOldFormItem == pFormNode) {
763     return 1;
764   }
765   CXFA_NodeArray* pItems = new CXFA_NodeArray;
766   SetObject(XFA_ATTRIBUTE_BindingNode, pItems, &deleteBindItemCallBack);
767   pItems->Add(pOldFormItem);
768   pItems->Add(pFormNode);
769   m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
770   return 2;
771 }
772 
RemoveBindItem(CXFA_Node * pFormNode)773 int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
774   if (BindsFormItems()) {
775     CXFA_NodeArray* pItems = nullptr;
776     TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
777     ASSERT(pItems);
778     int32_t iIndex = pItems->Find(pFormNode);
779     int32_t iCount = pItems->GetSize();
780     if (iIndex >= 0) {
781       if (iIndex != iCount - 1)
782         pItems->SetAt(iIndex, pItems->GetAt(iCount - 1));
783       pItems->RemoveAt(iCount - 1);
784       if (iCount == 2) {
785         CXFA_Node* pLastFormNode = pItems->GetAt(0);
786         SetObject(XFA_ATTRIBUTE_BindingNode, pLastFormNode);
787         m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
788       }
789       iCount--;
790     }
791     return iCount;
792   }
793   CXFA_Node* pOldFormItem =
794       static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
795   if (pOldFormItem == pFormNode) {
796     SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
797     pOldFormItem = nullptr;
798   }
799   return pOldFormItem ? 1 : 0;
800 }
801 
HasBindItem()802 bool CXFA_Node::HasBindItem() {
803   return GetPacketID() == XFA_XDPPACKET_Datasets &&
804          GetObject(XFA_ATTRIBUTE_BindingNode);
805 }
806 
GetWidgetData()807 CXFA_WidgetData* CXFA_Node::GetWidgetData() {
808   return (CXFA_WidgetData*)GetObject(XFA_ATTRIBUTE_WidgetData);
809 }
810 
GetContainerWidgetData()811 CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
812   if (GetPacketID() != XFA_XDPPACKET_Form)
813     return nullptr;
814   XFA_Element eType = GetElementType();
815   if (eType == XFA_Element::ExclGroup)
816     return nullptr;
817   CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
818   if (pParentNode && pParentNode->GetElementType() == XFA_Element::ExclGroup)
819     return nullptr;
820 
821   if (eType == XFA_Element::Field) {
822     CXFA_WidgetData* pFieldWidgetData = GetWidgetData();
823     if (pFieldWidgetData &&
824         pFieldWidgetData->GetChoiceListOpen() ==
825             XFA_ATTRIBUTEENUM_MultiSelect) {
826       return nullptr;
827     } else {
828       CFX_WideString wsPicture;
829       if (pFieldWidgetData) {
830         pFieldWidgetData->GetPictureContent(wsPicture,
831                                             XFA_VALUEPICTURE_DataBind);
832       }
833       if (!wsPicture.IsEmpty())
834         return pFieldWidgetData;
835       CXFA_Node* pDataNode = GetBindData();
836       if (!pDataNode)
837         return nullptr;
838       pFieldWidgetData = nullptr;
839       CXFA_NodeArray formNodes;
840       pDataNode->GetBindItems(formNodes);
841       for (int32_t i = 0; i < formNodes.GetSize(); i++) {
842         CXFA_Node* pFormNode = formNodes.GetAt(i);
843         if (!pFormNode || pFormNode->HasRemovedChildren())
844           continue;
845         pFieldWidgetData = pFormNode->GetWidgetData();
846         if (pFieldWidgetData) {
847           pFieldWidgetData->GetPictureContent(wsPicture,
848                                               XFA_VALUEPICTURE_DataBind);
849         }
850         if (!wsPicture.IsEmpty())
851           break;
852         pFieldWidgetData = nullptr;
853       }
854       return pFieldWidgetData;
855     }
856   }
857   CXFA_Node* pGrandNode =
858       pParentNode ? pParentNode->GetNodeItem(XFA_NODEITEM_Parent) : nullptr;
859   CXFA_Node* pValueNode =
860       (pParentNode && pParentNode->GetElementType() == XFA_Element::Value)
861           ? pParentNode
862           : nullptr;
863   if (!pValueNode) {
864     pValueNode =
865         (pGrandNode && pGrandNode->GetElementType() == XFA_Element::Value)
866             ? pGrandNode
867             : nullptr;
868   }
869   CXFA_Node* pParentOfValueNode =
870       pValueNode ? pValueNode->GetNodeItem(XFA_NODEITEM_Parent) : nullptr;
871   return pParentOfValueNode ? pParentOfValueNode->GetContainerWidgetData()
872                             : nullptr;
873 }
874 
GetLocaleName(CFX_WideString & wsLocaleName)875 bool CXFA_Node::GetLocaleName(CFX_WideString& wsLocaleName) {
876   CXFA_Node* pForm = GetDocument()->GetXFAObject(XFA_HASHCODE_Form)->AsNode();
877   CXFA_Node* pTopSubform = pForm->GetFirstChildByClass(XFA_Element::Subform);
878   ASSERT(pTopSubform);
879   CXFA_Node* pLocaleNode = this;
880   bool bLocale = false;
881   do {
882     bLocale = pLocaleNode->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, false);
883     if (!bLocale) {
884       pLocaleNode = pLocaleNode->GetNodeItem(XFA_NODEITEM_Parent);
885     }
886   } while (pLocaleNode && pLocaleNode != pTopSubform && !bLocale);
887   if (bLocale)
888     return true;
889   CXFA_Node* pConfig = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
890   wsLocaleName = GetDocument()->GetLocalMgr()->GetConfigLocaleName(pConfig);
891   if (!wsLocaleName.IsEmpty())
892     return true;
893   if (pTopSubform &&
894       pTopSubform->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, false)) {
895     return true;
896   }
897   IFX_Locale* pLocale = GetDocument()->GetLocalMgr()->GetDefLocale();
898   if (pLocale) {
899     wsLocaleName = pLocale->GetName();
900     return true;
901   }
902   return false;
903 }
904 
GetIntact()905 XFA_ATTRIBUTEENUM CXFA_Node::GetIntact() {
906   CXFA_Node* pKeep = GetFirstChildByClass(XFA_Element::Keep);
907   XFA_ATTRIBUTEENUM eLayoutType = GetEnum(XFA_ATTRIBUTE_Layout);
908   if (pKeep) {
909     XFA_ATTRIBUTEENUM eIntact;
910     if (pKeep->TryEnum(XFA_ATTRIBUTE_Intact, eIntact, false)) {
911       if (eIntact == XFA_ATTRIBUTEENUM_None &&
912           eLayoutType == XFA_ATTRIBUTEENUM_Row &&
913           m_pDocument->GetCurVersionMode() < XFA_VERSION_208) {
914         CXFA_Node* pPreviewRow = GetNodeItem(XFA_NODEITEM_PrevSibling,
915                                              XFA_ObjectType::ContainerNode);
916         if (pPreviewRow &&
917             pPreviewRow->GetEnum(XFA_ATTRIBUTE_Layout) ==
918                 XFA_ATTRIBUTEENUM_Row) {
919           XFA_ATTRIBUTEENUM eValue;
920           if (pKeep->TryEnum(XFA_ATTRIBUTE_Previous, eValue, false) &&
921               (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
922                eValue == XFA_ATTRIBUTEENUM_PageArea)) {
923             return XFA_ATTRIBUTEENUM_ContentArea;
924           }
925           CXFA_Node* pNode =
926               pPreviewRow->GetFirstChildByClass(XFA_Element::Keep);
927           if (pNode && pNode->TryEnum(XFA_ATTRIBUTE_Next, eValue, false) &&
928               (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
929                eValue == XFA_ATTRIBUTEENUM_PageArea)) {
930             return XFA_ATTRIBUTEENUM_ContentArea;
931           }
932         }
933       }
934       return eIntact;
935     }
936   }
937   switch (GetElementType()) {
938     case XFA_Element::Subform:
939       switch (eLayoutType) {
940         case XFA_ATTRIBUTEENUM_Position:
941         case XFA_ATTRIBUTEENUM_Row:
942           return XFA_ATTRIBUTEENUM_ContentArea;
943         case XFA_ATTRIBUTEENUM_Tb:
944         case XFA_ATTRIBUTEENUM_Table:
945         case XFA_ATTRIBUTEENUM_Lr_tb:
946         case XFA_ATTRIBUTEENUM_Rl_tb:
947           return XFA_ATTRIBUTEENUM_None;
948         default:
949           break;
950       }
951       break;
952     case XFA_Element::Field: {
953       CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
954       if (!pParentNode ||
955           pParentNode->GetElementType() == XFA_Element::PageArea)
956         return XFA_ATTRIBUTEENUM_ContentArea;
957       if (pParentNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
958         XFA_ATTRIBUTEENUM eParLayout =
959             pParentNode->GetEnum(XFA_ATTRIBUTE_Layout);
960         if (eParLayout == XFA_ATTRIBUTEENUM_Position ||
961             eParLayout == XFA_ATTRIBUTEENUM_Row ||
962             eParLayout == XFA_ATTRIBUTEENUM_Table) {
963           return XFA_ATTRIBUTEENUM_None;
964         }
965         XFA_VERSION version = m_pDocument->GetCurVersionMode();
966         if (eParLayout == XFA_ATTRIBUTEENUM_Tb && version < XFA_VERSION_208) {
967           CXFA_Measurement measureH;
968           if (TryMeasure(XFA_ATTRIBUTE_H, measureH, false))
969             return XFA_ATTRIBUTEENUM_ContentArea;
970         }
971         return XFA_ATTRIBUTEENUM_None;
972       }
973       return XFA_ATTRIBUTEENUM_ContentArea;
974     }
975     case XFA_Element::Draw:
976       return XFA_ATTRIBUTEENUM_ContentArea;
977     default:
978       break;
979   }
980   return XFA_ATTRIBUTEENUM_None;
981 }
982 
GetDataDescriptionNode()983 CXFA_Node* CXFA_Node::GetDataDescriptionNode() {
984   if (m_ePacket == XFA_XDPPACKET_Datasets)
985     return m_pAuxNode;
986   return nullptr;
987 }
988 
SetDataDescriptionNode(CXFA_Node * pDataDescriptionNode)989 void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode) {
990   ASSERT(m_ePacket == XFA_XDPPACKET_Datasets);
991   m_pAuxNode = pDataDescriptionNode;
992 }
993 
Script_TreeClass_ResolveNode(CFXJSE_Arguments * pArguments)994 void CXFA_Node::Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments) {
995   int32_t iLength = pArguments->GetLength();
996   if (iLength != 1) {
997     ThrowParamCountMismatchException(L"resolveNode");
998     return;
999   }
1000   CFX_WideString wsExpression =
1001       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1002   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1003   if (!pScriptContext)
1004     return;
1005   CXFA_Node* refNode = this;
1006   if (refNode->GetElementType() == XFA_Element::Xfa)
1007     refNode = ToNode(pScriptContext->GetThisObject());
1008   uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
1009                     XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1010                     XFA_RESOLVENODE_Siblings;
1011   XFA_RESOLVENODE_RS resoveNodeRS;
1012   int32_t iRet = pScriptContext->ResolveObjects(
1013       refNode, wsExpression.AsStringC(), resoveNodeRS, dwFlag);
1014   if (iRet < 1) {
1015     pArguments->GetReturnValue()->SetNull();
1016     return;
1017   }
1018   if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
1019     CXFA_Object* pNode = resoveNodeRS.nodes[0];
1020     pArguments->GetReturnValue()->Assign(
1021         pScriptContext->GetJSValueFromMap(pNode));
1022   } else {
1023     const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
1024         resoveNodeRS.pScriptAttribute;
1025     if (lpAttributeInfo && lpAttributeInfo->eValueType == XFA_SCRIPT_Object) {
1026       std::unique_ptr<CFXJSE_Value> pValue(
1027           new CFXJSE_Value(pScriptContext->GetRuntime()));
1028       (resoveNodeRS.nodes[0]->*(lpAttributeInfo->lpfnCallback))(
1029           pValue.get(), false, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
1030       pArguments->GetReturnValue()->Assign(pValue.get());
1031     } else {
1032       pArguments->GetReturnValue()->SetNull();
1033     }
1034   }
1035 }
1036 
Script_TreeClass_ResolveNodes(CFXJSE_Arguments * pArguments)1037 void CXFA_Node::Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments) {
1038   int32_t iLength = pArguments->GetLength();
1039   if (iLength != 1) {
1040     ThrowParamCountMismatchException(L"resolveNodes");
1041     return;
1042   }
1043   CFX_WideString wsExpression =
1044       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1045   CFXJSE_Value* pValue = pArguments->GetReturnValue();
1046   if (!pValue)
1047     return;
1048   uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
1049                     XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1050                     XFA_RESOLVENODE_Siblings;
1051   CXFA_Node* refNode = this;
1052   if (refNode->GetElementType() == XFA_Element::Xfa)
1053     refNode = ToNode(m_pDocument->GetScriptContext()->GetThisObject());
1054   Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag, refNode);
1055 }
1056 
Script_Som_ResolveNodeList(CFXJSE_Value * pValue,CFX_WideString wsExpression,uint32_t dwFlag,CXFA_Node * refNode)1057 void CXFA_Node::Script_Som_ResolveNodeList(CFXJSE_Value* pValue,
1058                                            CFX_WideString wsExpression,
1059                                            uint32_t dwFlag,
1060                                            CXFA_Node* refNode) {
1061   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1062   if (!pScriptContext)
1063     return;
1064   XFA_RESOLVENODE_RS resoveNodeRS;
1065   if (!refNode)
1066     refNode = this;
1067   pScriptContext->ResolveObjects(refNode, wsExpression.AsStringC(),
1068                                  resoveNodeRS, dwFlag);
1069   CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(m_pDocument);
1070   if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
1071     for (int32_t i = 0; i < resoveNodeRS.nodes.GetSize(); i++) {
1072       if (resoveNodeRS.nodes[i]->IsNode())
1073         pNodeList->Append(resoveNodeRS.nodes[i]->AsNode());
1074     }
1075   } else {
1076     CXFA_ValueArray valueArray(pScriptContext->GetRuntime());
1077     if (resoveNodeRS.GetAttributeResult(valueArray) > 0) {
1078       CXFA_ObjArray objectArray;
1079       valueArray.GetAttributeObject(objectArray);
1080       for (int32_t i = 0; i < objectArray.GetSize(); i++) {
1081         if (objectArray[i]->IsNode())
1082           pNodeList->Append(objectArray[i]->AsNode());
1083       }
1084     }
1085   }
1086   pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
1087 }
1088 
Script_TreeClass_All(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1089 void CXFA_Node::Script_TreeClass_All(CFXJSE_Value* pValue,
1090                                      bool bSetting,
1091                                      XFA_ATTRIBUTE eAttribute) {
1092   if (bSetting) {
1093     ThrowInvalidPropertyException();
1094     return;
1095   }
1096 
1097   uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
1098   CFX_WideString wsName;
1099   GetAttribute(XFA_ATTRIBUTE_Name, wsName);
1100   CFX_WideString wsExpression = wsName + L"[*]";
1101   Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag);
1102 }
1103 
Script_TreeClass_Nodes(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1104 void CXFA_Node::Script_TreeClass_Nodes(CFXJSE_Value* pValue,
1105                                        bool bSetting,
1106                                        XFA_ATTRIBUTE eAttribute) {
1107   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1108   if (!pScriptContext)
1109     return;
1110   if (bSetting) {
1111     CFX_WideString wsMessage = L"Unable to set ";
1112     FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC());
1113   } else {
1114     CXFA_AttachNodeList* pNodeList = new CXFA_AttachNodeList(m_pDocument, this);
1115     pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
1116   }
1117 }
1118 
Script_TreeClass_ClassAll(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1119 void CXFA_Node::Script_TreeClass_ClassAll(CFXJSE_Value* pValue,
1120                                           bool bSetting,
1121                                           XFA_ATTRIBUTE eAttribute) {
1122   if (bSetting) {
1123     ThrowInvalidPropertyException();
1124     return;
1125   }
1126   uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
1127   CFX_WideString wsExpression = L"#" + GetClassName() + L"[*]";
1128   Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag);
1129 }
1130 
Script_TreeClass_Parent(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1131 void CXFA_Node::Script_TreeClass_Parent(CFXJSE_Value* pValue,
1132                                         bool bSetting,
1133                                         XFA_ATTRIBUTE eAttribute) {
1134   if (bSetting) {
1135     ThrowInvalidPropertyException();
1136     return;
1137   }
1138   CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
1139   if (pParent) {
1140     pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pParent));
1141   } else {
1142     pValue->SetNull();
1143   }
1144 }
1145 
Script_TreeClass_Index(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1146 void CXFA_Node::Script_TreeClass_Index(CFXJSE_Value* pValue,
1147                                        bool bSetting,
1148                                        XFA_ATTRIBUTE eAttribute) {
1149   if (bSetting) {
1150     ThrowInvalidPropertyException();
1151     return;
1152   }
1153   pValue->SetInteger(GetNodeSameNameIndex());
1154 }
1155 
Script_TreeClass_ClassIndex(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1156 void CXFA_Node::Script_TreeClass_ClassIndex(CFXJSE_Value* pValue,
1157                                             bool bSetting,
1158                                             XFA_ATTRIBUTE eAttribute) {
1159   if (bSetting) {
1160     ThrowInvalidPropertyException();
1161     return;
1162   }
1163   pValue->SetInteger(GetNodeSameClassIndex());
1164 }
1165 
Script_TreeClass_SomExpression(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1166 void CXFA_Node::Script_TreeClass_SomExpression(CFXJSE_Value* pValue,
1167                                                bool bSetting,
1168                                                XFA_ATTRIBUTE eAttribute) {
1169   if (bSetting) {
1170     ThrowInvalidPropertyException();
1171     return;
1172   }
1173   CFX_WideString wsSOMExpression;
1174   GetSOMExpression(wsSOMExpression);
1175   pValue->SetString(wsSOMExpression.UTF8Encode().AsStringC());
1176 }
1177 
Script_NodeClass_ApplyXSL(CFXJSE_Arguments * pArguments)1178 void CXFA_Node::Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments) {
1179   int32_t iLength = pArguments->GetLength();
1180   if (iLength != 1) {
1181     ThrowParamCountMismatchException(L"applyXSL");
1182     return;
1183   }
1184   CFX_WideString wsExpression =
1185       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1186   // TODO(weili): check whether we need to implement this, pdfium:501.
1187   // For now, just put the variables here to avoid unused variable warning.
1188   (void)wsExpression;
1189 }
1190 
Script_NodeClass_AssignNode(CFXJSE_Arguments * pArguments)1191 void CXFA_Node::Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments) {
1192   int32_t iLength = pArguments->GetLength();
1193   if (iLength < 1 || iLength > 3) {
1194     ThrowParamCountMismatchException(L"assignNode");
1195     return;
1196   }
1197   CFX_WideString wsExpression;
1198   CFX_WideString wsValue;
1199   int32_t iAction = 0;
1200   wsExpression =
1201       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1202   if (iLength >= 2) {
1203     wsValue =
1204         CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1205   }
1206   if (iLength >= 3)
1207     iAction = pArguments->GetInt32(2);
1208   // TODO(weili): check whether we need to implement this, pdfium:501.
1209   // For now, just put the variables here to avoid unused variable warning.
1210   (void)wsExpression;
1211   (void)wsValue;
1212   (void)iAction;
1213 }
1214 
Script_NodeClass_Clone(CFXJSE_Arguments * pArguments)1215 void CXFA_Node::Script_NodeClass_Clone(CFXJSE_Arguments* pArguments) {
1216   int32_t iLength = pArguments->GetLength();
1217   if (iLength != 1) {
1218     ThrowParamCountMismatchException(L"clone");
1219     return;
1220   }
1221   bool bClone = !!pArguments->GetInt32(0);
1222   CXFA_Node* pCloneNode = Clone(bClone);
1223   pArguments->GetReturnValue()->Assign(
1224       m_pDocument->GetScriptContext()->GetJSValueFromMap(pCloneNode));
1225 }
1226 
Script_NodeClass_GetAttribute(CFXJSE_Arguments * pArguments)1227 void CXFA_Node::Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments) {
1228   int32_t iLength = pArguments->GetLength();
1229   if (iLength != 1) {
1230     ThrowParamCountMismatchException(L"getAttribute");
1231     return;
1232   }
1233   CFX_WideString wsExpression =
1234       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1235   CFX_WideString wsValue;
1236   GetAttribute(wsExpression.AsStringC(), wsValue);
1237   CFXJSE_Value* pValue = pArguments->GetReturnValue();
1238   if (pValue)
1239     pValue->SetString(wsValue.UTF8Encode().AsStringC());
1240 }
1241 
Script_NodeClass_GetElement(CFXJSE_Arguments * pArguments)1242 void CXFA_Node::Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments) {
1243   int32_t iLength = pArguments->GetLength();
1244   if (iLength < 1 || iLength > 2) {
1245     ThrowParamCountMismatchException(L"getElement");
1246     return;
1247   }
1248   CFX_WideString wsExpression;
1249   int32_t iValue = 0;
1250   wsExpression =
1251       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1252   if (iLength >= 2)
1253     iValue = pArguments->GetInt32(1);
1254   CXFA_Node* pNode =
1255       GetProperty(iValue, XFA_GetElementTypeForName(wsExpression.AsStringC()));
1256   pArguments->GetReturnValue()->Assign(
1257       m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
1258 }
1259 
Script_NodeClass_IsPropertySpecified(CFXJSE_Arguments * pArguments)1260 void CXFA_Node::Script_NodeClass_IsPropertySpecified(
1261     CFXJSE_Arguments* pArguments) {
1262   int32_t iLength = pArguments->GetLength();
1263   if (iLength < 1 || iLength > 3) {
1264     ThrowParamCountMismatchException(L"isPropertySpecified");
1265     return;
1266   }
1267   CFX_WideString wsExpression;
1268   bool bParent = true;
1269   int32_t iIndex = 0;
1270   wsExpression =
1271       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1272   if (iLength >= 2)
1273     bParent = !!pArguments->GetInt32(1);
1274   if (iLength >= 3)
1275     iIndex = pArguments->GetInt32(2);
1276   bool bHas = false;
1277   const XFA_ATTRIBUTEINFO* pAttributeInfo =
1278       XFA_GetAttributeByName(wsExpression.AsStringC());
1279   CFX_WideString wsValue;
1280   if (pAttributeInfo)
1281     bHas = HasAttribute(pAttributeInfo->eName);
1282   if (!bHas) {
1283     XFA_Element eType = XFA_GetElementTypeForName(wsExpression.AsStringC());
1284     bHas = !!GetProperty(iIndex, eType);
1285     if (!bHas && bParent && m_pParent) {
1286       // Also check on the parent.
1287       bHas = m_pParent->HasAttribute(pAttributeInfo->eName);
1288       if (!bHas)
1289         bHas = !!m_pParent->GetProperty(iIndex, eType);
1290     }
1291   }
1292   CFXJSE_Value* pValue = pArguments->GetReturnValue();
1293   if (pValue)
1294     pValue->SetBoolean(bHas);
1295 }
1296 
Script_NodeClass_LoadXML(CFXJSE_Arguments * pArguments)1297 void CXFA_Node::Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments) {
1298   int32_t iLength = pArguments->GetLength();
1299   if (iLength < 1 || iLength > 3) {
1300     ThrowParamCountMismatchException(L"loadXML");
1301     return;
1302   }
1303   CFX_WideString wsExpression;
1304   bool bIgnoreRoot = true;
1305   bool bOverwrite = 0;
1306   wsExpression =
1307       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1308   if (wsExpression.IsEmpty())
1309     return;
1310   if (iLength >= 2)
1311     bIgnoreRoot = !!pArguments->GetInt32(1);
1312   if (iLength >= 3)
1313     bOverwrite = !!pArguments->GetInt32(2);
1314   std::unique_ptr<CXFA_SimpleParser> pParser(
1315       new CXFA_SimpleParser(m_pDocument, false));
1316   if (!pParser)
1317     return;
1318   CFDE_XMLNode* pXMLNode = nullptr;
1319   int32_t iParserStatus =
1320       pParser->ParseXMLData(wsExpression, pXMLNode, nullptr);
1321   if (iParserStatus != XFA_PARSESTATUS_Done || !pXMLNode)
1322     return;
1323   if (bIgnoreRoot &&
1324       (pXMLNode->GetType() != FDE_XMLNODE_Element ||
1325        XFA_RecognizeRichText(static_cast<CFDE_XMLElement*>(pXMLNode)))) {
1326     bIgnoreRoot = false;
1327   }
1328   CXFA_Node* pFakeRoot = Clone(false);
1329   CFX_WideStringC wsContentType = GetCData(XFA_ATTRIBUTE_ContentType);
1330   if (!wsContentType.IsEmpty()) {
1331     pFakeRoot->SetCData(XFA_ATTRIBUTE_ContentType,
1332                         CFX_WideString(wsContentType));
1333   }
1334   CFDE_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
1335   if (!pFakeXMLRoot) {
1336     CFDE_XMLNode* pThisXMLRoot = GetXMLMappingNode();
1337     pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone(false) : nullptr;
1338   }
1339   if (!pFakeXMLRoot)
1340     pFakeXMLRoot = new CFDE_XMLElement(CFX_WideString(GetClassName()));
1341 
1342   if (bIgnoreRoot) {
1343     CFDE_XMLNode* pXMLChild = pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
1344     while (pXMLChild) {
1345       CFDE_XMLNode* pXMLSibling =
1346           pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling);
1347       pXMLNode->RemoveChildNode(pXMLChild);
1348       pFakeXMLRoot->InsertChildNode(pXMLChild);
1349       pXMLChild = pXMLSibling;
1350     }
1351   } else {
1352     CFDE_XMLNode* pXMLParent = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
1353     if (pXMLParent) {
1354       pXMLParent->RemoveChildNode(pXMLNode);
1355     }
1356     pFakeXMLRoot->InsertChildNode(pXMLNode);
1357   }
1358   pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
1359   pFakeRoot = pParser->GetRootNode();
1360   if (pFakeRoot) {
1361     if (bOverwrite) {
1362       CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild);
1363       CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1364       int32_t index = 0;
1365       while (pNewChild) {
1366         CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1367         pFakeRoot->RemoveChild(pNewChild);
1368         InsertChild(index++, pNewChild);
1369         pNewChild->SetFlag(XFA_NodeFlag_Initialized, true);
1370         pNewChild = pItem;
1371       }
1372       while (pChild) {
1373         CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1374         RemoveChild(pChild);
1375         pFakeRoot->InsertChild(pChild);
1376         pChild = pItem;
1377       }
1378       if (GetPacketID() == XFA_XDPPACKET_Form &&
1379           GetElementType() == XFA_Element::ExData) {
1380         CFDE_XMLNode* pTempXMLNode = GetXMLMappingNode();
1381         SetXMLMappingNode(pFakeXMLRoot);
1382         SetFlag(XFA_NodeFlag_OwnXMLNode, false);
1383         if (pTempXMLNode && !pTempXMLNode->GetNodeItem(CFDE_XMLNode::Parent)) {
1384           pFakeXMLRoot = pTempXMLNode;
1385         } else {
1386           pFakeXMLRoot = nullptr;
1387         }
1388       }
1389       MoveBufferMapData(pFakeRoot, this, XFA_CalcData, true);
1390     } else {
1391       CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1392       while (pChild) {
1393         CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1394         pFakeRoot->RemoveChild(pChild);
1395         InsertChild(pChild);
1396         pChild->SetFlag(XFA_NodeFlag_Initialized, true);
1397         pChild = pItem;
1398       }
1399     }
1400     if (pFakeXMLRoot) {
1401       pFakeRoot->SetXMLMappingNode(pFakeXMLRoot);
1402       pFakeRoot->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
1403     }
1404     pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false);
1405   } else {
1406     delete pFakeXMLRoot;
1407     pFakeXMLRoot = nullptr;
1408   }
1409 }
1410 
Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments * pArguments)1411 void CXFA_Node::Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments) {
1412   // TODO(weili): Check whether we need to implement this, pdfium:501.
1413 }
1414 
Script_NodeClass_SaveXML(CFXJSE_Arguments * pArguments)1415 void CXFA_Node::Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments) {
1416   int32_t iLength = pArguments->GetLength();
1417   if (iLength < 0 || iLength > 1) {
1418     ThrowParamCountMismatchException(L"saveXML");
1419     return;
1420   }
1421   bool bPrettyMode = false;
1422   if (iLength == 1) {
1423     if (pArguments->GetUTF8String(0) != "pretty") {
1424       ThrowArgumentMismatchException();
1425       return;
1426     }
1427     bPrettyMode = true;
1428   }
1429   CFX_ByteStringC bsXMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
1430   if (GetPacketID() == XFA_XDPPACKET_Form ||
1431       GetPacketID() == XFA_XDPPACKET_Datasets) {
1432     CFDE_XMLNode* pElement = nullptr;
1433     if (GetPacketID() == XFA_XDPPACKET_Datasets) {
1434       pElement = GetXMLMappingNode();
1435       if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
1436         pArguments->GetReturnValue()->SetString(bsXMLHeader);
1437         return;
1438       }
1439       XFA_DataExporter_DealWithDataGroupNode(this);
1440     }
1441     CFX_RetainPtr<IFX_MemoryStream> pMemoryStream =
1442         IFX_MemoryStream::Create(true);
1443 
1444     // Note: ambiguious below without static_cast.
1445     CFX_RetainPtr<IFGAS_Stream> pStream = IFGAS_Stream::CreateStream(
1446         CFX_RetainPtr<IFX_SeekableWriteStream>(pMemoryStream),
1447         FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
1448 
1449     if (!pStream) {
1450       pArguments->GetReturnValue()->SetString(bsXMLHeader);
1451       return;
1452     }
1453     pStream->SetCodePage(FX_CODEPAGE_UTF8);
1454     pStream->WriteData(bsXMLHeader.raw_str(), bsXMLHeader.GetLength());
1455     if (GetPacketID() == XFA_XDPPACKET_Form)
1456       XFA_DataExporter_RegenerateFormFile(this, pStream, nullptr, true);
1457     else
1458       pElement->SaveXMLNode(pStream);
1459     // TODO(weili): Check whether we need to save pretty print XML, pdfium:501.
1460     // For now, just put it here to avoid unused variable warning.
1461     (void)bPrettyMode;
1462     pArguments->GetReturnValue()->SetString(
1463         CFX_ByteStringC(pMemoryStream->GetBuffer(), pMemoryStream->GetSize()));
1464     return;
1465   }
1466   pArguments->GetReturnValue()->SetString("");
1467 }
1468 
Script_NodeClass_SetAttribute(CFXJSE_Arguments * pArguments)1469 void CXFA_Node::Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments) {
1470   int32_t iLength = pArguments->GetLength();
1471   if (iLength != 2) {
1472     ThrowParamCountMismatchException(L"setAttribute");
1473     return;
1474   }
1475   CFX_WideString wsAttributeValue =
1476       CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1477   CFX_WideString wsAttribute =
1478       CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1479   SetAttribute(wsAttribute.AsStringC(), wsAttributeValue.AsStringC(), true);
1480 }
1481 
Script_NodeClass_SetElement(CFXJSE_Arguments * pArguments)1482 void CXFA_Node::Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments) {
1483   int32_t iLength = pArguments->GetLength();
1484   if (iLength != 1 && iLength != 2) {
1485     ThrowParamCountMismatchException(L"setElement");
1486     return;
1487   }
1488   CXFA_Node* pNode = nullptr;
1489   CFX_WideString wsName;
1490   pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
1491   if (iLength == 2)
1492     wsName = CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1493   // TODO(weili): check whether we need to implement this, pdfium:501.
1494   // For now, just put the variables here to avoid unused variable warning.
1495   (void)pNode;
1496   (void)wsName;
1497 }
1498 
Script_NodeClass_Ns(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1499 void CXFA_Node::Script_NodeClass_Ns(CFXJSE_Value* pValue,
1500                                     bool bSetting,
1501                                     XFA_ATTRIBUTE eAttribute) {
1502   if (bSetting) {
1503     ThrowInvalidPropertyException();
1504     return;
1505   }
1506 
1507   CFX_WideString wsNameSpace;
1508   TryNamespace(wsNameSpace);
1509   pValue->SetString(wsNameSpace.UTF8Encode().AsStringC());
1510 }
1511 
Script_NodeClass_Model(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1512 void CXFA_Node::Script_NodeClass_Model(CFXJSE_Value* pValue,
1513                                        bool bSetting,
1514                                        XFA_ATTRIBUTE eAttribute) {
1515   if (bSetting) {
1516     ThrowInvalidPropertyException();
1517     return;
1518   }
1519   pValue->Assign(
1520       m_pDocument->GetScriptContext()->GetJSValueFromMap(GetModelNode()));
1521 }
1522 
Script_NodeClass_IsContainer(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1523 void CXFA_Node::Script_NodeClass_IsContainer(CFXJSE_Value* pValue,
1524                                              bool bSetting,
1525                                              XFA_ATTRIBUTE eAttribute) {
1526   if (bSetting) {
1527     ThrowInvalidPropertyException();
1528     return;
1529   }
1530   pValue->SetBoolean(IsContainerNode());
1531 }
1532 
Script_NodeClass_IsNull(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1533 void CXFA_Node::Script_NodeClass_IsNull(CFXJSE_Value* pValue,
1534                                         bool bSetting,
1535                                         XFA_ATTRIBUTE eAttribute) {
1536   if (bSetting) {
1537     ThrowInvalidPropertyException();
1538     return;
1539   }
1540   if (GetElementType() == XFA_Element::Subform) {
1541     pValue->SetBoolean(false);
1542     return;
1543   }
1544   CFX_WideString strValue;
1545   pValue->SetBoolean(!TryContent(strValue) || strValue.IsEmpty());
1546 }
1547 
Script_NodeClass_OneOfChild(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1548 void CXFA_Node::Script_NodeClass_OneOfChild(CFXJSE_Value* pValue,
1549                                             bool bSetting,
1550                                             XFA_ATTRIBUTE eAttribute) {
1551   if (bSetting) {
1552     ThrowInvalidPropertyException();
1553     return;
1554   }
1555 
1556   CXFA_NodeArray properts;
1557   int32_t iSize = GetNodeList(properts, XFA_NODEFILTER_OneOfProperty);
1558   if (iSize > 0) {
1559     pValue->Assign(
1560         m_pDocument->GetScriptContext()->GetJSValueFromMap(properts[0]));
1561   }
1562 }
1563 
Script_ContainerClass_GetDelta(CFXJSE_Arguments * pArguments)1564 void CXFA_Node::Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments) {}
1565 
Script_ContainerClass_GetDeltas(CFXJSE_Arguments * pArguments)1566 void CXFA_Node::Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments) {
1567   CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
1568   pArguments->GetReturnValue()->SetObject(
1569       pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
1570 }
Script_ModelClass_ClearErrorList(CFXJSE_Arguments * pArguments)1571 void CXFA_Node::Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments) {
1572 }
1573 
Script_ModelClass_CreateNode(CFXJSE_Arguments * pArguments)1574 void CXFA_Node::Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments) {
1575   Script_Template_CreateNode(pArguments);
1576 }
1577 
Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments * pArguments)1578 void CXFA_Node::Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments) {
1579   int32_t iLength = pArguments->GetLength();
1580   if (iLength < 1) {
1581     ThrowParamCountMismatchException(L"isCompatibleNS");
1582     return;
1583   }
1584   CFX_WideString wsNameSpace;
1585   if (iLength >= 1) {
1586     CFX_ByteString bsNameSpace = pArguments->GetUTF8String(0);
1587     wsNameSpace = CFX_WideString::FromUTF8(bsNameSpace.AsStringC());
1588   }
1589   CFX_WideString wsNodeNameSpace;
1590   TryNamespace(wsNodeNameSpace);
1591   CFXJSE_Value* pValue = pArguments->GetReturnValue();
1592   if (pValue)
1593     pValue->SetBoolean(wsNodeNameSpace == wsNameSpace);
1594 }
1595 
Script_ModelClass_Context(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1596 void CXFA_Node::Script_ModelClass_Context(CFXJSE_Value* pValue,
1597                                           bool bSetting,
1598                                           XFA_ATTRIBUTE eAttribute) {}
1599 
Script_ModelClass_AliasNode(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1600 void CXFA_Node::Script_ModelClass_AliasNode(CFXJSE_Value* pValue,
1601                                             bool bSetting,
1602                                             XFA_ATTRIBUTE eAttribute) {}
1603 
Script_Attribute_Integer(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1604 void CXFA_Node::Script_Attribute_Integer(CFXJSE_Value* pValue,
1605                                          bool bSetting,
1606                                          XFA_ATTRIBUTE eAttribute) {
1607   if (bSetting) {
1608     SetInteger(eAttribute, pValue->ToInteger(), true);
1609   } else {
1610     pValue->SetInteger(GetInteger(eAttribute));
1611   }
1612 }
1613 
Script_Attribute_IntegerRead(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1614 void CXFA_Node::Script_Attribute_IntegerRead(CFXJSE_Value* pValue,
1615                                              bool bSetting,
1616                                              XFA_ATTRIBUTE eAttribute) {
1617   if (bSetting) {
1618     ThrowInvalidPropertyException();
1619     return;
1620   }
1621   pValue->SetInteger(GetInteger(eAttribute));
1622 }
1623 
Script_Attribute_BOOL(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1624 void CXFA_Node::Script_Attribute_BOOL(CFXJSE_Value* pValue,
1625                                       bool bSetting,
1626                                       XFA_ATTRIBUTE eAttribute) {
1627   if (bSetting) {
1628     SetBoolean(eAttribute, pValue->ToBoolean(), true);
1629   } else {
1630     pValue->SetString(GetBoolean(eAttribute) ? "1" : "0");
1631   }
1632 }
1633 
Script_Attribute_BOOLRead(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1634 void CXFA_Node::Script_Attribute_BOOLRead(CFXJSE_Value* pValue,
1635                                           bool bSetting,
1636                                           XFA_ATTRIBUTE eAttribute) {
1637   if (bSetting) {
1638     ThrowInvalidPropertyException();
1639     return;
1640   }
1641   pValue->SetString(GetBoolean(eAttribute) ? "1" : "0");
1642 }
1643 
Script_Attribute_SendAttributeChangeMessage(XFA_ATTRIBUTE eAttribute,bool bScriptModify)1644 void CXFA_Node::Script_Attribute_SendAttributeChangeMessage(
1645     XFA_ATTRIBUTE eAttribute,
1646     bool bScriptModify) {
1647   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
1648   if (!pLayoutPro)
1649     return;
1650 
1651   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1652   if (!pNotify)
1653     return;
1654 
1655   uint32_t dwPacket = GetPacketID();
1656   if (!(dwPacket & XFA_XDPPACKET_Form)) {
1657     pNotify->OnValueChanged(this, eAttribute, this, this);
1658     return;
1659   }
1660 
1661   bool bNeedFindContainer = false;
1662   switch (GetElementType()) {
1663     case XFA_Element::Caption:
1664       bNeedFindContainer = true;
1665       pNotify->OnValueChanged(this, eAttribute, this,
1666                               GetNodeItem(XFA_NODEITEM_Parent));
1667       break;
1668     case XFA_Element::Font:
1669     case XFA_Element::Para: {
1670       bNeedFindContainer = true;
1671       CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
1672       if (pParentNode->GetElementType() == XFA_Element::Caption) {
1673         pNotify->OnValueChanged(this, eAttribute, pParentNode,
1674                                 pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
1675       } else {
1676         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
1677       }
1678     } break;
1679     case XFA_Element::Margin: {
1680       bNeedFindContainer = true;
1681       CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
1682       XFA_Element eParentType = pParentNode->GetElementType();
1683       if (pParentNode->IsContainerNode()) {
1684         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
1685       } else if (eParentType == XFA_Element::Caption) {
1686         pNotify->OnValueChanged(this, eAttribute, pParentNode,
1687                                 pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
1688       } else {
1689         CXFA_Node* pNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
1690         if (pNode && pNode->GetElementType() == XFA_Element::Ui) {
1691           pNotify->OnValueChanged(this, eAttribute, pNode,
1692                                   pNode->GetNodeItem(XFA_NODEITEM_Parent));
1693         }
1694       }
1695     } break;
1696     case XFA_Element::Comb: {
1697       CXFA_Node* pEditNode = GetNodeItem(XFA_NODEITEM_Parent);
1698       XFA_Element eUIType = pEditNode->GetElementType();
1699       if (pEditNode && (eUIType == XFA_Element::DateTimeEdit ||
1700                         eUIType == XFA_Element::NumericEdit ||
1701                         eUIType == XFA_Element::TextEdit)) {
1702         CXFA_Node* pUINode = pEditNode->GetNodeItem(XFA_NODEITEM_Parent);
1703         if (pUINode) {
1704           pNotify->OnValueChanged(this, eAttribute, pUINode,
1705                                   pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1706         }
1707       }
1708     } break;
1709     case XFA_Element::Button:
1710     case XFA_Element::Barcode:
1711     case XFA_Element::ChoiceList:
1712     case XFA_Element::DateTimeEdit:
1713     case XFA_Element::NumericEdit:
1714     case XFA_Element::PasswordEdit:
1715     case XFA_Element::TextEdit: {
1716       CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
1717       if (pUINode) {
1718         pNotify->OnValueChanged(this, eAttribute, pUINode,
1719                                 pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1720       }
1721     } break;
1722     case XFA_Element::CheckButton: {
1723       bNeedFindContainer = true;
1724       CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
1725       if (pUINode) {
1726         pNotify->OnValueChanged(this, eAttribute, pUINode,
1727                                 pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1728       }
1729     } break;
1730     case XFA_Element::Keep:
1731     case XFA_Element::Bookend:
1732     case XFA_Element::Break:
1733     case XFA_Element::BreakAfter:
1734     case XFA_Element::BreakBefore:
1735     case XFA_Element::Overflow:
1736       bNeedFindContainer = true;
1737       break;
1738     case XFA_Element::Area:
1739     case XFA_Element::Draw:
1740     case XFA_Element::ExclGroup:
1741     case XFA_Element::Field:
1742     case XFA_Element::Subform:
1743     case XFA_Element::SubformSet:
1744       pLayoutPro->AddChangedContainer(this);
1745       pNotify->OnValueChanged(this, eAttribute, this, this);
1746       break;
1747     case XFA_Element::Sharptext:
1748     case XFA_Element::Sharpxml:
1749     case XFA_Element::SharpxHTML: {
1750       CXFA_Node* pTextNode = GetNodeItem(XFA_NODEITEM_Parent);
1751       if (!pTextNode) {
1752         return;
1753       }
1754       CXFA_Node* pValueNode = pTextNode->GetNodeItem(XFA_NODEITEM_Parent);
1755       if (!pValueNode) {
1756         return;
1757       }
1758       XFA_Element eType = pValueNode->GetElementType();
1759       if (eType == XFA_Element::Value) {
1760         bNeedFindContainer = true;
1761         CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
1762         if (pNode && pNode->IsContainerNode()) {
1763           if (bScriptModify) {
1764             pValueNode = pNode;
1765           }
1766           pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
1767         } else {
1768           pNotify->OnValueChanged(this, eAttribute, pNode,
1769                                   pNode->GetNodeItem(XFA_NODEITEM_Parent));
1770         }
1771       } else {
1772         if (eType == XFA_Element::Items) {
1773           CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
1774           if (pNode && pNode->IsContainerNode()) {
1775             pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
1776           }
1777         }
1778       }
1779     } break;
1780     default:
1781       break;
1782   }
1783   if (bNeedFindContainer) {
1784     CXFA_Node* pParent = this;
1785     while (pParent) {
1786       if (pParent->IsContainerNode())
1787         break;
1788 
1789       pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
1790     }
1791     if (pParent) {
1792       pLayoutPro->AddChangedContainer(pParent);
1793     }
1794   }
1795 }
1796 
Script_Attribute_String(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1797 void CXFA_Node::Script_Attribute_String(CFXJSE_Value* pValue,
1798                                         bool bSetting,
1799                                         XFA_ATTRIBUTE eAttribute) {
1800   if (bSetting) {
1801     CFX_WideString wsValue = pValue->ToWideString();
1802     SetAttribute(eAttribute, wsValue.AsStringC(), true);
1803     if (eAttribute == XFA_ATTRIBUTE_Use &&
1804         GetElementType() == XFA_Element::Desc) {
1805       CXFA_Node* pTemplateNode =
1806           ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
1807       CXFA_Node* pProtoRoot =
1808           pTemplateNode->GetFirstChildByClass(XFA_Element::Subform)
1809               ->GetFirstChildByClass(XFA_Element::Proto);
1810 
1811       CFX_WideString wsID;
1812       CFX_WideString wsSOM;
1813       if (!wsValue.IsEmpty()) {
1814         if (wsValue[0] == '#') {
1815           wsID = CFX_WideString(wsValue.c_str() + 1, wsValue.GetLength() - 1);
1816         } else {
1817           wsSOM = wsValue;
1818         }
1819       }
1820       CXFA_Node* pProtoNode = nullptr;
1821       if (!wsSOM.IsEmpty()) {
1822         uint32_t dwFlag = XFA_RESOLVENODE_Children |
1823                           XFA_RESOLVENODE_Attributes |
1824                           XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1825                           XFA_RESOLVENODE_Siblings;
1826         XFA_RESOLVENODE_RS resoveNodeRS;
1827         int32_t iRet = m_pDocument->GetScriptContext()->ResolveObjects(
1828             pProtoRoot, wsSOM.AsStringC(), resoveNodeRS, dwFlag);
1829         if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
1830           pProtoNode = resoveNodeRS.nodes[0]->AsNode();
1831         }
1832       } else if (!wsID.IsEmpty()) {
1833         pProtoNode = m_pDocument->GetNodeByID(pProtoRoot, wsID.AsStringC());
1834       }
1835       if (pProtoNode) {
1836         CXFA_Node* pHeadChild = GetNodeItem(XFA_NODEITEM_FirstChild);
1837         while (pHeadChild) {
1838           CXFA_Node* pSibling =
1839               pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1840           RemoveChild(pHeadChild);
1841           pHeadChild = pSibling;
1842         }
1843         CXFA_Node* pProtoForm = pProtoNode->CloneTemplateToForm(true);
1844         pHeadChild = pProtoForm->GetNodeItem(XFA_NODEITEM_FirstChild);
1845         while (pHeadChild) {
1846           CXFA_Node* pSibling =
1847               pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1848           pProtoForm->RemoveChild(pHeadChild);
1849           InsertChild(pHeadChild);
1850           pHeadChild = pSibling;
1851         }
1852         m_pDocument->RemovePurgeNode(pProtoForm);
1853         delete pProtoForm;
1854       }
1855     }
1856   } else {
1857     CFX_WideString wsValue;
1858     GetAttribute(eAttribute, wsValue);
1859     pValue->SetString(wsValue.UTF8Encode().AsStringC());
1860   }
1861 }
1862 
Script_Attribute_StringRead(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1863 void CXFA_Node::Script_Attribute_StringRead(CFXJSE_Value* pValue,
1864                                             bool bSetting,
1865                                             XFA_ATTRIBUTE eAttribute) {
1866   if (bSetting) {
1867     ThrowInvalidPropertyException();
1868     return;
1869   }
1870 
1871   CFX_WideString wsValue;
1872   GetAttribute(eAttribute, wsValue);
1873   pValue->SetString(wsValue.UTF8Encode().AsStringC());
1874 }
1875 
Script_WsdlConnection_Execute(CFXJSE_Arguments * pArguments)1876 void CXFA_Node::Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments) {
1877   int32_t argc = pArguments->GetLength();
1878   if (argc != 0 && argc != 1) {
1879     ThrowParamCountMismatchException(L"execute");
1880     return;
1881   }
1882   pArguments->GetReturnValue()->SetBoolean(false);
1883 }
1884 
Script_Delta_Restore(CFXJSE_Arguments * pArguments)1885 void CXFA_Node::Script_Delta_Restore(CFXJSE_Arguments* pArguments) {
1886   if (pArguments->GetLength() != 0)
1887     ThrowParamCountMismatchException(L"restore");
1888 }
1889 
Script_Delta_CurrentValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1890 void CXFA_Node::Script_Delta_CurrentValue(CFXJSE_Value* pValue,
1891                                           bool bSetting,
1892                                           XFA_ATTRIBUTE eAttribute) {}
1893 
Script_Delta_SavedValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1894 void CXFA_Node::Script_Delta_SavedValue(CFXJSE_Value* pValue,
1895                                         bool bSetting,
1896                                         XFA_ATTRIBUTE eAttribute) {}
1897 
Script_Delta_Target(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1898 void CXFA_Node::Script_Delta_Target(CFXJSE_Value* pValue,
1899                                     bool bSetting,
1900                                     XFA_ATTRIBUTE eAttribute) {}
1901 
Script_Som_Message(CFXJSE_Value * pValue,bool bSetting,XFA_SOM_MESSAGETYPE iMessageType)1902 void CXFA_Node::Script_Som_Message(CFXJSE_Value* pValue,
1903                                    bool bSetting,
1904                                    XFA_SOM_MESSAGETYPE iMessageType) {
1905   CXFA_WidgetData* pWidgetData = GetWidgetData();
1906   if (!pWidgetData) {
1907     return;
1908   }
1909   bool bNew = false;
1910   CXFA_Validate validate = pWidgetData->GetValidate();
1911   if (!validate) {
1912     validate = pWidgetData->GetValidate(true);
1913     bNew = true;
1914   }
1915   if (bSetting) {
1916     switch (iMessageType) {
1917       case XFA_SOM_ValidationMessage:
1918         validate.SetScriptMessageText(pValue->ToWideString());
1919         break;
1920       case XFA_SOM_FormatMessage:
1921         validate.SetFormatMessageText(pValue->ToWideString());
1922         break;
1923       case XFA_SOM_MandatoryMessage:
1924         validate.SetNullMessageText(pValue->ToWideString());
1925         break;
1926       default:
1927         break;
1928     }
1929     if (!bNew) {
1930       CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1931       if (!pNotify) {
1932         return;
1933       }
1934       pNotify->AddCalcValidate(this);
1935     }
1936   } else {
1937     CFX_WideString wsMessage;
1938     switch (iMessageType) {
1939       case XFA_SOM_ValidationMessage:
1940         validate.GetScriptMessageText(wsMessage);
1941         break;
1942       case XFA_SOM_FormatMessage:
1943         validate.GetFormatMessageText(wsMessage);
1944         break;
1945       case XFA_SOM_MandatoryMessage:
1946         validate.GetNullMessageText(wsMessage);
1947         break;
1948       default:
1949         break;
1950     }
1951     pValue->SetString(wsMessage.UTF8Encode().AsStringC());
1952   }
1953 }
1954 
Script_Som_ValidationMessage(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1955 void CXFA_Node::Script_Som_ValidationMessage(CFXJSE_Value* pValue,
1956                                              bool bSetting,
1957                                              XFA_ATTRIBUTE eAttribute) {
1958   Script_Som_Message(pValue, bSetting, XFA_SOM_ValidationMessage);
1959 }
1960 
Script_Field_Length(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1961 void CXFA_Node::Script_Field_Length(CFXJSE_Value* pValue,
1962                                     bool bSetting,
1963                                     XFA_ATTRIBUTE eAttribute) {
1964   if (bSetting) {
1965     ThrowInvalidPropertyException();
1966     return;
1967   }
1968 
1969   CXFA_WidgetData* pWidgetData = GetWidgetData();
1970   if (!pWidgetData) {
1971     pValue->SetInteger(0);
1972     return;
1973   }
1974   pValue->SetInteger(pWidgetData->CountChoiceListItems(true));
1975 }
1976 
Script_Som_DefaultValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)1977 void CXFA_Node::Script_Som_DefaultValue(CFXJSE_Value* pValue,
1978                                         bool bSetting,
1979                                         XFA_ATTRIBUTE eAttribute) {
1980   XFA_Element eType = GetElementType();
1981   if (eType == XFA_Element::Field) {
1982     Script_Field_DefaultValue(pValue, bSetting, eAttribute);
1983     return;
1984   }
1985   if (eType == XFA_Element::Draw) {
1986     Script_Draw_DefaultValue(pValue, bSetting, eAttribute);
1987     return;
1988   }
1989   if (eType == XFA_Element::Boolean) {
1990     Script_Boolean_Value(pValue, bSetting, eAttribute);
1991     return;
1992   }
1993   if (bSetting) {
1994     CFX_WideString wsNewValue;
1995     if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
1996       wsNewValue = pValue->ToWideString();
1997 
1998     CFX_WideString wsFormatValue(wsNewValue);
1999     CXFA_WidgetData* pContainerWidgetData = nullptr;
2000     if (GetPacketID() == XFA_XDPPACKET_Datasets) {
2001       CXFA_NodeArray formNodes;
2002       GetBindItems(formNodes);
2003       CFX_WideString wsPicture;
2004       for (int32_t i = 0; i < formNodes.GetSize(); i++) {
2005         CXFA_Node* pFormNode = formNodes.GetAt(i);
2006         if (!pFormNode || pFormNode->HasRemovedChildren()) {
2007           continue;
2008         }
2009         pContainerWidgetData = pFormNode->GetContainerWidgetData();
2010         if (pContainerWidgetData) {
2011           pContainerWidgetData->GetPictureContent(wsPicture,
2012                                                   XFA_VALUEPICTURE_DataBind);
2013         }
2014         if (!wsPicture.IsEmpty()) {
2015           break;
2016         }
2017         pContainerWidgetData = nullptr;
2018       }
2019     } else if (GetPacketID() == XFA_XDPPACKET_Form) {
2020       pContainerWidgetData = GetContainerWidgetData();
2021     }
2022     if (pContainerWidgetData) {
2023       pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
2024     }
2025     SetScriptContent(wsNewValue, wsFormatValue, true, true);
2026   } else {
2027     CFX_WideString content = GetScriptContent(true);
2028     if (content.IsEmpty() && eType != XFA_Element::Text &&
2029         eType != XFA_Element::SubmitUrl) {
2030       pValue->SetNull();
2031     } else if (eType == XFA_Element::Integer) {
2032       pValue->SetInteger(FXSYS_wtoi(content.c_str()));
2033     } else if (eType == XFA_Element::Float || eType == XFA_Element::Decimal) {
2034       CFX_Decimal decimal(content.AsStringC());
2035       pValue->SetFloat((FX_FLOAT)(double)decimal);
2036     } else {
2037       pValue->SetString(content.UTF8Encode().AsStringC());
2038     }
2039   }
2040 }
2041 
Script_Som_DefaultValue_Read(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2042 void CXFA_Node::Script_Som_DefaultValue_Read(CFXJSE_Value* pValue,
2043                                              bool bSetting,
2044                                              XFA_ATTRIBUTE eAttribute) {
2045   if (bSetting) {
2046     ThrowInvalidPropertyException();
2047     return;
2048   }
2049 
2050   CFX_WideString content = GetScriptContent(true);
2051   if (content.IsEmpty()) {
2052     pValue->SetNull();
2053     return;
2054   }
2055   pValue->SetString(content.UTF8Encode().AsStringC());
2056 }
2057 
Script_Boolean_Value(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2058 void CXFA_Node::Script_Boolean_Value(CFXJSE_Value* pValue,
2059                                      bool bSetting,
2060                                      XFA_ATTRIBUTE eAttribute) {
2061   if (bSetting) {
2062     CFX_ByteString newValue;
2063     if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
2064       newValue = pValue->ToString();
2065 
2066     int32_t iValue = FXSYS_atoi(newValue.c_str());
2067     CFX_WideString wsNewValue(iValue == 0 ? L"0" : L"1");
2068     CFX_WideString wsFormatValue(wsNewValue);
2069     CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
2070     if (pContainerWidgetData) {
2071       pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
2072     }
2073     SetScriptContent(wsNewValue, wsFormatValue, true, true);
2074   } else {
2075     CFX_WideString wsValue = GetScriptContent(true);
2076     pValue->SetBoolean(wsValue == L"1");
2077   }
2078 }
2079 
Script_Som_BorderColor(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2080 void CXFA_Node::Script_Som_BorderColor(CFXJSE_Value* pValue,
2081                                        bool bSetting,
2082                                        XFA_ATTRIBUTE eAttribute) {
2083   CXFA_WidgetData* pWidgetData = GetWidgetData();
2084   if (!pWidgetData) {
2085     return;
2086   }
2087   CXFA_Border border = pWidgetData->GetBorder(true);
2088   int32_t iSize = border.CountEdges();
2089   if (bSetting) {
2090     int32_t r = 0;
2091     int32_t g = 0;
2092     int32_t b = 0;
2093     StrToRGB(pValue->ToWideString(), r, g, b);
2094     FX_ARGB rgb = ArgbEncode(100, r, g, b);
2095     for (int32_t i = 0; i < iSize; ++i) {
2096       CXFA_Edge edge = border.GetEdge(i);
2097       edge.SetColor(rgb);
2098     }
2099   } else {
2100     CXFA_Edge edge = border.GetEdge(0);
2101     FX_ARGB color = edge.GetColor();
2102     int32_t a, r, g, b;
2103     ArgbDecode(color, a, r, g, b);
2104     CFX_WideString strColor;
2105     strColor.Format(L"%d,%d,%d", r, g, b);
2106     pValue->SetString(strColor.UTF8Encode().AsStringC());
2107   }
2108 }
2109 
Script_Som_BorderWidth(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2110 void CXFA_Node::Script_Som_BorderWidth(CFXJSE_Value* pValue,
2111                                        bool bSetting,
2112                                        XFA_ATTRIBUTE eAttribute) {
2113   CXFA_WidgetData* pWidgetData = GetWidgetData();
2114   if (!pWidgetData) {
2115     return;
2116   }
2117   CXFA_Border border = pWidgetData->GetBorder(true);
2118   int32_t iSize = border.CountEdges();
2119   CFX_WideString wsThickness;
2120   if (bSetting) {
2121     wsThickness = pValue->ToWideString();
2122     for (int32_t i = 0; i < iSize; ++i) {
2123       CXFA_Edge edge = border.GetEdge(i);
2124       CXFA_Measurement thickness(wsThickness.AsStringC());
2125       edge.SetMSThickness(thickness);
2126     }
2127   } else {
2128     CXFA_Edge edge = border.GetEdge(0);
2129     CXFA_Measurement thickness = edge.GetMSThickness();
2130     thickness.ToString(wsThickness);
2131     pValue->SetString(wsThickness.UTF8Encode().AsStringC());
2132   }
2133 }
2134 
Script_Som_FillColor(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2135 void CXFA_Node::Script_Som_FillColor(CFXJSE_Value* pValue,
2136                                      bool bSetting,
2137                                      XFA_ATTRIBUTE eAttribute) {
2138   CXFA_WidgetData* pWidgetData = GetWidgetData();
2139   if (!pWidgetData) {
2140     return;
2141   }
2142   CXFA_Border border = pWidgetData->GetBorder(true);
2143   CXFA_Fill borderfill = border.GetFill(true);
2144   CXFA_Node* pNode = borderfill.GetNode();
2145   if (!pNode) {
2146     return;
2147   }
2148   if (bSetting) {
2149     int32_t r;
2150     int32_t g;
2151     int32_t b;
2152     StrToRGB(pValue->ToWideString(), r, g, b);
2153     FX_ARGB color = ArgbEncode(0xff, r, g, b);
2154     borderfill.SetColor(color);
2155   } else {
2156     FX_ARGB color = borderfill.GetColor();
2157     int32_t a;
2158     int32_t r;
2159     int32_t g;
2160     int32_t b;
2161     ArgbDecode(color, a, r, g, b);
2162     CFX_WideString wsColor;
2163     wsColor.Format(L"%d,%d,%d", r, g, b);
2164     pValue->SetString(wsColor.UTF8Encode().AsStringC());
2165   }
2166 }
2167 
Script_Som_DataNode(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2168 void CXFA_Node::Script_Som_DataNode(CFXJSE_Value* pValue,
2169                                     bool bSetting,
2170                                     XFA_ATTRIBUTE eAttribute) {
2171   if (bSetting) {
2172     ThrowInvalidPropertyException();
2173     return;
2174   }
2175 
2176   CXFA_Node* pDataNode = GetBindData();
2177   if (!pDataNode) {
2178     pValue->SetNull();
2179     return;
2180   }
2181 
2182   pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pDataNode));
2183 }
2184 
Script_Draw_DefaultValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2185 void CXFA_Node::Script_Draw_DefaultValue(CFXJSE_Value* pValue,
2186                                          bool bSetting,
2187                                          XFA_ATTRIBUTE eAttribute) {
2188   if (bSetting) {
2189     if (pValue && pValue->IsString()) {
2190       CXFA_WidgetData* pWidgetData = GetWidgetData();
2191       ASSERT(pWidgetData);
2192       XFA_Element uiType = pWidgetData->GetUIType();
2193       if (uiType == XFA_Element::Text) {
2194         CFX_WideString wsNewValue = pValue->ToWideString();
2195         CFX_WideString wsFormatValue(wsNewValue);
2196         SetScriptContent(wsNewValue, wsFormatValue, true, true);
2197       }
2198     }
2199   } else {
2200     CFX_WideString content = GetScriptContent(true);
2201     if (content.IsEmpty())
2202       pValue->SetNull();
2203     else
2204       pValue->SetString(content.UTF8Encode().AsStringC());
2205   }
2206 }
2207 
Script_Field_DefaultValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2208 void CXFA_Node::Script_Field_DefaultValue(CFXJSE_Value* pValue,
2209                                           bool bSetting,
2210                                           XFA_ATTRIBUTE eAttribute) {
2211   CXFA_WidgetData* pWidgetData = GetWidgetData();
2212   if (!pWidgetData) {
2213     return;
2214   }
2215   if (bSetting) {
2216     if (pValue && pValue->IsNull()) {
2217       pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
2218       pWidgetData->m_bIsNull = true;
2219     } else {
2220       pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
2221       pWidgetData->m_bIsNull = false;
2222     }
2223     CFX_WideString wsNewText;
2224     if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
2225       wsNewText = pValue->ToWideString();
2226 
2227     CXFA_Node* pUIChild = pWidgetData->GetUIChild();
2228     if (pUIChild->GetElementType() == XFA_Element::NumericEdit) {
2229       int32_t iLeadDigits = 0;
2230       int32_t iFracDigits = 0;
2231       pWidgetData->GetLeadDigits(iLeadDigits);
2232       pWidgetData->GetFracDigits(iFracDigits);
2233       wsNewText =
2234           pWidgetData->NumericLimit(wsNewText, iLeadDigits, iFracDigits);
2235     }
2236     CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
2237     CFX_WideString wsFormatText(wsNewText);
2238     if (pContainerWidgetData) {
2239       pContainerWidgetData->GetFormatDataValue(wsNewText, wsFormatText);
2240     }
2241     SetScriptContent(wsNewText, wsFormatText, true, true);
2242   } else {
2243     CFX_WideString content = GetScriptContent(true);
2244     if (content.IsEmpty()) {
2245       pValue->SetNull();
2246     } else {
2247       CXFA_Node* pUIChild = pWidgetData->GetUIChild();
2248       CXFA_Value defVal = pWidgetData->GetFormValue();
2249       CXFA_Node* pNode = defVal.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
2250       if (pNode && pNode->GetElementType() == XFA_Element::Decimal) {
2251         if (pUIChild->GetElementType() == XFA_Element::NumericEdit &&
2252             (pNode->GetInteger(XFA_ATTRIBUTE_FracDigits) == -1)) {
2253           pValue->SetString(content.UTF8Encode().AsStringC());
2254         } else {
2255           CFX_Decimal decimal(content.AsStringC());
2256           pValue->SetFloat((FX_FLOAT)(double)decimal);
2257         }
2258       } else if (pNode && pNode->GetElementType() == XFA_Element::Integer) {
2259         pValue->SetInteger(FXSYS_wtoi(content.c_str()));
2260       } else if (pNode && pNode->GetElementType() == XFA_Element::Boolean) {
2261         pValue->SetBoolean(FXSYS_wtoi(content.c_str()) == 0 ? false : true);
2262       } else if (pNode && pNode->GetElementType() == XFA_Element::Float) {
2263         CFX_Decimal decimal(content.AsStringC());
2264         pValue->SetFloat((FX_FLOAT)(double)decimal);
2265       } else {
2266         pValue->SetString(content.UTF8Encode().AsStringC());
2267       }
2268     }
2269   }
2270 }
2271 
Script_Field_EditValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2272 void CXFA_Node::Script_Field_EditValue(CFXJSE_Value* pValue,
2273                                        bool bSetting,
2274                                        XFA_ATTRIBUTE eAttribute) {
2275   CXFA_WidgetData* pWidgetData = GetWidgetData();
2276   if (!pWidgetData) {
2277     return;
2278   }
2279   if (bSetting) {
2280     pWidgetData->SetValue(pValue->ToWideString(), XFA_VALUEPICTURE_Edit);
2281   } else {
2282     CFX_WideString wsValue;
2283     pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Edit);
2284     pValue->SetString(wsValue.UTF8Encode().AsStringC());
2285   }
2286 }
2287 
Script_Som_FontColor(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2288 void CXFA_Node::Script_Som_FontColor(CFXJSE_Value* pValue,
2289                                      bool bSetting,
2290                                      XFA_ATTRIBUTE eAttribute) {
2291   CXFA_WidgetData* pWidgetData = GetWidgetData();
2292   if (!pWidgetData) {
2293     return;
2294   }
2295   CXFA_Font font = pWidgetData->GetFont(true);
2296   CXFA_Node* pNode = font.GetNode();
2297   if (!pNode) {
2298     return;
2299   }
2300   if (bSetting) {
2301     int32_t r;
2302     int32_t g;
2303     int32_t b;
2304     StrToRGB(pValue->ToWideString(), r, g, b);
2305     FX_ARGB color = ArgbEncode(0xff, r, g, b);
2306     font.SetColor(color);
2307   } else {
2308     FX_ARGB color = font.GetColor();
2309     int32_t a;
2310     int32_t r;
2311     int32_t g;
2312     int32_t b;
2313     ArgbDecode(color, a, r, g, b);
2314     CFX_WideString wsColor;
2315     wsColor.Format(L"%d,%d,%d", r, g, b);
2316     pValue->SetString(wsColor.UTF8Encode().AsStringC());
2317   }
2318 }
2319 
Script_Field_FormatMessage(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2320 void CXFA_Node::Script_Field_FormatMessage(CFXJSE_Value* pValue,
2321                                            bool bSetting,
2322                                            XFA_ATTRIBUTE eAttribute) {
2323   Script_Som_Message(pValue, bSetting, XFA_SOM_FormatMessage);
2324 }
2325 
Script_Field_FormattedValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2326 void CXFA_Node::Script_Field_FormattedValue(CFXJSE_Value* pValue,
2327                                             bool bSetting,
2328                                             XFA_ATTRIBUTE eAttribute) {
2329   CXFA_WidgetData* pWidgetData = GetWidgetData();
2330   if (!pWidgetData) {
2331     return;
2332   }
2333   if (bSetting) {
2334     pWidgetData->SetValue(pValue->ToWideString(), XFA_VALUEPICTURE_Display);
2335   } else {
2336     CFX_WideString wsValue;
2337     pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Display);
2338     pValue->SetString(wsValue.UTF8Encode().AsStringC());
2339   }
2340 }
2341 
Script_Som_Mandatory(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2342 void CXFA_Node::Script_Som_Mandatory(CFXJSE_Value* pValue,
2343                                      bool bSetting,
2344                                      XFA_ATTRIBUTE eAttribute) {
2345   CXFA_WidgetData* pWidgetData = GetWidgetData();
2346   if (!pWidgetData) {
2347     return;
2348   }
2349   CXFA_Validate validate = pWidgetData->GetValidate(true);
2350   if (bSetting) {
2351     validate.SetNullTest(pValue->ToWideString());
2352   } else {
2353     int32_t iValue = validate.GetNullTest();
2354     const XFA_ATTRIBUTEENUMINFO* pInfo =
2355         GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
2356     CFX_WideString wsValue;
2357     if (pInfo)
2358       wsValue = pInfo->pName;
2359     pValue->SetString(wsValue.UTF8Encode().AsStringC());
2360   }
2361 }
2362 
Script_Som_MandatoryMessage(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2363 void CXFA_Node::Script_Som_MandatoryMessage(CFXJSE_Value* pValue,
2364                                             bool bSetting,
2365                                             XFA_ATTRIBUTE eAttribute) {
2366   Script_Som_Message(pValue, bSetting, XFA_SOM_MandatoryMessage);
2367 }
2368 
Script_Field_ParentSubform(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2369 void CXFA_Node::Script_Field_ParentSubform(CFXJSE_Value* pValue,
2370                                            bool bSetting,
2371                                            XFA_ATTRIBUTE eAttribute) {
2372   if (bSetting) {
2373     ThrowInvalidPropertyException();
2374     return;
2375   }
2376   pValue->SetNull();
2377 }
2378 
Script_Field_SelectedIndex(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2379 void CXFA_Node::Script_Field_SelectedIndex(CFXJSE_Value* pValue,
2380                                            bool bSetting,
2381                                            XFA_ATTRIBUTE eAttribute) {
2382   CXFA_WidgetData* pWidgetData = GetWidgetData();
2383   if (!pWidgetData) {
2384     return;
2385   }
2386   if (bSetting) {
2387     int32_t iIndex = pValue->ToInteger();
2388     if (iIndex == -1) {
2389       pWidgetData->ClearAllSelections();
2390       return;
2391     }
2392     pWidgetData->SetItemState(iIndex, true, true, true, true);
2393   } else {
2394     pValue->SetInteger(pWidgetData->GetSelectedItem());
2395   }
2396 }
2397 
Script_Field_ClearItems(CFXJSE_Arguments * pArguments)2398 void CXFA_Node::Script_Field_ClearItems(CFXJSE_Arguments* pArguments) {
2399   CXFA_WidgetData* pWidgetData = GetWidgetData();
2400   if (!pWidgetData) {
2401     return;
2402   }
2403   pWidgetData->DeleteItem(-1, true);
2404 }
2405 
Script_Field_ExecEvent(CFXJSE_Arguments * pArguments)2406 void CXFA_Node::Script_Field_ExecEvent(CFXJSE_Arguments* pArguments) {
2407   if (pArguments->GetLength() != 1) {
2408     ThrowParamCountMismatchException(L"execEvent");
2409     return;
2410   }
2411 
2412   CFX_ByteString eventString = pArguments->GetUTF8String(0);
2413   int32_t iRet = execSingleEventByName(
2414       CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2415       XFA_Element::Field);
2416   if (eventString != "validate")
2417     return;
2418 
2419   pArguments->GetReturnValue()->SetBoolean(
2420       (iRet == XFA_EVENTERROR_Error) ? false : true);
2421 }
2422 
Script_Field_ExecInitialize(CFXJSE_Arguments * pArguments)2423 void CXFA_Node::Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments) {
2424   if (pArguments->GetLength() != 0) {
2425     ThrowParamCountMismatchException(L"execInitialize");
2426     return;
2427   }
2428 
2429   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2430   if (!pNotify)
2431     return;
2432 
2433   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize, false, false);
2434 }
2435 
Script_Field_DeleteItem(CFXJSE_Arguments * pArguments)2436 void CXFA_Node::Script_Field_DeleteItem(CFXJSE_Arguments* pArguments) {
2437   int32_t iLength = pArguments->GetLength();
2438   if (iLength != 1) {
2439     ThrowParamCountMismatchException(L"deleteItem");
2440     return;
2441   }
2442   CXFA_WidgetData* pWidgetData = GetWidgetData();
2443   if (!pWidgetData) {
2444     return;
2445   }
2446   int32_t iIndex = pArguments->GetInt32(0);
2447   bool bValue = pWidgetData->DeleteItem(iIndex, true, true);
2448   CFXJSE_Value* pValue = pArguments->GetReturnValue();
2449   if (pValue)
2450     pValue->SetBoolean(bValue);
2451 }
2452 
Script_Field_GetSaveItem(CFXJSE_Arguments * pArguments)2453 void CXFA_Node::Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments) {
2454   int32_t iLength = pArguments->GetLength();
2455   if (iLength != 1) {
2456     ThrowParamCountMismatchException(L"getSaveItem");
2457     return;
2458   }
2459   int32_t iIndex = pArguments->GetInt32(0);
2460   if (iIndex < 0) {
2461     pArguments->GetReturnValue()->SetNull();
2462     return;
2463   }
2464   CXFA_WidgetData* pWidgetData = GetWidgetData();
2465   if (!pWidgetData) {
2466     pArguments->GetReturnValue()->SetNull();
2467     return;
2468   }
2469   CFX_WideString wsValue;
2470   if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, true)) {
2471     pArguments->GetReturnValue()->SetNull();
2472     return;
2473   }
2474   pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC());
2475 }
2476 
Script_Field_BoundItem(CFXJSE_Arguments * pArguments)2477 void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments) {
2478   int32_t iLength = pArguments->GetLength();
2479   if (iLength != 1) {
2480     ThrowParamCountMismatchException(L"boundItem");
2481     return;
2482   }
2483   CXFA_WidgetData* pWidgetData = GetWidgetData();
2484   if (!pWidgetData) {
2485     return;
2486   }
2487   CFX_ByteString bsValue = pArguments->GetUTF8String(0);
2488   CFX_WideString wsValue = CFX_WideString::FromUTF8(bsValue.AsStringC());
2489   CFX_WideString wsBoundValue;
2490   pWidgetData->GetItemValue(wsValue.AsStringC(), wsBoundValue);
2491   CFXJSE_Value* pValue = pArguments->GetReturnValue();
2492   if (pValue)
2493     pValue->SetString(wsBoundValue.UTF8Encode().AsStringC());
2494 }
2495 
Script_Field_GetItemState(CFXJSE_Arguments * pArguments)2496 void CXFA_Node::Script_Field_GetItemState(CFXJSE_Arguments* pArguments) {
2497   int32_t iLength = pArguments->GetLength();
2498   if (iLength != 1) {
2499     ThrowParamCountMismatchException(L"getItemState");
2500     return;
2501   }
2502   CXFA_WidgetData* pWidgetData = GetWidgetData();
2503   if (!pWidgetData) {
2504     return;
2505   }
2506   int32_t iIndex = pArguments->GetInt32(0);
2507   bool bValue = pWidgetData->GetItemState(iIndex);
2508   CFXJSE_Value* pValue = pArguments->GetReturnValue();
2509   if (pValue)
2510     pValue->SetBoolean(bValue);
2511 }
2512 
Script_Field_ExecCalculate(CFXJSE_Arguments * pArguments)2513 void CXFA_Node::Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments) {
2514   if (pArguments->GetLength() != 0) {
2515     ThrowParamCountMismatchException(L"execCalculate");
2516     return;
2517   }
2518 
2519   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2520   if (!pNotify)
2521     return;
2522 
2523   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate, false, false);
2524 }
2525 
Script_Field_SetItems(CFXJSE_Arguments * pArguments)2526 void CXFA_Node::Script_Field_SetItems(CFXJSE_Arguments* pArguments) {}
2527 
Script_Field_GetDisplayItem(CFXJSE_Arguments * pArguments)2528 void CXFA_Node::Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments) {
2529   int32_t iLength = pArguments->GetLength();
2530   if (iLength != 1) {
2531     ThrowParamCountMismatchException(L"getDisplayItem");
2532     return;
2533   }
2534   int32_t iIndex = pArguments->GetInt32(0);
2535   if (iIndex < 0) {
2536     pArguments->GetReturnValue()->SetNull();
2537     return;
2538   }
2539   CXFA_WidgetData* pWidgetData = GetWidgetData();
2540   if (!pWidgetData) {
2541     pArguments->GetReturnValue()->SetNull();
2542     return;
2543   }
2544   CFX_WideString wsValue;
2545   if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, false)) {
2546     pArguments->GetReturnValue()->SetNull();
2547     return;
2548   }
2549   pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC());
2550 }
2551 
Script_Field_SetItemState(CFXJSE_Arguments * pArguments)2552 void CXFA_Node::Script_Field_SetItemState(CFXJSE_Arguments* pArguments) {
2553   int32_t iLength = pArguments->GetLength();
2554   if (iLength != 2) {
2555     ThrowParamCountMismatchException(L"setItemState");
2556     return;
2557   }
2558   CXFA_WidgetData* pWidgetData = GetWidgetData();
2559   if (!pWidgetData)
2560     return;
2561 
2562   int32_t iIndex = pArguments->GetInt32(0);
2563   if (pArguments->GetInt32(1) != 0) {
2564     pWidgetData->SetItemState(iIndex, true, true, true, true);
2565   } else {
2566     if (pWidgetData->GetItemState(iIndex))
2567       pWidgetData->SetItemState(iIndex, false, true, true, true);
2568   }
2569 }
2570 
Script_Field_AddItem(CFXJSE_Arguments * pArguments)2571 void CXFA_Node::Script_Field_AddItem(CFXJSE_Arguments* pArguments) {
2572   int32_t iLength = pArguments->GetLength();
2573   if (iLength < 1 || iLength > 2) {
2574     ThrowParamCountMismatchException(L"addItem");
2575     return;
2576   }
2577   CXFA_WidgetData* pWidgetData = GetWidgetData();
2578   if (!pWidgetData) {
2579     return;
2580   }
2581   CFX_WideString wsLabel;
2582   CFX_WideString wsValue;
2583   if (iLength >= 1) {
2584     CFX_ByteString bsLabel = pArguments->GetUTF8String(0);
2585     wsLabel = CFX_WideString::FromUTF8(bsLabel.AsStringC());
2586   }
2587   if (iLength >= 2) {
2588     CFX_ByteString bsValue = pArguments->GetUTF8String(1);
2589     wsValue = CFX_WideString::FromUTF8(bsValue.AsStringC());
2590   }
2591   pWidgetData->InsertItem(wsLabel, wsValue, -1, true);
2592 }
2593 
Script_Field_ExecValidate(CFXJSE_Arguments * pArguments)2594 void CXFA_Node::Script_Field_ExecValidate(CFXJSE_Arguments* pArguments) {
2595   if (pArguments->GetLength() != 0) {
2596     ThrowParamCountMismatchException(L"execValidate");
2597     return;
2598   }
2599 
2600   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2601   if (!pNotify) {
2602     pArguments->GetReturnValue()->SetBoolean(false);
2603     return;
2604   }
2605 
2606   int32_t iRet =
2607       pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate, false, false);
2608   pArguments->GetReturnValue()->SetBoolean(
2609       (iRet == XFA_EVENTERROR_Error) ? false : true);
2610 }
2611 
Script_ExclGroup_ErrorText(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2612 void CXFA_Node::Script_ExclGroup_ErrorText(CFXJSE_Value* pValue,
2613                                            bool bSetting,
2614                                            XFA_ATTRIBUTE eAttribute) {
2615   if (bSetting)
2616     ThrowInvalidPropertyException();
2617 }
2618 
Script_ExclGroup_DefaultAndRawValue(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2619 void CXFA_Node::Script_ExclGroup_DefaultAndRawValue(CFXJSE_Value* pValue,
2620                                                     bool bSetting,
2621                                                     XFA_ATTRIBUTE eAttribute) {
2622   CXFA_WidgetData* pWidgetData = GetWidgetData();
2623   if (!pWidgetData) {
2624     return;
2625   }
2626   if (bSetting) {
2627     pWidgetData->SetSelectedMemberByValue(pValue->ToWideString().AsStringC(),
2628                                           true, true, true);
2629   } else {
2630     CFX_WideString wsValue = GetScriptContent(true);
2631     XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
2632     if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
2633       pValue->SetNull();
2634     } else {
2635       pValue->SetString(wsValue.UTF8Encode().AsStringC());
2636     }
2637   }
2638 }
2639 
Script_ExclGroup_Transient(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2640 void CXFA_Node::Script_ExclGroup_Transient(CFXJSE_Value* pValue,
2641                                            bool bSetting,
2642                                            XFA_ATTRIBUTE eAttribute) {}
2643 
Script_ExclGroup_ExecEvent(CFXJSE_Arguments * pArguments)2644 void CXFA_Node::Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments) {
2645   if (pArguments->GetLength() != 1) {
2646     ThrowParamCountMismatchException(L"execEvent");
2647     return;
2648   }
2649 
2650   CFX_ByteString eventString = pArguments->GetUTF8String(0);
2651   execSingleEventByName(
2652       CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2653       XFA_Element::ExclGroup);
2654 }
2655 
Script_ExclGroup_SelectedMember(CFXJSE_Arguments * pArguments)2656 void CXFA_Node::Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments) {
2657   int32_t argc = pArguments->GetLength();
2658   if (argc < 0 || argc > 1) {
2659     ThrowParamCountMismatchException(L"selectedMember");
2660     return;
2661   }
2662 
2663   CXFA_WidgetData* pWidgetData = GetWidgetData();
2664   if (!pWidgetData) {
2665     pArguments->GetReturnValue()->SetNull();
2666     return;
2667   }
2668 
2669   CXFA_Node* pReturnNode = nullptr;
2670   if (argc == 0) {
2671     pReturnNode = pWidgetData->GetSelectedMember();
2672   } else {
2673     CFX_ByteString szName;
2674     szName = pArguments->GetUTF8String(0);
2675     pReturnNode = pWidgetData->SetSelectedMember(
2676         CFX_WideString::FromUTF8(szName.AsStringC()).AsStringC(), true);
2677   }
2678   if (!pReturnNode) {
2679     pArguments->GetReturnValue()->SetNull();
2680     return;
2681   }
2682   pArguments->GetReturnValue()->Assign(
2683       m_pDocument->GetScriptContext()->GetJSValueFromMap(pReturnNode));
2684 }
2685 
Script_ExclGroup_ExecInitialize(CFXJSE_Arguments * pArguments)2686 void CXFA_Node::Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments) {
2687   if (pArguments->GetLength() != 0) {
2688     ThrowParamCountMismatchException(L"execInitialize");
2689     return;
2690   }
2691 
2692   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2693   if (!pNotify)
2694     return;
2695 
2696   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
2697 }
2698 
Script_ExclGroup_ExecCalculate(CFXJSE_Arguments * pArguments)2699 void CXFA_Node::Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments) {
2700   if (pArguments->GetLength() != 0) {
2701     ThrowParamCountMismatchException(L"execCalculate");
2702     return;
2703   }
2704 
2705   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2706   if (!pNotify)
2707     return;
2708 
2709   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
2710 }
2711 
Script_ExclGroup_ExecValidate(CFXJSE_Arguments * pArguments)2712 void CXFA_Node::Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments) {
2713   if (pArguments->GetLength() != 0) {
2714     ThrowParamCountMismatchException(L"execValidate");
2715     return;
2716   }
2717 
2718   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2719   if (!pNotify) {
2720     pArguments->GetReturnValue()->SetBoolean(false);
2721     return;
2722   }
2723 
2724   int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
2725   pArguments->GetReturnValue()->SetBoolean(
2726       (iRet == XFA_EVENTERROR_Error) ? false : true);
2727 }
2728 
Script_Som_InstanceIndex(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2729 void CXFA_Node::Script_Som_InstanceIndex(CFXJSE_Value* pValue,
2730                                          bool bSetting,
2731                                          XFA_ATTRIBUTE eAttribute) {
2732   if (bSetting) {
2733     int32_t iTo = pValue->ToInteger();
2734     int32_t iFrom = Subform_and_SubformSet_InstanceIndex();
2735     CXFA_Node* pManagerNode = nullptr;
2736     for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2737          pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2738       if (pNode->GetElementType() == XFA_Element::InstanceManager) {
2739         pManagerNode = pNode;
2740         break;
2741       }
2742     }
2743     if (pManagerNode) {
2744       pManagerNode->InstanceManager_MoveInstance(iTo, iFrom);
2745       CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2746       if (!pNotify) {
2747         return;
2748       }
2749       CXFA_Node* pToInstance = GetItem(pManagerNode, iTo);
2750       if (pToInstance &&
2751           pToInstance->GetElementType() == XFA_Element::Subform) {
2752         pNotify->RunSubformIndexChange(pToInstance);
2753       }
2754       CXFA_Node* pFromInstance = GetItem(pManagerNode, iFrom);
2755       if (pFromInstance &&
2756           pFromInstance->GetElementType() == XFA_Element::Subform) {
2757         pNotify->RunSubformIndexChange(pFromInstance);
2758       }
2759     }
2760   } else {
2761     pValue->SetInteger(Subform_and_SubformSet_InstanceIndex());
2762   }
2763 }
2764 
Script_Subform_InstanceManager(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2765 void CXFA_Node::Script_Subform_InstanceManager(CFXJSE_Value* pValue,
2766                                                bool bSetting,
2767                                                XFA_ATTRIBUTE eAttribute) {
2768   if (bSetting) {
2769     ThrowInvalidPropertyException();
2770     return;
2771   }
2772 
2773   CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
2774   CXFA_Node* pInstanceMgr = nullptr;
2775   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2776        pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2777     if (pNode->GetElementType() == XFA_Element::InstanceManager) {
2778       CFX_WideStringC wsInstMgrName = pNode->GetCData(XFA_ATTRIBUTE_Name);
2779       if (wsInstMgrName.GetLength() >= 1 && wsInstMgrName.GetAt(0) == '_' &&
2780           wsInstMgrName.Mid(1) == wsName) {
2781         pInstanceMgr = pNode;
2782       }
2783       break;
2784     }
2785   }
2786   if (!pInstanceMgr) {
2787     pValue->SetNull();
2788     return;
2789   }
2790 
2791   pValue->Assign(
2792       m_pDocument->GetScriptContext()->GetJSValueFromMap(pInstanceMgr));
2793 }
2794 
Script_Subform_Locale(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)2795 void CXFA_Node::Script_Subform_Locale(CFXJSE_Value* pValue,
2796                                       bool bSetting,
2797                                       XFA_ATTRIBUTE eAttribute) {
2798   if (bSetting) {
2799     SetCData(XFA_ATTRIBUTE_Locale, pValue->ToWideString(), true, true);
2800   } else {
2801     CFX_WideString wsLocaleName;
2802     GetLocaleName(wsLocaleName);
2803     pValue->SetString(wsLocaleName.UTF8Encode().AsStringC());
2804   }
2805 }
2806 
Script_Subform_ExecEvent(CFXJSE_Arguments * pArguments)2807 void CXFA_Node::Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments) {
2808   if (pArguments->GetLength() != 1) {
2809     ThrowParamCountMismatchException(L"execEvent");
2810     return;
2811   }
2812 
2813   CFX_ByteString eventString = pArguments->GetUTF8String(0);
2814   execSingleEventByName(
2815       CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2816       XFA_Element::Subform);
2817 }
2818 
Script_Subform_ExecInitialize(CFXJSE_Arguments * pArguments)2819 void CXFA_Node::Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments) {
2820   if (pArguments->GetLength() != 0) {
2821     ThrowParamCountMismatchException(L"execInitialize");
2822     return;
2823   }
2824 
2825   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2826   if (!pNotify)
2827     return;
2828 
2829   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
2830 }
2831 
Script_Subform_ExecCalculate(CFXJSE_Arguments * pArguments)2832 void CXFA_Node::Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments) {
2833   if (pArguments->GetLength() != 0) {
2834     ThrowParamCountMismatchException(L"execCalculate");
2835     return;
2836   }
2837 
2838   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2839   if (!pNotify)
2840     return;
2841 
2842   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
2843 }
2844 
Script_Subform_ExecValidate(CFXJSE_Arguments * pArguments)2845 void CXFA_Node::Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments) {
2846   if (pArguments->GetLength() != 0) {
2847     ThrowParamCountMismatchException(L"execValidate");
2848     return;
2849   }
2850 
2851   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2852   if (!pNotify) {
2853     pArguments->GetReturnValue()->SetBoolean(false);
2854     return;
2855   }
2856 
2857   int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
2858   pArguments->GetReturnValue()->SetBoolean(
2859       (iRet == XFA_EVENTERROR_Error) ? false : true);
2860 }
2861 
Script_Subform_GetInvalidObjects(CFXJSE_Arguments * pArguments)2862 void CXFA_Node::Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments) {
2863   if (pArguments->GetLength() != 0)
2864     ThrowParamCountMismatchException(L"getInvalidObjects");
2865 }
2866 
Subform_and_SubformSet_InstanceIndex()2867 int32_t CXFA_Node::Subform_and_SubformSet_InstanceIndex() {
2868   int32_t index = 0;
2869   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2870        pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2871     if ((pNode->GetElementType() == XFA_Element::Subform) ||
2872         (pNode->GetElementType() == XFA_Element::SubformSet)) {
2873       index++;
2874     } else {
2875       break;
2876     }
2877   }
2878   return index;
2879 }
2880 
Script_Template_FormNodes(CFXJSE_Arguments * pArguments)2881 void CXFA_Node::Script_Template_FormNodes(CFXJSE_Arguments* pArguments) {
2882   if (pArguments->GetLength() != 1) {
2883     ThrowParamCountMismatchException(L"formNodes");
2884     return;
2885   }
2886   pArguments->GetReturnValue()->SetBoolean(true);
2887 }
2888 
Script_Template_Remerge(CFXJSE_Arguments * pArguments)2889 void CXFA_Node::Script_Template_Remerge(CFXJSE_Arguments* pArguments) {
2890   if (pArguments->GetLength() != 0) {
2891     ThrowParamCountMismatchException(L"remerge");
2892     return;
2893   }
2894   m_pDocument->DoDataRemerge(true);
2895 }
2896 
Script_Template_ExecInitialize(CFXJSE_Arguments * pArguments)2897 void CXFA_Node::Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments) {
2898   if (pArguments->GetLength() != 0) {
2899     ThrowParamCountMismatchException(L"execInitialize");
2900     return;
2901   }
2902 
2903   CXFA_WidgetData* pWidgetData = GetWidgetData();
2904   if (!pWidgetData) {
2905     pArguments->GetReturnValue()->SetBoolean(false);
2906     return;
2907   }
2908   pArguments->GetReturnValue()->SetBoolean(true);
2909 }
2910 
Script_Template_CreateNode(CFXJSE_Arguments * pArguments)2911 void CXFA_Node::Script_Template_CreateNode(CFXJSE_Arguments* pArguments) {
2912   int32_t argc = pArguments->GetLength();
2913   if (argc <= 0 || argc >= 4) {
2914     ThrowParamCountMismatchException(L"createNode");
2915     return;
2916   }
2917 
2918   CFX_WideString strName;
2919   CFX_WideString strNameSpace;
2920   CFX_ByteString bsTagName = pArguments->GetUTF8String(0);
2921   CFX_WideString strTagName = CFX_WideString::FromUTF8(bsTagName.AsStringC());
2922   if (argc > 1) {
2923     CFX_ByteString bsName = pArguments->GetUTF8String(1);
2924     strName = CFX_WideString::FromUTF8(bsName.AsStringC());
2925     if (argc == 3) {
2926       CFX_ByteString bsNameSpace = pArguments->GetUTF8String(2);
2927       strNameSpace = CFX_WideString::FromUTF8(bsNameSpace.AsStringC());
2928     }
2929   }
2930 
2931   XFA_Element eType = XFA_GetElementTypeForName(strTagName.AsStringC());
2932   CXFA_Node* pNewNode = CreateSamePacketNode(eType);
2933   if (!pNewNode) {
2934     pArguments->GetReturnValue()->SetNull();
2935     return;
2936   }
2937 
2938   if (strName.IsEmpty()) {
2939     pArguments->GetReturnValue()->Assign(
2940         m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
2941     return;
2942   }
2943 
2944   if (!GetAttributeOfElement(eType, XFA_ATTRIBUTE_Name,
2945                              XFA_XDPPACKET_UNKNOWN)) {
2946     ThrowMissingPropertyException(strTagName, L"name");
2947     return;
2948   }
2949 
2950   pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, strName.AsStringC(), true);
2951   if (pNewNode->GetPacketID() == XFA_XDPPACKET_Datasets)
2952     pNewNode->CreateXMLMappingNode();
2953 
2954   pArguments->GetReturnValue()->Assign(
2955       m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
2956 }
2957 
Script_Template_Recalculate(CFXJSE_Arguments * pArguments)2958 void CXFA_Node::Script_Template_Recalculate(CFXJSE_Arguments* pArguments) {
2959   if (pArguments->GetLength() != 1) {
2960     ThrowParamCountMismatchException(L"recalculate");
2961     return;
2962   }
2963   pArguments->GetReturnValue()->SetBoolean(true);
2964 }
2965 
Script_Template_ExecCalculate(CFXJSE_Arguments * pArguments)2966 void CXFA_Node::Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments) {
2967   if (pArguments->GetLength() != 0) {
2968     ThrowParamCountMismatchException(L"execCalculate");
2969     return;
2970   }
2971 
2972   CXFA_WidgetData* pWidgetData = GetWidgetData();
2973   if (!pWidgetData) {
2974     pArguments->GetReturnValue()->SetBoolean(false);
2975     return;
2976   }
2977   pArguments->GetReturnValue()->SetBoolean(true);
2978 }
2979 
Script_Template_ExecValidate(CFXJSE_Arguments * pArguments)2980 void CXFA_Node::Script_Template_ExecValidate(CFXJSE_Arguments* pArguments) {
2981   if (pArguments->GetLength() != 0) {
2982     ThrowParamCountMismatchException(L"execValidate");
2983     return;
2984   }
2985   CXFA_WidgetData* pWidgetData = GetWidgetData();
2986   if (!pWidgetData) {
2987     pArguments->GetReturnValue()->SetBoolean(false);
2988     return;
2989   }
2990   pArguments->GetReturnValue()->SetBoolean(true);
2991 }
2992 
Script_Manifest_Evaluate(CFXJSE_Arguments * pArguments)2993 void CXFA_Node::Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments) {
2994   if (pArguments->GetLength() != 0) {
2995     ThrowParamCountMismatchException(L"evaluate");
2996     return;
2997   }
2998 
2999   CXFA_WidgetData* pWidgetData = GetWidgetData();
3000   if (!pWidgetData) {
3001     pArguments->GetReturnValue()->SetBoolean(false);
3002     return;
3003   }
3004   pArguments->GetReturnValue()->SetBoolean(true);
3005 }
3006 
Script_InstanceManager_Max(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3007 void CXFA_Node::Script_InstanceManager_Max(CFXJSE_Value* pValue,
3008                                            bool bSetting,
3009                                            XFA_ATTRIBUTE eAttribute) {
3010   if (bSetting) {
3011     ThrowInvalidPropertyException();
3012     return;
3013   }
3014   CXFA_Occur nodeOccur(GetOccurNode());
3015   pValue->SetInteger(nodeOccur.GetMax());
3016 }
3017 
Script_InstanceManager_Min(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3018 void CXFA_Node::Script_InstanceManager_Min(CFXJSE_Value* pValue,
3019                                            bool bSetting,
3020                                            XFA_ATTRIBUTE eAttribute) {
3021   if (bSetting) {
3022     ThrowInvalidPropertyException();
3023     return;
3024   }
3025   CXFA_Occur nodeOccur(GetOccurNode());
3026   pValue->SetInteger(nodeOccur.GetMin());
3027 }
3028 
Script_InstanceManager_Count(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3029 void CXFA_Node::Script_InstanceManager_Count(CFXJSE_Value* pValue,
3030                                              bool bSetting,
3031                                              XFA_ATTRIBUTE eAttribute) {
3032   if (bSetting) {
3033     int32_t iDesired = pValue->ToInteger();
3034     InstanceManager_SetInstances(iDesired);
3035   } else {
3036     pValue->SetInteger(GetCount(this));
3037   }
3038 }
3039 
Script_InstanceManager_MoveInstance(CFXJSE_Arguments * pArguments)3040 void CXFA_Node::Script_InstanceManager_MoveInstance(
3041     CFXJSE_Arguments* pArguments) {
3042   if (pArguments->GetLength() != 2) {
3043     pArguments->GetReturnValue()->SetUndefined();
3044     return;
3045   }
3046   int32_t iFrom = pArguments->GetInt32(0);
3047   int32_t iTo = pArguments->GetInt32(1);
3048   InstanceManager_MoveInstance(iTo, iFrom);
3049   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3050   if (!pNotify) {
3051     return;
3052   }
3053   CXFA_Node* pToInstance = GetItem(this, iTo);
3054   if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform) {
3055     pNotify->RunSubformIndexChange(pToInstance);
3056   }
3057   CXFA_Node* pFromInstance = GetItem(this, iFrom);
3058   if (pFromInstance &&
3059       pFromInstance->GetElementType() == XFA_Element::Subform) {
3060     pNotify->RunSubformIndexChange(pFromInstance);
3061   }
3062 }
3063 
Script_InstanceManager_RemoveInstance(CFXJSE_Arguments * pArguments)3064 void CXFA_Node::Script_InstanceManager_RemoveInstance(
3065     CFXJSE_Arguments* pArguments) {
3066   if (pArguments->GetLength() != 1) {
3067     pArguments->GetReturnValue()->SetUndefined();
3068     return;
3069   }
3070   int32_t iIndex = pArguments->GetInt32(0);
3071   int32_t iCount = GetCount(this);
3072   if (iIndex < 0 || iIndex >= iCount) {
3073     ThrowIndexOutOfBoundsException();
3074     return;
3075   }
3076   CXFA_Occur nodeOccur(GetOccurNode());
3077   int32_t iMin = nodeOccur.GetMin();
3078   if (iCount - 1 < iMin) {
3079     ThrowTooManyOccurancesException(L"min");
3080     return;
3081   }
3082   CXFA_Node* pRemoveInstance = GetItem(this, iIndex);
3083   RemoveItem(this, pRemoveInstance);
3084   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3085   if (pNotify) {
3086     for (int32_t i = iIndex; i < iCount - 1; i++) {
3087       CXFA_Node* pSubformInstance = GetItem(this, i);
3088       if (pSubformInstance &&
3089           pSubformInstance->GetElementType() == XFA_Element::Subform) {
3090         pNotify->RunSubformIndexChange(pSubformInstance);
3091       }
3092     }
3093   }
3094   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3095   if (!pLayoutPro) {
3096     return;
3097   }
3098   pLayoutPro->AddChangedContainer(
3099       ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3100 }
3101 
Script_InstanceManager_SetInstances(CFXJSE_Arguments * pArguments)3102 void CXFA_Node::Script_InstanceManager_SetInstances(
3103     CFXJSE_Arguments* pArguments) {
3104   if (pArguments->GetLength() != 1) {
3105     pArguments->GetReturnValue()->SetUndefined();
3106     return;
3107   }
3108   int32_t iDesired = pArguments->GetInt32(0);
3109   InstanceManager_SetInstances(iDesired);
3110 }
3111 
Script_InstanceManager_AddInstance(CFXJSE_Arguments * pArguments)3112 void CXFA_Node::Script_InstanceManager_AddInstance(
3113     CFXJSE_Arguments* pArguments) {
3114   int32_t argc = pArguments->GetLength();
3115   if (argc != 0 && argc != 1) {
3116     ThrowParamCountMismatchException(L"addInstance");
3117     return;
3118   }
3119   bool fFlags = true;
3120   if (argc == 1) {
3121     fFlags = pArguments->GetInt32(0) == 0 ? false : true;
3122   }
3123   int32_t iCount = GetCount(this);
3124   CXFA_Occur nodeOccur(GetOccurNode());
3125   int32_t iMax = nodeOccur.GetMax();
3126   if (iMax >= 0 && iCount >= iMax) {
3127     ThrowTooManyOccurancesException(L"max");
3128     return;
3129   }
3130   CXFA_Node* pNewInstance = CreateInstance(this, fFlags);
3131   InsertItem(this, pNewInstance, iCount, iCount, false);
3132   pArguments->GetReturnValue()->Assign(
3133       m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
3134   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3135   if (!pNotify) {
3136     return;
3137   }
3138   pNotify->RunNodeInitialize(pNewInstance);
3139   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3140   if (!pLayoutPro) {
3141     return;
3142   }
3143   pLayoutPro->AddChangedContainer(
3144       ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3145 }
3146 
Script_InstanceManager_InsertInstance(CFXJSE_Arguments * pArguments)3147 void CXFA_Node::Script_InstanceManager_InsertInstance(
3148     CFXJSE_Arguments* pArguments) {
3149   int32_t argc = pArguments->GetLength();
3150   if (argc != 1 && argc != 2) {
3151     ThrowParamCountMismatchException(L"insertInstance");
3152     return;
3153   }
3154   int32_t iIndex = pArguments->GetInt32(0);
3155   bool bBind = false;
3156   if (argc == 2) {
3157     bBind = pArguments->GetInt32(1) == 0 ? false : true;
3158   }
3159   CXFA_Occur nodeOccur(GetOccurNode());
3160   int32_t iCount = GetCount(this);
3161   if (iIndex < 0 || iIndex > iCount) {
3162     ThrowIndexOutOfBoundsException();
3163     return;
3164   }
3165   int32_t iMax = nodeOccur.GetMax();
3166   if (iMax >= 0 && iCount >= iMax) {
3167     ThrowTooManyOccurancesException(L"max");
3168     return;
3169   }
3170   CXFA_Node* pNewInstance = CreateInstance(this, bBind);
3171   InsertItem(this, pNewInstance, iIndex, iCount, true);
3172   pArguments->GetReturnValue()->Assign(
3173       m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
3174   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3175   if (!pNotify) {
3176     return;
3177   }
3178   pNotify->RunNodeInitialize(pNewInstance);
3179   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3180   if (!pLayoutPro) {
3181     return;
3182   }
3183   pLayoutPro->AddChangedContainer(
3184       ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3185 }
3186 
InstanceManager_SetInstances(int32_t iDesired)3187 int32_t CXFA_Node::InstanceManager_SetInstances(int32_t iDesired) {
3188   CXFA_Occur nodeOccur(GetOccurNode());
3189   int32_t iMax = nodeOccur.GetMax();
3190   int32_t iMin = nodeOccur.GetMin();
3191   if (iDesired < iMin) {
3192     ThrowTooManyOccurancesException(L"min");
3193     return 1;
3194   }
3195   if ((iMax >= 0) && (iDesired > iMax)) {
3196     ThrowTooManyOccurancesException(L"max");
3197     return 2;
3198   }
3199   int32_t iCount = GetCount(this);
3200   if (iDesired == iCount) {
3201     return 0;
3202   }
3203   if (iDesired < iCount) {
3204     CFX_WideStringC wsInstManagerName = GetCData(XFA_ATTRIBUTE_Name);
3205     CFX_WideString wsInstanceName =
3206         CFX_WideString(wsInstManagerName.IsEmpty() ? wsInstManagerName
3207                                                    : wsInstManagerName.Mid(1));
3208     uint32_t dInstanceNameHash =
3209         FX_HashCode_GetW(wsInstanceName.AsStringC(), false);
3210     CXFA_Node* pPrevSibling =
3211         (iDesired == 0) ? this : GetItem(this, iDesired - 1);
3212     while (iCount > iDesired) {
3213       CXFA_Node* pRemoveInstance =
3214           pPrevSibling->GetNodeItem(XFA_NODEITEM_NextSibling);
3215       if (pRemoveInstance->GetElementType() != XFA_Element::Subform &&
3216           pRemoveInstance->GetElementType() != XFA_Element::SubformSet) {
3217         continue;
3218       }
3219       if (pRemoveInstance->GetElementType() == XFA_Element::InstanceManager) {
3220         ASSERT(false);
3221         break;
3222       }
3223       if (pRemoveInstance->GetNameHash() == dInstanceNameHash) {
3224         RemoveItem(this, pRemoveInstance);
3225         iCount--;
3226       }
3227     }
3228   } else if (iDesired > iCount) {
3229     while (iCount < iDesired) {
3230       CXFA_Node* pNewInstance = CreateInstance(this, true);
3231       InsertItem(this, pNewInstance, iCount, iCount, false);
3232       iCount++;
3233       CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3234       if (!pNotify) {
3235         return 0;
3236       }
3237       pNotify->RunNodeInitialize(pNewInstance);
3238     }
3239   }
3240   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3241   if (pLayoutPro) {
3242     pLayoutPro->AddChangedContainer(
3243         ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3244   }
3245   return 0;
3246 }
3247 
InstanceManager_MoveInstance(int32_t iTo,int32_t iFrom)3248 int32_t CXFA_Node::InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom) {
3249   int32_t iCount = GetCount(this);
3250   if (iFrom > iCount || iTo > iCount - 1) {
3251     ThrowIndexOutOfBoundsException();
3252     return 1;
3253   }
3254   if (iFrom < 0 || iTo < 0 || iFrom == iTo) {
3255     return 0;
3256   }
3257   CXFA_Node* pMoveInstance = GetItem(this, iFrom);
3258   RemoveItem(this, pMoveInstance, false);
3259   InsertItem(this, pMoveInstance, iTo, iCount - 1, true);
3260   CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3261   if (pLayoutPro) {
3262     pLayoutPro->AddChangedContainer(
3263         ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3264   }
3265   return 0;
3266 }
3267 
Script_Occur_Max(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3268 void CXFA_Node::Script_Occur_Max(CFXJSE_Value* pValue,
3269                                  bool bSetting,
3270                                  XFA_ATTRIBUTE eAttribute) {
3271   CXFA_Occur occur(this);
3272   if (bSetting) {
3273     int32_t iMax = pValue->ToInteger();
3274     occur.SetMax(iMax);
3275   } else {
3276     pValue->SetInteger(occur.GetMax());
3277   }
3278 }
3279 
Script_Occur_Min(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3280 void CXFA_Node::Script_Occur_Min(CFXJSE_Value* pValue,
3281                                  bool bSetting,
3282                                  XFA_ATTRIBUTE eAttribute) {
3283   CXFA_Occur occur(this);
3284   if (bSetting) {
3285     int32_t iMin = pValue->ToInteger();
3286     occur.SetMin(iMin);
3287   } else {
3288     pValue->SetInteger(occur.GetMin());
3289   }
3290 }
3291 
Script_Desc_Metadata(CFXJSE_Arguments * pArguments)3292 void CXFA_Node::Script_Desc_Metadata(CFXJSE_Arguments* pArguments) {
3293   int32_t argc = pArguments->GetLength();
3294   if (argc != 0 && argc != 1) {
3295     ThrowParamCountMismatchException(L"metadata");
3296     return;
3297   }
3298   pArguments->GetReturnValue()->SetString("");
3299 }
3300 
Script_Form_FormNodes(CFXJSE_Arguments * pArguments)3301 void CXFA_Node::Script_Form_FormNodes(CFXJSE_Arguments* pArguments) {
3302   if (pArguments->GetLength() != 1) {
3303     ThrowParamCountMismatchException(L"formNodes");
3304     return;
3305   }
3306 
3307   CXFA_Node* pDataNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
3308   if (!pDataNode) {
3309     ThrowArgumentMismatchException();
3310     return;
3311   }
3312 
3313   CXFA_NodeArray formItems;
3314   CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
3315   pFormNodes->SetArrayNodeList(formItems);
3316   pArguments->GetReturnValue()->SetObject(
3317       pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
3318 }
3319 
Script_Form_Remerge(CFXJSE_Arguments * pArguments)3320 void CXFA_Node::Script_Form_Remerge(CFXJSE_Arguments* pArguments) {
3321   if (pArguments->GetLength() != 0) {
3322     ThrowParamCountMismatchException(L"remerge");
3323     return;
3324   }
3325 
3326   m_pDocument->DoDataRemerge(true);
3327 }
3328 
Script_Form_ExecInitialize(CFXJSE_Arguments * pArguments)3329 void CXFA_Node::Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments) {
3330   if (pArguments->GetLength() != 0) {
3331     ThrowParamCountMismatchException(L"execInitialize");
3332     return;
3333   }
3334 
3335   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3336   if (!pNotify)
3337     return;
3338 
3339   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
3340 }
3341 
Script_Form_Recalculate(CFXJSE_Arguments * pArguments)3342 void CXFA_Node::Script_Form_Recalculate(CFXJSE_Arguments* pArguments) {
3343   CXFA_EventParam* pEventParam =
3344       m_pDocument->GetScriptContext()->GetEventParam();
3345   if (pEventParam->m_eType == XFA_EVENT_Calculate ||
3346       pEventParam->m_eType == XFA_EVENT_InitCalculate) {
3347     return;
3348   }
3349   if (pArguments->GetLength() != 1) {
3350     ThrowParamCountMismatchException(L"recalculate");
3351     return;
3352   }
3353 
3354   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3355   if (!pNotify)
3356     return;
3357   if (pArguments->GetInt32(0) != 0)
3358     return;
3359 
3360   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
3361   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
3362   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Ready, true);
3363 }
3364 
Script_Form_ExecCalculate(CFXJSE_Arguments * pArguments)3365 void CXFA_Node::Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments) {
3366   if (pArguments->GetLength() != 0) {
3367     ThrowParamCountMismatchException(L"execCalculate");
3368     return;
3369   }
3370 
3371   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3372   if (!pNotify)
3373     return;
3374 
3375   pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
3376 }
3377 
Script_Form_ExecValidate(CFXJSE_Arguments * pArguments)3378 void CXFA_Node::Script_Form_ExecValidate(CFXJSE_Arguments* pArguments) {
3379   if (pArguments->GetLength() != 0) {
3380     ThrowParamCountMismatchException(L"execValidate");
3381     return;
3382   }
3383 
3384   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3385   if (!pNotify) {
3386     pArguments->GetReturnValue()->SetBoolean(false);
3387     return;
3388   }
3389 
3390   int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
3391   pArguments->GetReturnValue()->SetBoolean(
3392       (iRet == XFA_EVENTERROR_Error) ? false : true);
3393 }
3394 
Script_Form_Checksum(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3395 void CXFA_Node::Script_Form_Checksum(CFXJSE_Value* pValue,
3396                                      bool bSetting,
3397                                      XFA_ATTRIBUTE eAttribute) {
3398   if (bSetting) {
3399     SetAttribute(XFA_ATTRIBUTE_Checksum, pValue->ToWideString().AsStringC());
3400     return;
3401   }
3402   CFX_WideString wsChecksum;
3403   GetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum, false);
3404   pValue->SetString(wsChecksum.UTF8Encode().AsStringC());
3405 }
3406 
Script_Packet_GetAttribute(CFXJSE_Arguments * pArguments)3407 void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) {
3408   if (pArguments->GetLength() != 1) {
3409     ThrowParamCountMismatchException(L"getAttribute");
3410     return;
3411   }
3412   CFX_ByteString bsAttributeName = pArguments->GetUTF8String(0);
3413   CFX_WideString wsAttributeValue;
3414   CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3415   if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3416     static_cast<CFDE_XMLElement*>(pXMLNode)->GetString(
3417         CFX_WideString::FromUTF8(bsAttributeName.AsStringC()).c_str(),
3418         wsAttributeValue);
3419   }
3420   pArguments->GetReturnValue()->SetString(
3421       wsAttributeValue.UTF8Encode().AsStringC());
3422 }
3423 
Script_Packet_SetAttribute(CFXJSE_Arguments * pArguments)3424 void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments) {
3425   if (pArguments->GetLength() != 2) {
3426     ThrowParamCountMismatchException(L"setAttribute");
3427     return;
3428   }
3429   CFX_ByteString bsValue = pArguments->GetUTF8String(0);
3430   CFX_ByteString bsName = pArguments->GetUTF8String(1);
3431   CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3432   if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3433     static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(
3434         CFX_WideString::FromUTF8(bsName.AsStringC()),
3435         CFX_WideString::FromUTF8(bsValue.AsStringC()));
3436   }
3437   pArguments->GetReturnValue()->SetNull();
3438 }
3439 
Script_Packet_RemoveAttribute(CFXJSE_Arguments * pArguments)3440 void CXFA_Node::Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments) {
3441   if (pArguments->GetLength() != 1) {
3442     ThrowParamCountMismatchException(L"removeAttribute");
3443     return;
3444   }
3445 
3446   CFX_ByteString bsName = pArguments->GetUTF8String(0);
3447   CFX_WideString wsName = CFX_WideString::FromUTF8(bsName.AsStringC());
3448   CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3449   if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3450     CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3451     if (pXMLElement->HasAttribute(wsName.c_str())) {
3452       pXMLElement->RemoveAttribute(wsName.c_str());
3453     }
3454   }
3455   pArguments->GetReturnValue()->SetNull();
3456 }
3457 
Script_Packet_Content(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3458 void CXFA_Node::Script_Packet_Content(CFXJSE_Value* pValue,
3459                                       bool bSetting,
3460                                       XFA_ATTRIBUTE eAttribute) {
3461   if (bSetting) {
3462     CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3463     if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3464       CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3465       pXMLElement->SetTextData(pValue->ToWideString());
3466     }
3467   } else {
3468     CFX_WideString wsTextData;
3469     CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3470     if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3471       CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3472       pXMLElement->GetTextData(wsTextData);
3473     }
3474     pValue->SetString(wsTextData.UTF8Encode().AsStringC());
3475   }
3476 }
3477 
Script_Source_Next(CFXJSE_Arguments * pArguments)3478 void CXFA_Node::Script_Source_Next(CFXJSE_Arguments* pArguments) {
3479   if (pArguments->GetLength() != 0)
3480     ThrowParamCountMismatchException(L"next");
3481 }
3482 
Script_Source_CancelBatch(CFXJSE_Arguments * pArguments)3483 void CXFA_Node::Script_Source_CancelBatch(CFXJSE_Arguments* pArguments) {
3484   if (pArguments->GetLength() != 0)
3485     ThrowParamCountMismatchException(L"cancelBatch");
3486 }
3487 
Script_Source_First(CFXJSE_Arguments * pArguments)3488 void CXFA_Node::Script_Source_First(CFXJSE_Arguments* pArguments) {
3489   if (pArguments->GetLength() != 0)
3490     ThrowParamCountMismatchException(L"first");
3491 }
3492 
Script_Source_UpdateBatch(CFXJSE_Arguments * pArguments)3493 void CXFA_Node::Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments) {
3494   if (pArguments->GetLength() != 0)
3495     ThrowParamCountMismatchException(L"updateBatch");
3496 }
3497 
Script_Source_Previous(CFXJSE_Arguments * pArguments)3498 void CXFA_Node::Script_Source_Previous(CFXJSE_Arguments* pArguments) {
3499   if (pArguments->GetLength() != 0)
3500     ThrowParamCountMismatchException(L"previous");
3501 }
3502 
Script_Source_IsBOF(CFXJSE_Arguments * pArguments)3503 void CXFA_Node::Script_Source_IsBOF(CFXJSE_Arguments* pArguments) {
3504   if (pArguments->GetLength() != 0)
3505     ThrowParamCountMismatchException(L"isBOF");
3506 }
3507 
Script_Source_IsEOF(CFXJSE_Arguments * pArguments)3508 void CXFA_Node::Script_Source_IsEOF(CFXJSE_Arguments* pArguments) {
3509   if (pArguments->GetLength() != 0)
3510     ThrowParamCountMismatchException(L"isEOF");
3511 }
3512 
Script_Source_Cancel(CFXJSE_Arguments * pArguments)3513 void CXFA_Node::Script_Source_Cancel(CFXJSE_Arguments* pArguments) {
3514   if (pArguments->GetLength() != 0)
3515     ThrowParamCountMismatchException(L"cancel");
3516 }
3517 
Script_Source_Update(CFXJSE_Arguments * pArguments)3518 void CXFA_Node::Script_Source_Update(CFXJSE_Arguments* pArguments) {
3519   if (pArguments->GetLength() != 0)
3520     ThrowParamCountMismatchException(L"update");
3521 }
3522 
Script_Source_Open(CFXJSE_Arguments * pArguments)3523 void CXFA_Node::Script_Source_Open(CFXJSE_Arguments* pArguments) {
3524   if (pArguments->GetLength() != 0)
3525     ThrowParamCountMismatchException(L"open");
3526 }
3527 
Script_Source_Delete(CFXJSE_Arguments * pArguments)3528 void CXFA_Node::Script_Source_Delete(CFXJSE_Arguments* pArguments) {
3529   if (pArguments->GetLength() != 0)
3530     ThrowParamCountMismatchException(L"delete");
3531 }
3532 
Script_Source_AddNew(CFXJSE_Arguments * pArguments)3533 void CXFA_Node::Script_Source_AddNew(CFXJSE_Arguments* pArguments) {
3534   if (pArguments->GetLength() != 0)
3535     ThrowParamCountMismatchException(L"addNew");
3536 }
3537 
Script_Source_Requery(CFXJSE_Arguments * pArguments)3538 void CXFA_Node::Script_Source_Requery(CFXJSE_Arguments* pArguments) {
3539   if (pArguments->GetLength() != 0)
3540     ThrowParamCountMismatchException(L"requery");
3541 }
3542 
Script_Source_Resync(CFXJSE_Arguments * pArguments)3543 void CXFA_Node::Script_Source_Resync(CFXJSE_Arguments* pArguments) {
3544   if (pArguments->GetLength() != 0)
3545     ThrowParamCountMismatchException(L"resync");
3546 }
3547 
Script_Source_Close(CFXJSE_Arguments * pArguments)3548 void CXFA_Node::Script_Source_Close(CFXJSE_Arguments* pArguments) {
3549   if (pArguments->GetLength() != 0)
3550     ThrowParamCountMismatchException(L"close");
3551 }
3552 
Script_Source_Last(CFXJSE_Arguments * pArguments)3553 void CXFA_Node::Script_Source_Last(CFXJSE_Arguments* pArguments) {
3554   if (pArguments->GetLength() != 0)
3555     ThrowParamCountMismatchException(L"last");
3556 }
3557 
Script_Source_HasDataChanged(CFXJSE_Arguments * pArguments)3558 void CXFA_Node::Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments) {
3559   if (pArguments->GetLength() != 0)
3560     ThrowParamCountMismatchException(L"hasDataChanged");
3561 }
3562 
Script_Source_Db(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3563 void CXFA_Node::Script_Source_Db(CFXJSE_Value* pValue,
3564                                  bool bSetting,
3565                                  XFA_ATTRIBUTE eAttribute) {}
3566 
Script_Xfa_This(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3567 void CXFA_Node::Script_Xfa_This(CFXJSE_Value* pValue,
3568                                 bool bSetting,
3569                                 XFA_ATTRIBUTE eAttribute) {
3570   if (!bSetting) {
3571     CXFA_Object* pThis = m_pDocument->GetScriptContext()->GetThisObject();
3572     ASSERT(pThis);
3573     pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pThis));
3574   }
3575 }
3576 
Script_Handler_Version(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3577 void CXFA_Node::Script_Handler_Version(CFXJSE_Value* pValue,
3578                                        bool bSetting,
3579                                        XFA_ATTRIBUTE eAttribute) {}
3580 
Script_SubmitFormat_Mode(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3581 void CXFA_Node::Script_SubmitFormat_Mode(CFXJSE_Value* pValue,
3582                                          bool bSetting,
3583                                          XFA_ATTRIBUTE eAttribute) {}
3584 
Script_Extras_Type(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3585 void CXFA_Node::Script_Extras_Type(CFXJSE_Value* pValue,
3586                                    bool bSetting,
3587                                    XFA_ATTRIBUTE eAttribute) {}
3588 
Script_Script_Stateless(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3589 void CXFA_Node::Script_Script_Stateless(CFXJSE_Value* pValue,
3590                                         bool bSetting,
3591                                         XFA_ATTRIBUTE eAttribute) {
3592   if (bSetting) {
3593     ThrowInvalidPropertyException();
3594     return;
3595   }
3596   pValue->SetString(FX_UTF8Encode(CFX_WideStringC(L"0", 1)).AsStringC());
3597 }
3598 
Script_Encrypt_Format(CFXJSE_Value * pValue,bool bSetting,XFA_ATTRIBUTE eAttribute)3599 void CXFA_Node::Script_Encrypt_Format(CFXJSE_Value* pValue,
3600                                       bool bSetting,
3601                                       XFA_ATTRIBUTE eAttribute) {}
3602 
HasAttribute(XFA_ATTRIBUTE eAttr,bool bCanInherit)3603 bool CXFA_Node::HasAttribute(XFA_ATTRIBUTE eAttr, bool bCanInherit) {
3604   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3605   return HasMapModuleKey(pKey, bCanInherit);
3606 }
3607 
SetAttribute(XFA_ATTRIBUTE eAttr,const CFX_WideStringC & wsValue,bool bNotify)3608 bool CXFA_Node::SetAttribute(XFA_ATTRIBUTE eAttr,
3609                              const CFX_WideStringC& wsValue,
3610                              bool bNotify) {
3611   const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
3612   if (!pAttr)
3613     return false;
3614 
3615   XFA_ATTRIBUTETYPE eType = pAttr->eType;
3616   if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
3617     const XFA_NOTSUREATTRIBUTE* pNotsure =
3618         XFA_GetNotsureAttribute(GetElementType(), pAttr->eName);
3619     eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
3620   }
3621   switch (eType) {
3622     case XFA_ATTRIBUTETYPE_Enum: {
3623       const XFA_ATTRIBUTEENUMINFO* pEnum = XFA_GetAttributeEnumByName(wsValue);
3624       return SetEnum(pAttr->eName,
3625                      pEnum ? pEnum->eName
3626                            : (XFA_ATTRIBUTEENUM)(intptr_t)(pAttr->pDefValue),
3627                      bNotify);
3628     } break;
3629     case XFA_ATTRIBUTETYPE_Cdata:
3630       return SetCData(pAttr->eName, CFX_WideString(wsValue), bNotify);
3631     case XFA_ATTRIBUTETYPE_Boolean:
3632       return SetBoolean(pAttr->eName, wsValue != L"0", bNotify);
3633     case XFA_ATTRIBUTETYPE_Integer:
3634       return SetInteger(pAttr->eName,
3635                         FXSYS_round(FXSYS_wcstof(wsValue.c_str(),
3636                                                  wsValue.GetLength(), nullptr)),
3637                         bNotify);
3638     case XFA_ATTRIBUTETYPE_Measure:
3639       return SetMeasure(pAttr->eName, CXFA_Measurement(wsValue), bNotify);
3640     default:
3641       break;
3642   }
3643   return false;
3644 }
3645 
GetAttribute(XFA_ATTRIBUTE eAttr,CFX_WideString & wsValue,bool bUseDefault)3646 bool CXFA_Node::GetAttribute(XFA_ATTRIBUTE eAttr,
3647                              CFX_WideString& wsValue,
3648                              bool bUseDefault) {
3649   const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
3650   if (!pAttr) {
3651     return false;
3652   }
3653   XFA_ATTRIBUTETYPE eType = pAttr->eType;
3654   if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
3655     const XFA_NOTSUREATTRIBUTE* pNotsure =
3656         XFA_GetNotsureAttribute(GetElementType(), pAttr->eName);
3657     eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
3658   }
3659   switch (eType) {
3660     case XFA_ATTRIBUTETYPE_Enum: {
3661       XFA_ATTRIBUTEENUM eValue;
3662       if (!TryEnum(pAttr->eName, eValue, bUseDefault)) {
3663         return false;
3664       }
3665       wsValue = GetAttributeEnumByID(eValue)->pName;
3666       return true;
3667     } break;
3668     case XFA_ATTRIBUTETYPE_Cdata: {
3669       CFX_WideStringC wsValueC;
3670       if (!TryCData(pAttr->eName, wsValueC, bUseDefault)) {
3671         return false;
3672       }
3673       wsValue = wsValueC;
3674       return true;
3675     } break;
3676     case XFA_ATTRIBUTETYPE_Boolean: {
3677       bool bValue;
3678       if (!TryBoolean(pAttr->eName, bValue, bUseDefault)) {
3679         return false;
3680       }
3681       wsValue = bValue ? L"1" : L"0";
3682       return true;
3683     } break;
3684     case XFA_ATTRIBUTETYPE_Integer: {
3685       int32_t iValue;
3686       if (!TryInteger(pAttr->eName, iValue, bUseDefault)) {
3687         return false;
3688       }
3689       wsValue.Format(L"%d", iValue);
3690       return true;
3691     } break;
3692     case XFA_ATTRIBUTETYPE_Measure: {
3693       CXFA_Measurement mValue;
3694       if (!TryMeasure(pAttr->eName, mValue, bUseDefault)) {
3695         return false;
3696       }
3697       mValue.ToString(wsValue);
3698       return true;
3699     } break;
3700     default:
3701       break;
3702   }
3703   return false;
3704 }
3705 
SetAttribute(const CFX_WideStringC & wsAttr,const CFX_WideStringC & wsValue,bool bNotify)3706 bool CXFA_Node::SetAttribute(const CFX_WideStringC& wsAttr,
3707                              const CFX_WideStringC& wsValue,
3708                              bool bNotify) {
3709   const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsValue);
3710   if (pAttributeInfo) {
3711     return SetAttribute(pAttributeInfo->eName, wsValue, bNotify);
3712   }
3713   void* pKey = GetMapKey_Custom(wsAttr);
3714   SetMapModuleString(pKey, wsValue);
3715   return true;
3716 }
3717 
GetAttribute(const CFX_WideStringC & wsAttr,CFX_WideString & wsValue,bool bUseDefault)3718 bool CXFA_Node::GetAttribute(const CFX_WideStringC& wsAttr,
3719                              CFX_WideString& wsValue,
3720                              bool bUseDefault) {
3721   const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsAttr);
3722   if (pAttributeInfo) {
3723     return GetAttribute(pAttributeInfo->eName, wsValue, bUseDefault);
3724   }
3725   void* pKey = GetMapKey_Custom(wsAttr);
3726   CFX_WideStringC wsValueC;
3727   if (GetMapModuleString(pKey, wsValueC)) {
3728     wsValue = wsValueC;
3729   }
3730   return true;
3731 }
3732 
RemoveAttribute(const CFX_WideStringC & wsAttr)3733 bool CXFA_Node::RemoveAttribute(const CFX_WideStringC& wsAttr) {
3734   void* pKey = GetMapKey_Custom(wsAttr);
3735   RemoveMapModuleKey(pKey);
3736   return true;
3737 }
3738 
TryBoolean(XFA_ATTRIBUTE eAttr,bool & bValue,bool bUseDefault)3739 bool CXFA_Node::TryBoolean(XFA_ATTRIBUTE eAttr,
3740                            bool& bValue,
3741                            bool bUseDefault) {
3742   void* pValue = nullptr;
3743   if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, bUseDefault, pValue))
3744     return false;
3745   bValue = !!pValue;
3746   return true;
3747 }
3748 
TryInteger(XFA_ATTRIBUTE eAttr,int32_t & iValue,bool bUseDefault)3749 bool CXFA_Node::TryInteger(XFA_ATTRIBUTE eAttr,
3750                            int32_t& iValue,
3751                            bool bUseDefault) {
3752   void* pValue = nullptr;
3753   if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, bUseDefault, pValue))
3754     return false;
3755   iValue = (int32_t)(uintptr_t)pValue;
3756   return true;
3757 }
3758 
TryEnum(XFA_ATTRIBUTE eAttr,XFA_ATTRIBUTEENUM & eValue,bool bUseDefault)3759 bool CXFA_Node::TryEnum(XFA_ATTRIBUTE eAttr,
3760                         XFA_ATTRIBUTEENUM& eValue,
3761                         bool bUseDefault) {
3762   void* pValue = nullptr;
3763   if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, bUseDefault, pValue))
3764     return false;
3765   eValue = (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
3766   return true;
3767 }
3768 
SetMeasure(XFA_ATTRIBUTE eAttr,CXFA_Measurement mValue,bool bNotify)3769 bool CXFA_Node::SetMeasure(XFA_ATTRIBUTE eAttr,
3770                            CXFA_Measurement mValue,
3771                            bool bNotify) {
3772   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3773   OnChanging(eAttr, bNotify);
3774   SetMapModuleBuffer(pKey, &mValue, sizeof(CXFA_Measurement));
3775   OnChanged(eAttr, bNotify, false);
3776   return true;
3777 }
3778 
TryMeasure(XFA_ATTRIBUTE eAttr,CXFA_Measurement & mValue,bool bUseDefault) const3779 bool CXFA_Node::TryMeasure(XFA_ATTRIBUTE eAttr,
3780                            CXFA_Measurement& mValue,
3781                            bool bUseDefault) const {
3782   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3783   void* pValue;
3784   int32_t iBytes;
3785   if (GetMapModuleBuffer(pKey, pValue, iBytes) && iBytes == sizeof(mValue)) {
3786     FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
3787     return true;
3788   }
3789   if (bUseDefault &&
3790       XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3791                                    XFA_ATTRIBUTETYPE_Measure, m_ePacket)) {
3792     FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
3793     return true;
3794   }
3795   return false;
3796 }
3797 
GetMeasure(XFA_ATTRIBUTE eAttr) const3798 CXFA_Measurement CXFA_Node::GetMeasure(XFA_ATTRIBUTE eAttr) const {
3799   CXFA_Measurement mValue;
3800   return TryMeasure(eAttr, mValue, true) ? mValue : CXFA_Measurement();
3801 }
3802 
SetCData(XFA_ATTRIBUTE eAttr,const CFX_WideString & wsValue,bool bNotify,bool bScriptModify)3803 bool CXFA_Node::SetCData(XFA_ATTRIBUTE eAttr,
3804                          const CFX_WideString& wsValue,
3805                          bool bNotify,
3806                          bool bScriptModify) {
3807   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3808   OnChanging(eAttr, bNotify);
3809   if (eAttr == XFA_ATTRIBUTE_Value) {
3810     CFX_WideString* pClone = new CFX_WideString(wsValue);
3811     SetUserData(pKey, pClone, &deleteWideStringCallBack);
3812   } else {
3813     SetMapModuleString(pKey, wsValue.AsStringC());
3814     if (eAttr == XFA_ATTRIBUTE_Name)
3815       UpdateNameHash();
3816   }
3817   OnChanged(eAttr, bNotify, bScriptModify);
3818 
3819   if (!IsNeedSavingXMLNode() || eAttr == XFA_ATTRIBUTE_QualifiedName ||
3820       eAttr == XFA_ATTRIBUTE_BindingNode) {
3821     return true;
3822   }
3823 
3824   if (eAttr == XFA_ATTRIBUTE_Name &&
3825       (m_elementType == XFA_Element::DataValue ||
3826        m_elementType == XFA_Element::DataGroup)) {
3827     return true;
3828   }
3829 
3830   if (eAttr == XFA_ATTRIBUTE_Value) {
3831     FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
3832     switch (eXMLType) {
3833       case FDE_XMLNODE_Element:
3834         if (IsAttributeInXML()) {
3835           static_cast<CFDE_XMLElement*>(m_pXMLNode)
3836               ->SetString(CFX_WideString(GetCData(XFA_ATTRIBUTE_QualifiedName)),
3837                           wsValue);
3838         } else {
3839           bool bDeleteChildren = true;
3840           if (GetPacketID() == XFA_XDPPACKET_Datasets) {
3841             for (CXFA_Node* pChildDataNode =
3842                      GetNodeItem(XFA_NODEITEM_FirstChild);
3843                  pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
3844                                      XFA_NODEITEM_NextSibling)) {
3845               CXFA_NodeArray formNodes;
3846               if (pChildDataNode->GetBindItems(formNodes) > 0) {
3847                 bDeleteChildren = false;
3848                 break;
3849               }
3850             }
3851           }
3852           if (bDeleteChildren) {
3853             static_cast<CFDE_XMLElement*>(m_pXMLNode)->DeleteChildren();
3854           }
3855           static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetTextData(wsValue);
3856         }
3857         break;
3858       case FDE_XMLNODE_Text:
3859         static_cast<CFDE_XMLText*>(m_pXMLNode)->SetText(wsValue);
3860         break;
3861       default:
3862         ASSERT(0);
3863     }
3864     return true;
3865   }
3866 
3867   const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
3868   if (pInfo) {
3869     ASSERT(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
3870     CFX_WideString wsAttrName = pInfo->pName;
3871     if (pInfo->eName == XFA_ATTRIBUTE_ContentType) {
3872       wsAttrName = L"xfa:" + wsAttrName;
3873     }
3874     static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetString(wsAttrName, wsValue);
3875   }
3876   return true;
3877 }
3878 
SetAttributeValue(const CFX_WideString & wsValue,const CFX_WideString & wsXMLValue,bool bNotify,bool bScriptModify)3879 bool CXFA_Node::SetAttributeValue(const CFX_WideString& wsValue,
3880                                   const CFX_WideString& wsXMLValue,
3881                                   bool bNotify,
3882                                   bool bScriptModify) {
3883   void* pKey = GetMapKey_Element(GetElementType(), XFA_ATTRIBUTE_Value);
3884   OnChanging(XFA_ATTRIBUTE_Value, bNotify);
3885   CFX_WideString* pClone = new CFX_WideString(wsValue);
3886   SetUserData(pKey, pClone, &deleteWideStringCallBack);
3887   OnChanged(XFA_ATTRIBUTE_Value, bNotify, bScriptModify);
3888   if (IsNeedSavingXMLNode()) {
3889     FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
3890     switch (eXMLType) {
3891       case FDE_XMLNODE_Element:
3892         if (IsAttributeInXML()) {
3893           static_cast<CFDE_XMLElement*>(m_pXMLNode)
3894               ->SetString(CFX_WideString(GetCData(XFA_ATTRIBUTE_QualifiedName)),
3895                           wsXMLValue);
3896         } else {
3897           bool bDeleteChildren = true;
3898           if (GetPacketID() == XFA_XDPPACKET_Datasets) {
3899             for (CXFA_Node* pChildDataNode =
3900                      GetNodeItem(XFA_NODEITEM_FirstChild);
3901                  pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
3902                                      XFA_NODEITEM_NextSibling)) {
3903               CXFA_NodeArray formNodes;
3904               if (pChildDataNode->GetBindItems(formNodes) > 0) {
3905                 bDeleteChildren = false;
3906                 break;
3907               }
3908             }
3909           }
3910           if (bDeleteChildren) {
3911             static_cast<CFDE_XMLElement*>(m_pXMLNode)->DeleteChildren();
3912           }
3913           static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetTextData(wsXMLValue);
3914         }
3915         break;
3916       case FDE_XMLNODE_Text:
3917         static_cast<CFDE_XMLText*>(m_pXMLNode)->SetText(wsXMLValue);
3918         break;
3919       default:
3920         ASSERT(0);
3921     }
3922   }
3923   return true;
3924 }
3925 
TryCData(XFA_ATTRIBUTE eAttr,CFX_WideString & wsValue,bool bUseDefault,bool bProto)3926 bool CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
3927                          CFX_WideString& wsValue,
3928                          bool bUseDefault,
3929                          bool bProto) {
3930   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3931   if (eAttr == XFA_ATTRIBUTE_Value) {
3932     CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
3933     if (pStr) {
3934       wsValue = *pStr;
3935       return true;
3936     }
3937   } else {
3938     CFX_WideStringC wsValueC;
3939     if (GetMapModuleString(pKey, wsValueC)) {
3940       wsValue = wsValueC;
3941       return true;
3942     }
3943   }
3944   if (!bUseDefault) {
3945     return false;
3946   }
3947   void* pValue = nullptr;
3948   if (XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3949                                    XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
3950     wsValue = (const FX_WCHAR*)pValue;
3951     return true;
3952   }
3953   return false;
3954 }
3955 
TryCData(XFA_ATTRIBUTE eAttr,CFX_WideStringC & wsValue,bool bUseDefault,bool bProto)3956 bool CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
3957                          CFX_WideStringC& wsValue,
3958                          bool bUseDefault,
3959                          bool bProto) {
3960   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3961   if (eAttr == XFA_ATTRIBUTE_Value) {
3962     CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
3963     if (pStr) {
3964       wsValue = pStr->AsStringC();
3965       return true;
3966     }
3967   } else {
3968     if (GetMapModuleString(pKey, wsValue)) {
3969       return true;
3970     }
3971   }
3972   if (!bUseDefault) {
3973     return false;
3974   }
3975   void* pValue = nullptr;
3976   if (XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3977                                    XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
3978     wsValue = (CFX_WideStringC)(const FX_WCHAR*)pValue;
3979     return true;
3980   }
3981   return false;
3982 }
3983 
SetObject(XFA_ATTRIBUTE eAttr,void * pData,XFA_MAPDATABLOCKCALLBACKINFO * pCallbackInfo)3984 bool CXFA_Node::SetObject(XFA_ATTRIBUTE eAttr,
3985                           void* pData,
3986                           XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
3987   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3988   return SetUserData(pKey, pData, pCallbackInfo);
3989 }
3990 
TryObject(XFA_ATTRIBUTE eAttr,void * & pData)3991 bool CXFA_Node::TryObject(XFA_ATTRIBUTE eAttr, void*& pData) {
3992   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3993   pData = GetUserData(pKey);
3994   return !!pData;
3995 }
3996 
SetValue(XFA_ATTRIBUTE eAttr,XFA_ATTRIBUTETYPE eType,void * pValue,bool bNotify)3997 bool CXFA_Node::SetValue(XFA_ATTRIBUTE eAttr,
3998                          XFA_ATTRIBUTETYPE eType,
3999                          void* pValue,
4000                          bool bNotify) {
4001   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
4002   OnChanging(eAttr, bNotify);
4003   SetMapModuleValue(pKey, pValue);
4004   OnChanged(eAttr, bNotify, false);
4005   if (IsNeedSavingXMLNode()) {
4006     ASSERT(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
4007     const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
4008     if (pInfo) {
4009       switch (eType) {
4010         case XFA_ATTRIBUTETYPE_Enum:
4011           static_cast<CFDE_XMLElement*>(m_pXMLNode)
4012               ->SetString(
4013                   pInfo->pName,
4014                   GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(uintptr_t)pValue)
4015                       ->pName);
4016           break;
4017         case XFA_ATTRIBUTETYPE_Boolean:
4018           static_cast<CFDE_XMLElement*>(m_pXMLNode)
4019               ->SetString(pInfo->pName, pValue ? L"1" : L"0");
4020           break;
4021         case XFA_ATTRIBUTETYPE_Integer:
4022           static_cast<CFDE_XMLElement*>(m_pXMLNode)
4023               ->SetInteger(pInfo->pName, (int32_t)(uintptr_t)pValue);
4024           break;
4025         default:
4026           ASSERT(0);
4027       }
4028     }
4029   }
4030   return true;
4031 }
4032 
GetValue(XFA_ATTRIBUTE eAttr,XFA_ATTRIBUTETYPE eType,bool bUseDefault,void * & pValue)4033 bool CXFA_Node::GetValue(XFA_ATTRIBUTE eAttr,
4034                          XFA_ATTRIBUTETYPE eType,
4035                          bool bUseDefault,
4036                          void*& pValue) {
4037   void* pKey = GetMapKey_Element(GetElementType(), eAttr);
4038   if (GetMapModuleValue(pKey, pValue)) {
4039     return true;
4040   }
4041   if (!bUseDefault) {
4042     return false;
4043   }
4044   return XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr, eType,
4045                                       m_ePacket);
4046 }
4047 
SetUserData(void * pKey,void * pData,XFA_MAPDATABLOCKCALLBACKINFO * pCallbackInfo)4048 bool CXFA_Node::SetUserData(void* pKey,
4049                             void* pData,
4050                             XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
4051   SetMapModuleBuffer(pKey, &pData, sizeof(void*),
4052                      pCallbackInfo ? pCallbackInfo : &gs_XFADefaultFreeData);
4053   return true;
4054 }
4055 
TryUserData(void * pKey,void * & pData,bool bProtoAlso)4056 bool CXFA_Node::TryUserData(void* pKey, void*& pData, bool bProtoAlso) {
4057   int32_t iBytes = 0;
4058   if (!GetMapModuleBuffer(pKey, pData, iBytes, bProtoAlso)) {
4059     return false;
4060   }
4061   return iBytes == sizeof(void*) && FXSYS_memcpy(&pData, pData, iBytes);
4062 }
4063 
SetScriptContent(const CFX_WideString & wsContent,const CFX_WideString & wsXMLValue,bool bNotify,bool bScriptModify,bool bSyncData)4064 bool CXFA_Node::SetScriptContent(const CFX_WideString& wsContent,
4065                                  const CFX_WideString& wsXMLValue,
4066                                  bool bNotify,
4067                                  bool bScriptModify,
4068                                  bool bSyncData) {
4069   CXFA_Node* pNode = nullptr;
4070   CXFA_Node* pBindNode = nullptr;
4071   switch (GetObjectType()) {
4072     case XFA_ObjectType::ContainerNode: {
4073       if (XFA_FieldIsMultiListBox(this)) {
4074         CXFA_Node* pValue = GetProperty(0, XFA_Element::Value);
4075         CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4076         ASSERT(pChildValue);
4077         pChildValue->SetCData(XFA_ATTRIBUTE_ContentType, L"text/xml");
4078         pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
4079                                       bScriptModify, false);
4080         CXFA_Node* pBind = GetBindData();
4081         if (bSyncData && pBind) {
4082           std::vector<CFX_WideString> wsSaveTextArray;
4083           int32_t iSize = 0;
4084           if (!wsContent.IsEmpty()) {
4085             int32_t iStart = 0;
4086             int32_t iLength = wsContent.GetLength();
4087             int32_t iEnd = wsContent.Find(L'\n', iStart);
4088             iEnd = (iEnd == -1) ? iLength : iEnd;
4089             while (iEnd >= iStart) {
4090               wsSaveTextArray.push_back(wsContent.Mid(iStart, iEnd - iStart));
4091               iStart = iEnd + 1;
4092               if (iStart >= iLength) {
4093                 break;
4094               }
4095               iEnd = wsContent.Find(L'\n', iStart);
4096               if (iEnd < 0) {
4097                 wsSaveTextArray.push_back(
4098                     wsContent.Mid(iStart, iLength - iStart));
4099               }
4100             }
4101             iSize = pdfium::CollectionSize<int32_t>(wsSaveTextArray);
4102           }
4103           if (iSize == 0) {
4104             while (CXFA_Node* pChildNode =
4105                        pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
4106               pBind->RemoveChild(pChildNode);
4107             }
4108           } else {
4109             CXFA_NodeArray valueNodes;
4110             int32_t iDatas = pBind->GetNodeList(
4111                 valueNodes, XFA_NODEFILTER_Children, XFA_Element::DataValue);
4112             if (iDatas < iSize) {
4113               int32_t iAddNodes = iSize - iDatas;
4114               CXFA_Node* pValueNodes = nullptr;
4115               while (iAddNodes-- > 0) {
4116                 pValueNodes =
4117                     pBind->CreateSamePacketNode(XFA_Element::DataValue);
4118                 pValueNodes->SetCData(XFA_ATTRIBUTE_Name, L"value");
4119                 pValueNodes->CreateXMLMappingNode();
4120                 pBind->InsertChild(pValueNodes);
4121               }
4122               pValueNodes = nullptr;
4123             } else if (iDatas > iSize) {
4124               int32_t iDelNodes = iDatas - iSize;
4125               while (iDelNodes-- > 0) {
4126                 pBind->RemoveChild(pBind->GetNodeItem(XFA_NODEITEM_FirstChild));
4127               }
4128             }
4129             int32_t i = 0;
4130             for (CXFA_Node* pValueNode =
4131                      pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
4132                  pValueNode; pValueNode = pValueNode->GetNodeItem(
4133                                  XFA_NODEITEM_NextSibling)) {
4134               pValueNode->SetAttributeValue(wsSaveTextArray[i],
4135                                             wsSaveTextArray[i], false);
4136               i++;
4137             }
4138           }
4139           CXFA_NodeArray nodeArray;
4140           pBind->GetBindItems(nodeArray);
4141           for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4142             if (nodeArray[i] != this) {
4143               nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify,
4144                                              bScriptModify, false);
4145             }
4146           }
4147         }
4148         break;
4149       } else if (GetElementType() == XFA_Element::ExclGroup) {
4150         pNode = this;
4151       } else {
4152         CXFA_Node* pValue = GetProperty(0, XFA_Element::Value);
4153         CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4154         ASSERT(pChildValue);
4155         pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
4156                                       bScriptModify, false);
4157       }
4158       pBindNode = GetBindData();
4159       if (pBindNode && bSyncData) {
4160         pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
4161                                     bScriptModify, false);
4162         CXFA_NodeArray nodeArray;
4163         pBindNode->GetBindItems(nodeArray);
4164         for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4165           if (nodeArray[i] != this) {
4166             nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify, true,
4167                                            false);
4168           }
4169         }
4170       }
4171       pBindNode = nullptr;
4172       break;
4173     }
4174     case XFA_ObjectType::ContentNode: {
4175       CFX_WideString wsContentType;
4176       if (GetElementType() == XFA_Element::ExData) {
4177         GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false);
4178         if (wsContentType == L"text/html") {
4179           wsContentType = L"";
4180           SetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType.AsStringC());
4181         }
4182       }
4183       CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
4184       if (!pContentRawDataNode) {
4185         pContentRawDataNode = CreateSamePacketNode(
4186             (wsContentType == L"text/xml") ? XFA_Element::Sharpxml
4187                                            : XFA_Element::Sharptext);
4188         InsertChild(pContentRawDataNode);
4189       }
4190       return pContentRawDataNode->SetScriptContent(
4191           wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
4192     } break;
4193     case XFA_ObjectType::NodeC:
4194     case XFA_ObjectType::TextNode:
4195       pNode = this;
4196       break;
4197     case XFA_ObjectType::NodeV:
4198       pNode = this;
4199       if (bSyncData && GetPacketID() == XFA_XDPPACKET_Form) {
4200         CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
4201         if (pParent) {
4202           pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
4203         }
4204         if (pParent && pParent->GetElementType() == XFA_Element::Value) {
4205           pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
4206           if (pParent && pParent->IsContainerNode()) {
4207             pBindNode = pParent->GetBindData();
4208             if (pBindNode) {
4209               pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
4210                                           bScriptModify, false);
4211             }
4212           }
4213         }
4214       }
4215       break;
4216     default:
4217       if (GetElementType() == XFA_Element::DataValue) {
4218         pNode = this;
4219         pBindNode = this;
4220       }
4221       break;
4222   }
4223   if (pNode) {
4224     SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
4225     if (pBindNode && bSyncData) {
4226       CXFA_NodeArray nodeArray;
4227       pBindNode->GetBindItems(nodeArray);
4228       for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4229         nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify,
4230                                        bScriptModify, false);
4231       }
4232     }
4233     return true;
4234   }
4235   return false;
4236 }
4237 
SetContent(const CFX_WideString & wsContent,const CFX_WideString & wsXMLValue,bool bNotify,bool bScriptModify,bool bSyncData)4238 bool CXFA_Node::SetContent(const CFX_WideString& wsContent,
4239                            const CFX_WideString& wsXMLValue,
4240                            bool bNotify,
4241                            bool bScriptModify,
4242                            bool bSyncData) {
4243   return SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify,
4244                           bSyncData);
4245 }
4246 
GetScriptContent(bool bScriptModify)4247 CFX_WideString CXFA_Node::GetScriptContent(bool bScriptModify) {
4248   CFX_WideString wsContent;
4249   return TryContent(wsContent, bScriptModify) ? wsContent : CFX_WideString();
4250 }
4251 
GetContent()4252 CFX_WideString CXFA_Node::GetContent() {
4253   return GetScriptContent();
4254 }
4255 
TryContent(CFX_WideString & wsContent,bool bScriptModify,bool bProto)4256 bool CXFA_Node::TryContent(CFX_WideString& wsContent,
4257                            bool bScriptModify,
4258                            bool bProto) {
4259   CXFA_Node* pNode = nullptr;
4260   switch (GetObjectType()) {
4261     case XFA_ObjectType::ContainerNode:
4262       if (GetElementType() == XFA_Element::ExclGroup) {
4263         pNode = this;
4264       } else {
4265         CXFA_Node* pValue = GetChild(0, XFA_Element::Value);
4266         if (!pValue) {
4267           return false;
4268         }
4269         CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4270         if (pChildValue && XFA_FieldIsMultiListBox(this)) {
4271           pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType, L"text/xml");
4272         }
4273         return pChildValue
4274                    ? pChildValue->TryContent(wsContent, bScriptModify, bProto)
4275                    : false;
4276       }
4277       break;
4278     case XFA_ObjectType::ContentNode: {
4279       CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
4280       if (!pContentRawDataNode) {
4281         XFA_Element element = XFA_Element::Sharptext;
4282         if (GetElementType() == XFA_Element::ExData) {
4283           CFX_WideString wsContentType;
4284           GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false);
4285           if (wsContentType == L"text/html") {
4286             element = XFA_Element::SharpxHTML;
4287           } else if (wsContentType == L"text/xml") {
4288             element = XFA_Element::Sharpxml;
4289           }
4290         }
4291         pContentRawDataNode = CreateSamePacketNode(element);
4292         InsertChild(pContentRawDataNode);
4293       }
4294       return pContentRawDataNode->TryContent(wsContent, bScriptModify, bProto);
4295     }
4296     case XFA_ObjectType::NodeC:
4297     case XFA_ObjectType::NodeV:
4298     case XFA_ObjectType::TextNode:
4299       pNode = this;
4300     default:
4301       if (GetElementType() == XFA_Element::DataValue) {
4302         pNode = this;
4303       }
4304       break;
4305   }
4306   if (pNode) {
4307     if (bScriptModify) {
4308       CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4309       if (pScriptContext) {
4310         m_pDocument->GetScriptContext()->AddNodesOfRunScript(this);
4311       }
4312     }
4313     return TryCData(XFA_ATTRIBUTE_Value, wsContent, false, bProto);
4314   }
4315   return false;
4316 }
4317 
GetModelNode()4318 CXFA_Node* CXFA_Node::GetModelNode() {
4319   switch (GetPacketID()) {
4320     case XFA_XDPPACKET_XDP:
4321       return m_pDocument->GetRoot();
4322     case XFA_XDPPACKET_Config:
4323       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
4324     case XFA_XDPPACKET_Template:
4325       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
4326     case XFA_XDPPACKET_Form:
4327       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
4328     case XFA_XDPPACKET_Datasets:
4329       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
4330     case XFA_XDPPACKET_LocaleSet:
4331       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_LocaleSet));
4332     case XFA_XDPPACKET_ConnectionSet:
4333       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_ConnectionSet));
4334     case XFA_XDPPACKET_SourceSet:
4335       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_SourceSet));
4336     case XFA_XDPPACKET_Xdc:
4337       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Xdc));
4338     default:
4339       return this;
4340   }
4341 }
4342 
TryNamespace(CFX_WideString & wsNamespace)4343 bool CXFA_Node::TryNamespace(CFX_WideString& wsNamespace) {
4344   wsNamespace.clear();
4345   if (IsModelNode() || GetElementType() == XFA_Element::Packet) {
4346     CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
4347     if (!pXMLNode || pXMLNode->GetType() != FDE_XMLNODE_Element) {
4348       return false;
4349     }
4350     static_cast<CFDE_XMLElement*>(pXMLNode)->GetNamespaceURI(wsNamespace);
4351     return true;
4352   } else if (GetPacketID() == XFA_XDPPACKET_Datasets) {
4353     CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
4354     if (!pXMLNode) {
4355       return false;
4356     }
4357     if (pXMLNode->GetType() != FDE_XMLNODE_Element) {
4358       return true;
4359     }
4360     if (GetElementType() == XFA_Element::DataValue &&
4361         GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData) {
4362       return XFA_FDEExtension_ResolveNamespaceQualifier(
4363           static_cast<CFDE_XMLElement*>(pXMLNode),
4364           GetCData(XFA_ATTRIBUTE_QualifiedName), wsNamespace);
4365     }
4366     static_cast<CFDE_XMLElement*>(pXMLNode)->GetNamespaceURI(wsNamespace);
4367     return true;
4368   } else {
4369     CXFA_Node* pModelNode = GetModelNode();
4370     return pModelNode->TryNamespace(wsNamespace);
4371   }
4372 }
4373 
GetProperty(int32_t index,XFA_Element eProperty,bool bCreateProperty)4374 CXFA_Node* CXFA_Node::GetProperty(int32_t index,
4375                                   XFA_Element eProperty,
4376                                   bool bCreateProperty) {
4377   XFA_Element eType = GetElementType();
4378   uint32_t dwPacket = GetPacketID();
4379   const XFA_PROPERTY* pProperty =
4380       XFA_GetPropertyOfElement(eType, eProperty, dwPacket);
4381   if (!pProperty || index >= pProperty->uOccur)
4382     return nullptr;
4383 
4384   CXFA_Node* pNode = m_pChild;
4385   int32_t iCount = 0;
4386   for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4387     if (pNode->GetElementType() == eProperty) {
4388       iCount++;
4389       if (iCount > index) {
4390         return pNode;
4391       }
4392     }
4393   }
4394   if (!bCreateProperty)
4395     return nullptr;
4396 
4397   if (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf) {
4398     pNode = m_pChild;
4399     for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4400       const XFA_PROPERTY* pExistProperty =
4401           XFA_GetPropertyOfElement(eType, pNode->GetElementType(), dwPacket);
4402       if (pExistProperty && (pExistProperty->uFlags & XFA_PROPERTYFLAG_OneOf))
4403         return nullptr;
4404     }
4405   }
4406 
4407   const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(dwPacket);
4408   CXFA_Node* pNewNode = nullptr;
4409   for (; iCount <= index; iCount++) {
4410     pNewNode = m_pDocument->CreateNode(pPacket, eProperty);
4411     if (!pNewNode)
4412       return nullptr;
4413     InsertChild(pNewNode, nullptr);
4414     pNewNode->SetFlag(XFA_NodeFlag_Initialized, true);
4415   }
4416   return pNewNode;
4417 }
4418 
CountChildren(XFA_Element eType,bool bOnlyChild)4419 int32_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) {
4420   CXFA_Node* pNode = m_pChild;
4421   int32_t iCount = 0;
4422   for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4423     if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) {
4424       if (bOnlyChild) {
4425         const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
4426             GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN);
4427         if (pProperty) {
4428           continue;
4429         }
4430       }
4431       iCount++;
4432     }
4433   }
4434   return iCount;
4435 }
4436 
GetChild(int32_t index,XFA_Element eType,bool bOnlyChild)4437 CXFA_Node* CXFA_Node::GetChild(int32_t index,
4438                                XFA_Element eType,
4439                                bool bOnlyChild) {
4440   ASSERT(index > -1);
4441   CXFA_Node* pNode = m_pChild;
4442   int32_t iCount = 0;
4443   for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4444     if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) {
4445       if (bOnlyChild) {
4446         const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
4447             GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN);
4448         if (pProperty) {
4449           continue;
4450         }
4451       }
4452       iCount++;
4453       if (iCount > index) {
4454         return pNode;
4455       }
4456     }
4457   }
4458   return nullptr;
4459 }
4460 
InsertChild(int32_t index,CXFA_Node * pNode)4461 int32_t CXFA_Node::InsertChild(int32_t index, CXFA_Node* pNode) {
4462   ASSERT(!pNode->m_pNext);
4463   pNode->m_pParent = this;
4464   bool ret = m_pDocument->RemovePurgeNode(pNode);
4465   ASSERT(ret);
4466   (void)ret;  // Avoid unused variable warning.
4467 
4468   if (!m_pChild || index == 0) {
4469     if (index > 0) {
4470       return -1;
4471     }
4472     pNode->m_pNext = m_pChild;
4473     m_pChild = pNode;
4474     index = 0;
4475   } else if (index < 0) {
4476     m_pLastChild->m_pNext = pNode;
4477   } else {
4478     CXFA_Node* pPrev = m_pChild;
4479     int32_t iCount = 0;
4480     while (++iCount != index && pPrev->m_pNext) {
4481       pPrev = pPrev->m_pNext;
4482     }
4483     if (index > 0 && index != iCount) {
4484       return -1;
4485     }
4486     pNode->m_pNext = pPrev->m_pNext;
4487     pPrev->m_pNext = pNode;
4488     index = iCount;
4489   }
4490   if (!pNode->m_pNext) {
4491     m_pLastChild = pNode;
4492   }
4493   ASSERT(m_pLastChild);
4494   ASSERT(!m_pLastChild->m_pNext);
4495   pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
4496   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4497   if (pNotify)
4498     pNotify->OnChildAdded(this);
4499 
4500   if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4501     ASSERT(!pNode->m_pXMLNode->GetNodeItem(CFDE_XMLNode::Parent));
4502     m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, index);
4503     pNode->ClearFlag(XFA_NodeFlag_OwnXMLNode);
4504   }
4505   return index;
4506 }
4507 
InsertChild(CXFA_Node * pNode,CXFA_Node * pBeforeNode)4508 bool CXFA_Node::InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
4509   if (!pNode || pNode->m_pParent ||
4510       (pBeforeNode && pBeforeNode->m_pParent != this)) {
4511     ASSERT(false);
4512     return false;
4513   }
4514   bool ret = m_pDocument->RemovePurgeNode(pNode);
4515   ASSERT(ret);
4516   (void)ret;  // Avoid unused variable warning.
4517 
4518   int32_t nIndex = -1;
4519   pNode->m_pParent = this;
4520   if (!m_pChild || pBeforeNode == m_pChild) {
4521     pNode->m_pNext = m_pChild;
4522     m_pChild = pNode;
4523     nIndex = 0;
4524   } else if (!pBeforeNode) {
4525     pNode->m_pNext = m_pLastChild->m_pNext;
4526     m_pLastChild->m_pNext = pNode;
4527   } else {
4528     nIndex = 1;
4529     CXFA_Node* pPrev = m_pChild;
4530     while (pPrev->m_pNext != pBeforeNode) {
4531       pPrev = pPrev->m_pNext;
4532       nIndex++;
4533     }
4534     pNode->m_pNext = pPrev->m_pNext;
4535     pPrev->m_pNext = pNode;
4536   }
4537   if (!pNode->m_pNext) {
4538     m_pLastChild = pNode;
4539   }
4540   ASSERT(m_pLastChild);
4541   ASSERT(!m_pLastChild->m_pNext);
4542   pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
4543   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4544   if (pNotify)
4545     pNotify->OnChildAdded(this);
4546 
4547   if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4548     ASSERT(!pNode->m_pXMLNode->GetNodeItem(CFDE_XMLNode::Parent));
4549     m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, nIndex);
4550     pNode->ClearFlag(XFA_NodeFlag_OwnXMLNode);
4551   }
4552   return true;
4553 }
4554 
Deprecated_GetPrevSibling()4555 CXFA_Node* CXFA_Node::Deprecated_GetPrevSibling() {
4556   if (!m_pParent) {
4557     return nullptr;
4558   }
4559   for (CXFA_Node* pSibling = m_pParent->m_pChild; pSibling;
4560        pSibling = pSibling->m_pNext) {
4561     if (pSibling->m_pNext == this) {
4562       return pSibling;
4563     }
4564   }
4565   return nullptr;
4566 }
4567 
RemoveChild(CXFA_Node * pNode,bool bNotify)4568 bool CXFA_Node::RemoveChild(CXFA_Node* pNode, bool bNotify) {
4569   if (!pNode || pNode->m_pParent != this) {
4570     ASSERT(false);
4571     return false;
4572   }
4573   if (m_pChild == pNode) {
4574     m_pChild = pNode->m_pNext;
4575     if (m_pLastChild == pNode) {
4576       m_pLastChild = pNode->m_pNext;
4577     }
4578     pNode->m_pNext = nullptr;
4579     pNode->m_pParent = nullptr;
4580   } else {
4581     CXFA_Node* pPrev = pNode->Deprecated_GetPrevSibling();
4582     pPrev->m_pNext = pNode->m_pNext;
4583     if (m_pLastChild == pNode) {
4584       m_pLastChild = pNode->m_pNext ? pNode->m_pNext : pPrev;
4585     }
4586     pNode->m_pNext = nullptr;
4587     pNode->m_pParent = nullptr;
4588   }
4589   ASSERT(!m_pLastChild || !m_pLastChild->m_pNext);
4590   OnRemoved(bNotify);
4591   pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren, true);
4592   m_pDocument->AddPurgeNode(pNode);
4593   if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4594     if (pNode->IsAttributeInXML()) {
4595       ASSERT(pNode->m_pXMLNode == m_pXMLNode &&
4596              m_pXMLNode->GetType() == FDE_XMLNODE_Element);
4597       if (pNode->m_pXMLNode->GetType() == FDE_XMLNODE_Element) {
4598         CFDE_XMLElement* pXMLElement =
4599             static_cast<CFDE_XMLElement*>(pNode->m_pXMLNode);
4600         CFX_WideStringC wsAttributeName =
4601             pNode->GetCData(XFA_ATTRIBUTE_QualifiedName);
4602         pXMLElement->RemoveAttribute(wsAttributeName.c_str());
4603       }
4604       CFX_WideString wsName;
4605       pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, false);
4606       CFDE_XMLElement* pNewXMLElement = new CFDE_XMLElement(wsName);
4607       CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
4608       if (!wsValue.IsEmpty()) {
4609         pNewXMLElement->SetTextData(CFX_WideString(wsValue));
4610       }
4611       pNode->m_pXMLNode = pNewXMLElement;
4612       pNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
4613     } else {
4614       m_pXMLNode->RemoveChildNode(pNode->m_pXMLNode);
4615     }
4616     pNode->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
4617   }
4618   return true;
4619 }
4620 
GetFirstChildByName(const CFX_WideStringC & wsName) const4621 CXFA_Node* CXFA_Node::GetFirstChildByName(const CFX_WideStringC& wsName) const {
4622   return GetFirstChildByName(FX_HashCode_GetW(wsName, false));
4623 }
4624 
GetFirstChildByName(uint32_t dwNameHash) const4625 CXFA_Node* CXFA_Node::GetFirstChildByName(uint32_t dwNameHash) const {
4626   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
4627        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4628     if (pNode->GetNameHash() == dwNameHash) {
4629       return pNode;
4630     }
4631   }
4632   return nullptr;
4633 }
4634 
GetFirstChildByClass(XFA_Element eType) const4635 CXFA_Node* CXFA_Node::GetFirstChildByClass(XFA_Element eType) const {
4636   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
4637        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4638     if (pNode->GetElementType() == eType) {
4639       return pNode;
4640     }
4641   }
4642   return nullptr;
4643 }
4644 
GetNextSameNameSibling(uint32_t dwNameHash) const4645 CXFA_Node* CXFA_Node::GetNextSameNameSibling(uint32_t dwNameHash) const {
4646   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
4647        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4648     if (pNode->GetNameHash() == dwNameHash) {
4649       return pNode;
4650     }
4651   }
4652   return nullptr;
4653 }
4654 
GetNextSameNameSibling(const CFX_WideStringC & wsNodeName) const4655 CXFA_Node* CXFA_Node::GetNextSameNameSibling(
4656     const CFX_WideStringC& wsNodeName) const {
4657   return GetNextSameNameSibling(FX_HashCode_GetW(wsNodeName, false));
4658 }
4659 
GetNextSameClassSibling(XFA_Element eType) const4660 CXFA_Node* CXFA_Node::GetNextSameClassSibling(XFA_Element eType) const {
4661   for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
4662        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4663     if (pNode->GetElementType() == eType) {
4664       return pNode;
4665     }
4666   }
4667   return nullptr;
4668 }
4669 
GetNodeSameNameIndex() const4670 int32_t CXFA_Node::GetNodeSameNameIndex() const {
4671   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4672   if (!pScriptContext) {
4673     return -1;
4674   }
4675   return pScriptContext->GetIndexByName(const_cast<CXFA_Node*>(this));
4676 }
4677 
GetNodeSameClassIndex() const4678 int32_t CXFA_Node::GetNodeSameClassIndex() const {
4679   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4680   if (!pScriptContext) {
4681     return -1;
4682   }
4683   return pScriptContext->GetIndexByClassName(const_cast<CXFA_Node*>(this));
4684 }
4685 
GetSOMExpression(CFX_WideString & wsSOMExpression)4686 void CXFA_Node::GetSOMExpression(CFX_WideString& wsSOMExpression) {
4687   CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4688   if (!pScriptContext) {
4689     return;
4690   }
4691   pScriptContext->GetSomExpression(this, wsSOMExpression);
4692 }
4693 
GetInstanceMgrOfSubform()4694 CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
4695   CXFA_Node* pInstanceMgr = nullptr;
4696   if (m_ePacket == XFA_XDPPACKET_Form) {
4697     CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
4698     if (!pParentNode || pParentNode->GetElementType() == XFA_Element::Area) {
4699       return pInstanceMgr;
4700     }
4701     for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
4702          pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
4703       XFA_Element eType = pNode->GetElementType();
4704       if ((eType == XFA_Element::Subform || eType == XFA_Element::SubformSet) &&
4705           pNode->m_dwNameHash != m_dwNameHash) {
4706         break;
4707       }
4708       if (eType == XFA_Element::InstanceManager) {
4709         CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
4710         CFX_WideStringC wsInstName = pNode->GetCData(XFA_ATTRIBUTE_Name);
4711         if (wsInstName.GetLength() > 0 && wsInstName.GetAt(0) == '_' &&
4712             wsInstName.Mid(1) == wsName) {
4713           pInstanceMgr = pNode;
4714         }
4715         break;
4716       }
4717     }
4718   }
4719   return pInstanceMgr;
4720 }
4721 
GetOccurNode()4722 CXFA_Node* CXFA_Node::GetOccurNode() {
4723   return GetFirstChildByClass(XFA_Element::Occur);
4724 }
4725 
HasFlag(XFA_NodeFlag dwFlag) const4726 bool CXFA_Node::HasFlag(XFA_NodeFlag dwFlag) const {
4727   if (m_uNodeFlags & dwFlag)
4728     return true;
4729   if (dwFlag == XFA_NodeFlag_HasRemovedChildren)
4730     return m_pParent && m_pParent->HasFlag(dwFlag);
4731   return false;
4732 }
4733 
SetFlag(uint32_t dwFlag,bool bNotify)4734 void CXFA_Node::SetFlag(uint32_t dwFlag, bool bNotify) {
4735   if (dwFlag == XFA_NodeFlag_Initialized && bNotify && !IsInitialized()) {
4736     CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4737     if (pNotify) {
4738       pNotify->OnNodeReady(this);
4739     }
4740   }
4741   m_uNodeFlags |= dwFlag;
4742 }
4743 
ClearFlag(uint32_t dwFlag)4744 void CXFA_Node::ClearFlag(uint32_t dwFlag) {
4745   m_uNodeFlags &= ~dwFlag;
4746 }
4747 
IsAttributeInXML()4748 bool CXFA_Node::IsAttributeInXML() {
4749   return GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData;
4750 }
4751 
OnRemoved(bool bNotify)4752 void CXFA_Node::OnRemoved(bool bNotify) {
4753   if (!bNotify)
4754     return;
4755 
4756   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4757   if (pNotify)
4758     pNotify->OnChildRemoved();
4759 }
4760 
OnChanging(XFA_ATTRIBUTE eAttr,bool bNotify)4761 void CXFA_Node::OnChanging(XFA_ATTRIBUTE eAttr, bool bNotify) {
4762   if (bNotify && IsInitialized()) {
4763     CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4764     if (pNotify) {
4765       pNotify->OnValueChanging(this, eAttr);
4766     }
4767   }
4768 }
4769 
OnChanged(XFA_ATTRIBUTE eAttr,bool bNotify,bool bScriptModify)4770 void CXFA_Node::OnChanged(XFA_ATTRIBUTE eAttr,
4771                           bool bNotify,
4772                           bool bScriptModify) {
4773   if (bNotify && IsInitialized()) {
4774     Script_Attribute_SendAttributeChangeMessage(eAttr, bScriptModify);
4775   }
4776 }
4777 
execSingleEventByName(const CFX_WideStringC & wsEventName,XFA_Element eType)4778 int32_t CXFA_Node::execSingleEventByName(const CFX_WideStringC& wsEventName,
4779                                          XFA_Element eType) {
4780   int32_t iRet = XFA_EVENTERROR_NotExist;
4781   const XFA_ExecEventParaInfo* eventParaInfo =
4782       GetEventParaInfoByName(wsEventName);
4783   if (eventParaInfo) {
4784     uint32_t validFlags = eventParaInfo->m_validFlags;
4785     CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4786     if (!pNotify) {
4787       return iRet;
4788     }
4789     if (validFlags == 1) {
4790       iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType);
4791     } else if (validFlags == 2) {
4792       iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4793                                            false, false);
4794     } else if (validFlags == 3) {
4795       if (eType == XFA_Element::Subform) {
4796         iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4797                                              false, false);
4798       }
4799     } else if (validFlags == 4) {
4800       if (eType == XFA_Element::ExclGroup || eType == XFA_Element::Field) {
4801         CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
4802         if (pParentNode &&
4803             pParentNode->GetElementType() == XFA_Element::ExclGroup) {
4804           iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4805                                                false, false);
4806         }
4807         iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4808                                              false, false);
4809       }
4810     } else if (validFlags == 5) {
4811       if (eType == XFA_Element::Field) {
4812         iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4813                                              false, false);
4814       }
4815     } else if (validFlags == 6) {
4816       CXFA_WidgetData* pWidgetData = GetWidgetData();
4817       if (pWidgetData) {
4818         CXFA_Node* pUINode = pWidgetData->GetUIChild();
4819         if (pUINode->m_elementType == XFA_Element::Signature) {
4820           iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4821                                                false, false);
4822         }
4823       }
4824     } else if (validFlags == 7) {
4825       CXFA_WidgetData* pWidgetData = GetWidgetData();
4826       if (pWidgetData) {
4827         CXFA_Node* pUINode = pWidgetData->GetUIChild();
4828         if ((pUINode->m_elementType == XFA_Element::ChoiceList) &&
4829             (!pWidgetData->IsListBox())) {
4830           iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4831                                                false, false);
4832         }
4833       }
4834     }
4835   }
4836   return iRet;
4837 }
4838 
UpdateNameHash()4839 void CXFA_Node::UpdateNameHash() {
4840   const XFA_NOTSUREATTRIBUTE* pNotsure =
4841       XFA_GetNotsureAttribute(GetElementType(), XFA_ATTRIBUTE_Name);
4842   CFX_WideStringC wsName;
4843   if (!pNotsure || pNotsure->eType == XFA_ATTRIBUTETYPE_Cdata) {
4844     wsName = GetCData(XFA_ATTRIBUTE_Name);
4845     m_dwNameHash = FX_HashCode_GetW(wsName, false);
4846   } else if (pNotsure->eType == XFA_ATTRIBUTETYPE_Enum) {
4847     wsName = GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
4848     m_dwNameHash = FX_HashCode_GetW(wsName, false);
4849   }
4850 }
4851 
CreateXMLMappingNode()4852 CFDE_XMLNode* CXFA_Node::CreateXMLMappingNode() {
4853   if (!m_pXMLNode) {
4854     CFX_WideString wsTag(GetCData(XFA_ATTRIBUTE_Name));
4855     m_pXMLNode = new CFDE_XMLElement(wsTag);
4856     SetFlag(XFA_NodeFlag_OwnXMLNode, false);
4857   }
4858   return m_pXMLNode;
4859 }
4860 
IsNeedSavingXMLNode()4861 bool CXFA_Node::IsNeedSavingXMLNode() {
4862   return m_pXMLNode && (GetPacketID() == XFA_XDPPACKET_Datasets ||
4863                         GetElementType() == XFA_Element::Xfa);
4864 }
4865 
CreateMapModuleData()4866 XFA_MAPMODULEDATA* CXFA_Node::CreateMapModuleData() {
4867   if (!m_pMapModuleData)
4868     m_pMapModuleData = new XFA_MAPMODULEDATA;
4869   return m_pMapModuleData;
4870 }
4871 
GetMapModuleData() const4872 XFA_MAPMODULEDATA* CXFA_Node::GetMapModuleData() const {
4873   return m_pMapModuleData;
4874 }
4875 
SetMapModuleValue(void * pKey,void * pValue)4876 void CXFA_Node::SetMapModuleValue(void* pKey, void* pValue) {
4877   XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
4878   pModule->m_ValueMap[pKey] = pValue;
4879 }
4880 
GetMapModuleValue(void * pKey,void * & pValue)4881 bool CXFA_Node::GetMapModuleValue(void* pKey, void*& pValue) {
4882   for (CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4883     XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4884     if (pModule) {
4885       auto it = pModule->m_ValueMap.find(pKey);
4886       if (it != pModule->m_ValueMap.end()) {
4887         pValue = it->second;
4888         return true;
4889       }
4890     }
4891     if (pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4892       break;
4893   }
4894   return false;
4895 }
4896 
SetMapModuleString(void * pKey,const CFX_WideStringC & wsValue)4897 void CXFA_Node::SetMapModuleString(void* pKey, const CFX_WideStringC& wsValue) {
4898   SetMapModuleBuffer(pKey, (void*)wsValue.c_str(),
4899                      wsValue.GetLength() * sizeof(FX_WCHAR));
4900 }
4901 
GetMapModuleString(void * pKey,CFX_WideStringC & wsValue)4902 bool CXFA_Node::GetMapModuleString(void* pKey, CFX_WideStringC& wsValue) {
4903   void* pValue;
4904   int32_t iBytes;
4905   if (!GetMapModuleBuffer(pKey, pValue, iBytes)) {
4906     return false;
4907   }
4908   wsValue = CFX_WideStringC((const FX_WCHAR*)pValue, iBytes / sizeof(FX_WCHAR));
4909   return true;
4910 }
4911 
SetMapModuleBuffer(void * pKey,void * pValue,int32_t iBytes,XFA_MAPDATABLOCKCALLBACKINFO * pCallbackInfo)4912 void CXFA_Node::SetMapModuleBuffer(
4913     void* pKey,
4914     void* pValue,
4915     int32_t iBytes,
4916     XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
4917   XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
4918   XFA_MAPDATABLOCK*& pBuffer = pModule->m_BufferMap[pKey];
4919   if (!pBuffer) {
4920     pBuffer =
4921         (XFA_MAPDATABLOCK*)FX_Alloc(uint8_t, sizeof(XFA_MAPDATABLOCK) + iBytes);
4922   } else if (pBuffer->iBytes != iBytes) {
4923     if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
4924       pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4925     }
4926     pBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(uint8_t, pBuffer,
4927                                             sizeof(XFA_MAPDATABLOCK) + iBytes);
4928   } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
4929     pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4930   }
4931   if (!pBuffer)
4932     return;
4933 
4934   pBuffer->pCallbackInfo = pCallbackInfo;
4935   pBuffer->iBytes = iBytes;
4936   FXSYS_memcpy(pBuffer->GetData(), pValue, iBytes);
4937 }
4938 
GetMapModuleBuffer(void * pKey,void * & pValue,int32_t & iBytes,bool bProtoAlso) const4939 bool CXFA_Node::GetMapModuleBuffer(void* pKey,
4940                                    void*& pValue,
4941                                    int32_t& iBytes,
4942                                    bool bProtoAlso) const {
4943   XFA_MAPDATABLOCK* pBuffer = nullptr;
4944   for (const CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4945     XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4946     if (pModule) {
4947       auto it = pModule->m_BufferMap.find(pKey);
4948       if (it != pModule->m_BufferMap.end()) {
4949         pBuffer = it->second;
4950         break;
4951       }
4952     }
4953     if (!bProtoAlso || pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4954       break;
4955   }
4956   if (!pBuffer)
4957     return false;
4958 
4959   pValue = pBuffer->GetData();
4960   iBytes = pBuffer->iBytes;
4961   return true;
4962 }
4963 
HasMapModuleKey(void * pKey,bool bProtoAlso)4964 bool CXFA_Node::HasMapModuleKey(void* pKey, bool bProtoAlso) {
4965   for (CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4966     XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4967     if (pModule) {
4968       auto it1 = pModule->m_ValueMap.find(pKey);
4969       if (it1 != pModule->m_ValueMap.end())
4970         return true;
4971 
4972       auto it2 = pModule->m_BufferMap.find(pKey);
4973       if (it2 != pModule->m_BufferMap.end())
4974         return true;
4975     }
4976     if (!bProtoAlso || pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4977       break;
4978   }
4979   return false;
4980 }
4981 
RemoveMapModuleKey(void * pKey)4982 void CXFA_Node::RemoveMapModuleKey(void* pKey) {
4983   XFA_MAPMODULEDATA* pModule = GetMapModuleData();
4984   if (!pModule)
4985     return;
4986 
4987   if (pKey) {
4988     auto it = pModule->m_BufferMap.find(pKey);
4989     if (it != pModule->m_BufferMap.end()) {
4990       XFA_MAPDATABLOCK* pBuffer = it->second;
4991       if (pBuffer) {
4992         if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
4993           pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4994         FX_Free(pBuffer);
4995       }
4996       pModule->m_BufferMap.erase(it);
4997     }
4998     pModule->m_ValueMap.erase(pKey);
4999     return;
5000   }
5001 
5002   for (auto& pair : pModule->m_BufferMap) {
5003     XFA_MAPDATABLOCK* pBuffer = pair.second;
5004     if (pBuffer) {
5005       if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
5006         pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
5007       FX_Free(pBuffer);
5008     }
5009   }
5010   pModule->m_BufferMap.clear();
5011   pModule->m_ValueMap.clear();
5012   delete pModule;
5013 }
5014 
MergeAllData(void * pDstModule)5015 void CXFA_Node::MergeAllData(void* pDstModule) {
5016   XFA_MAPMODULEDATA* pDstModuleData =
5017       static_cast<CXFA_Node*>(pDstModule)->CreateMapModuleData();
5018   XFA_MAPMODULEDATA* pSrcModuleData = GetMapModuleData();
5019   if (!pSrcModuleData)
5020     return;
5021 
5022   for (const auto& pair : pSrcModuleData->m_ValueMap)
5023     pDstModuleData->m_ValueMap[pair.first] = pair.second;
5024 
5025   for (const auto& pair : pSrcModuleData->m_BufferMap) {
5026     XFA_MAPDATABLOCK* pSrcBuffer = pair.second;
5027     XFA_MAPDATABLOCK*& pDstBuffer = pDstModuleData->m_BufferMap[pair.first];
5028     if (pSrcBuffer->pCallbackInfo && pSrcBuffer->pCallbackInfo->pFree &&
5029         !pSrcBuffer->pCallbackInfo->pCopy) {
5030       if (pDstBuffer) {
5031         pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5032         pDstModuleData->m_BufferMap.erase(pair.first);
5033       }
5034       continue;
5035     }
5036     if (!pDstBuffer) {
5037       pDstBuffer = (XFA_MAPDATABLOCK*)FX_Alloc(
5038           uint8_t, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
5039     } else if (pDstBuffer->iBytes != pSrcBuffer->iBytes) {
5040       if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
5041         pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5042       }
5043       pDstBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(
5044           uint8_t, pDstBuffer, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
5045     } else if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
5046       pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5047     }
5048     if (!pDstBuffer) {
5049       continue;
5050     }
5051     pDstBuffer->pCallbackInfo = pSrcBuffer->pCallbackInfo;
5052     pDstBuffer->iBytes = pSrcBuffer->iBytes;
5053     FXSYS_memcpy(pDstBuffer->GetData(), pSrcBuffer->GetData(),
5054                  pSrcBuffer->iBytes);
5055     if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pCopy) {
5056       pDstBuffer->pCallbackInfo->pCopy(*(void**)pDstBuffer->GetData());
5057     }
5058   }
5059 }
5060 
MoveBufferMapData(CXFA_Node * pDstModule,void * pKey)5061 void CXFA_Node::MoveBufferMapData(CXFA_Node* pDstModule, void* pKey) {
5062   if (!pDstModule) {
5063     return;
5064   }
5065   bool bNeedMove = true;
5066   if (!pKey) {
5067     bNeedMove = false;
5068   }
5069   if (pDstModule->GetElementType() != GetElementType()) {
5070     bNeedMove = false;
5071   }
5072   XFA_MAPMODULEDATA* pSrcModuleData = nullptr;
5073   XFA_MAPMODULEDATA* pDstModuleData = nullptr;
5074   if (bNeedMove) {
5075     pSrcModuleData = GetMapModuleData();
5076     if (!pSrcModuleData) {
5077       bNeedMove = false;
5078     }
5079     pDstModuleData = pDstModule->CreateMapModuleData();
5080   }
5081   if (bNeedMove) {
5082     auto it = pSrcModuleData->m_BufferMap.find(pKey);
5083     if (it != pSrcModuleData->m_BufferMap.end()) {
5084       XFA_MAPDATABLOCK* pBufferBlockData = it->second;
5085       if (pBufferBlockData) {
5086         pSrcModuleData->m_BufferMap.erase(pKey);
5087         pDstModuleData->m_BufferMap[pKey] = pBufferBlockData;
5088       }
5089     }
5090   }
5091   if (pDstModule->IsNodeV()) {
5092     CFX_WideString wsValue = pDstModule->GetScriptContent(false);
5093     CFX_WideString wsFormatValue(wsValue);
5094     CXFA_WidgetData* pWidgetData = pDstModule->GetContainerWidgetData();
5095     if (pWidgetData) {
5096       pWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
5097     }
5098     pDstModule->SetScriptContent(wsValue, wsFormatValue, true, true);
5099   }
5100 }
5101 
MoveBufferMapData(CXFA_Node * pSrcModule,CXFA_Node * pDstModule,void * pKey,bool bRecursive)5102 void CXFA_Node::MoveBufferMapData(CXFA_Node* pSrcModule,
5103                                   CXFA_Node* pDstModule,
5104                                   void* pKey,
5105                                   bool bRecursive) {
5106   if (!pSrcModule || !pDstModule || !pKey) {
5107     return;
5108   }
5109   if (bRecursive) {
5110     CXFA_Node* pSrcChild = pSrcModule->GetNodeItem(XFA_NODEITEM_FirstChild);
5111     CXFA_Node* pDstChild = pDstModule->GetNodeItem(XFA_NODEITEM_FirstChild);
5112     for (; pSrcChild && pDstChild;
5113          pSrcChild = pSrcChild->GetNodeItem(XFA_NODEITEM_NextSibling),
5114          pDstChild = pDstChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
5115       MoveBufferMapData(pSrcChild, pDstChild, pKey, true);
5116     }
5117   }
5118   pSrcModule->MoveBufferMapData(pDstModule, pKey);
5119 }
5120 
ThrowMissingPropertyException(const CFX_WideString & obj,const CFX_WideString & prop) const5121 void CXFA_Node::ThrowMissingPropertyException(
5122     const CFX_WideString& obj,
5123     const CFX_WideString& prop) const {
5124   ThrowException(L"'%s' doesn't have property '%s'.", obj.c_str(),
5125                  prop.c_str());
5126 }
5127 
ThrowTooManyOccurancesException(const CFX_WideString & obj) const5128 void CXFA_Node::ThrowTooManyOccurancesException(
5129     const CFX_WideString& obj) const {
5130   ThrowException(
5131       L"The element [%s] has violated its allowable number of occurrences.",
5132       obj.c_str());
5133 }
5134