• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
8 
9 #include <map>
10 #include <vector>
11 
12 #include "core/fxcrt/fx_ext.h"
13 #include "third_party/base/stl_util.h"
14 #include "xfa/fde/xml/fde_xml_imp.h"
15 #include "xfa/fxfa/parser/cxfa_document.h"
16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
17 #include "xfa/fxfa/parser/cxfa_occur.h"
18 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
19 #include "xfa/fxfa/parser/xfa_localemgr.h"
20 #include "xfa/fxfa/parser/xfa_object.h"
21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
22 #include "xfa/fxfa/parser/xfa_utils.h"
23 
24 namespace {
25 
26 class CXFA_TraverseStrategy_DDGroup {
27  public:
GetFirstChild(CXFA_Node * pDDGroupNode)28   static CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) {
29     return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group);
30   }
GetNextSibling(CXFA_Node * pDDGroupNode)31   static CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) {
32     return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group);
33   }
GetParent(CXFA_Node * pDDGroupNode)34   static CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) {
35     return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent);
36   }
37 };
38 
39 struct RecurseRecord {
40   CXFA_Node* pTemplateChild;
41   CXFA_Node* pDataChild;
42 };
43 
GetOccurInfo(CXFA_Node * pOccurNode,int32_t & iMin,int32_t & iMax,int32_t & iInit)44 bool GetOccurInfo(CXFA_Node* pOccurNode,
45                   int32_t& iMin,
46                   int32_t& iMax,
47                   int32_t& iInit) {
48   if (!pOccurNode)
49     return false;
50 
51   CXFA_Occur occur(pOccurNode);
52   return occur.GetOccurInfo(iMin, iMax, iInit);
53 }
54 
FormValueNode_CreateChild(CXFA_Node * pValueNode,XFA_Element iType)55 CXFA_Node* FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_Element iType) {
56   CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
57   if (!pChildNode) {
58     if (iType == XFA_Element::Unknown)
59       return nullptr;
60     pChildNode = pValueNode->GetProperty(0, iType);
61   }
62   return pChildNode;
63 }
64 
FormValueNode_MatchNoneCreateChild(CXFA_Node * pFormNode)65 void FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode) {
66   CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
67   ASSERT(pWidgetData);
68   pWidgetData->GetUIType();
69 }
70 
FormValueNode_SetChildContent(CXFA_Node * pValueNode,const CFX_WideString & wsContent,XFA_Element iType=XFA_Element::Unknown)71 bool FormValueNode_SetChildContent(CXFA_Node* pValueNode,
72                                    const CFX_WideString& wsContent,
73                                    XFA_Element iType = XFA_Element::Unknown) {
74   if (!pValueNode)
75     return false;
76 
77   ASSERT(pValueNode->GetPacketID() == XFA_XDPPACKET_Form);
78   CXFA_Node* pChildNode = FormValueNode_CreateChild(pValueNode, iType);
79   if (!pChildNode)
80     return false;
81 
82   switch (pChildNode->GetObjectType()) {
83     case XFA_ObjectType::ContentNode: {
84       CXFA_Node* pContentRawDataNode =
85           pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild);
86       if (!pContentRawDataNode) {
87         XFA_Element element = XFA_Element::Sharptext;
88         if (pChildNode->GetElementType() == XFA_Element::ExData) {
89           CFX_WideString wsContentType;
90           pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
91                                    false);
92           if (wsContentType == L"text/html")
93             element = XFA_Element::SharpxHTML;
94           else if (wsContentType == L"text/xml")
95             element = XFA_Element::Sharpxml;
96         }
97         pContentRawDataNode = pChildNode->CreateSamePacketNode(element);
98         pChildNode->InsertChild(pContentRawDataNode);
99       }
100       pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
101       break;
102     }
103     case XFA_ObjectType::NodeC:
104     case XFA_ObjectType::TextNode:
105     case XFA_ObjectType::NodeV: {
106       pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
107       break;
108     }
109     default:
110       ASSERT(false);
111       break;
112   }
113   return true;
114 }
115 
CreateDataBinding(CXFA_Node * pFormNode,CXFA_Node * pDataNode,bool bDataToForm)116 void CreateDataBinding(CXFA_Node* pFormNode,
117                        CXFA_Node* pDataNode,
118                        bool bDataToForm) {
119   pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode);
120   pDataNode->AddBindItem(pFormNode);
121   XFA_Element eType = pFormNode->GetElementType();
122   if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup)
123     return;
124 
125   CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
126   ASSERT(pWidgetData);
127   XFA_Element eUIType = pWidgetData->GetUIType();
128   CXFA_Value defValue(pFormNode->GetProperty(0, XFA_Element::Value));
129   if (!bDataToForm) {
130     CFX_WideString wsValue;
131     CFX_WideString wsFormattedValue;
132     switch (eUIType) {
133       case XFA_Element::ImageEdit: {
134         CXFA_Image image = defValue.GetImage();
135         CFX_WideString wsContentType;
136         CFX_WideString wsHref;
137         if (image) {
138           image.GetContent(wsValue);
139           image.GetContentType(wsContentType);
140           image.GetHref(wsHref);
141         }
142         CFDE_XMLElement* pXMLDataElement =
143             static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode());
144         ASSERT(pXMLDataElement);
145         pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
146         pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
147         pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
148         if (!wsHref.IsEmpty())
149           pXMLDataElement->SetString(L"href", wsHref);
150 
151         break;
152       }
153       case XFA_Element::ChoiceList:
154         defValue.GetChildValueContent(wsValue);
155         if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
156           std::vector<CFX_WideString> wsSelTextArray;
157           pWidgetData->GetSelectedItemsValue(wsSelTextArray);
158           int32_t iSize = pdfium::CollectionSize<int32_t>(wsSelTextArray);
159           if (iSize >= 1) {
160             CXFA_Node* pValue = nullptr;
161             for (int32_t i = 0; i < iSize; i++) {
162               pValue = pDataNode->CreateSamePacketNode(XFA_Element::DataValue);
163               pValue->SetCData(XFA_ATTRIBUTE_Name, L"value");
164               pValue->CreateXMLMappingNode();
165               pDataNode->InsertChild(pValue);
166               pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]);
167             }
168           } else {
169             CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
170             ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element);
171             static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(L"xfa:dataNode",
172                                                                L"dataGroup");
173           }
174         } else if (!wsValue.IsEmpty()) {
175           pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
176           pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
177         }
178         break;
179       case XFA_Element::CheckButton:
180         defValue.GetChildValueContent(wsValue);
181         if (wsValue.IsEmpty())
182           break;
183 
184         pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
185         pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
186         break;
187       case XFA_Element::ExclGroup: {
188         CXFA_Node* pChecked = nullptr;
189         CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
190         for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
191           if (pChild->GetElementType() != XFA_Element::Field)
192             continue;
193 
194           CXFA_Node* pValue = pChild->GetChild(0, XFA_Element::Value);
195           if (!pValue)
196             continue;
197 
198           CXFA_Value valueChild(pValue);
199           valueChild.GetChildValueContent(wsValue);
200           if (wsValue.IsEmpty())
201             continue;
202 
203           CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items);
204           if (!pItems)
205             continue;
206 
207           CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
208           if (!pText)
209             continue;
210 
211           CFX_WideString wsContent;
212           if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
213             pChecked = pChild;
214             wsFormattedValue = wsValue;
215             pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
216             pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
217             break;
218           }
219         }
220         if (!pChecked)
221           break;
222 
223         pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
224         for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
225           if (pChild == pChecked)
226             continue;
227           if (pChild->GetElementType() != XFA_Element::Field)
228             continue;
229 
230           CXFA_Node* pValue = pChild->GetProperty(0, XFA_Element::Value);
231           CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items);
232           CXFA_Node* pText =
233               pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : nullptr;
234           if (pText)
235             pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
236 
237           CFX_WideString wsContent;
238           if (pText)
239             pText->TryContent(wsContent);
240 
241           FormValueNode_SetChildContent(pValue, wsContent, XFA_Element::Text);
242         }
243         break;
244       }
245       case XFA_Element::NumericEdit: {
246         defValue.GetChildValueContent(wsValue);
247         if (wsValue.IsEmpty())
248           break;
249 
250         CFX_WideString wsOutput;
251         pWidgetData->NormalizeNumStr(wsValue, wsOutput);
252         wsValue = wsOutput;
253         pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
254         pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
255         CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_Element::Value);
256         FormValueNode_SetChildContent(pValue, wsValue, XFA_Element::Float);
257         break;
258       }
259       default:
260         defValue.GetChildValueContent(wsValue);
261         if (wsValue.IsEmpty())
262           break;
263 
264         pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
265         pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
266         break;
267     }
268     return;
269   }
270 
271   CFX_WideString wsXMLValue;
272   pDataNode->TryContent(wsXMLValue);
273   CFX_WideString wsNormalizeValue;
274   pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormalizeValue);
275   pDataNode->SetAttributeValue(wsNormalizeValue, wsXMLValue);
276   switch (eUIType) {
277     case XFA_Element::ImageEdit: {
278       FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
279                                     XFA_Element::Image);
280       CXFA_Image image = defValue.GetImage();
281       if (image) {
282         CFDE_XMLElement* pXMLDataElement =
283             static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode());
284         ASSERT(pXMLDataElement);
285         CFX_WideString wsContentType;
286         CFX_WideString wsHref;
287         pXMLDataElement->GetString(L"xfa:contentType", wsContentType);
288         if (!wsContentType.IsEmpty()) {
289           pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
290           image.SetContentType(wsContentType);
291         }
292         pXMLDataElement->GetString(L"href", wsHref);
293         if (!wsHref.IsEmpty())
294           image.SetHref(wsHref);
295       }
296       break;
297     }
298     case XFA_Element::ChoiceList:
299       if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
300         CXFA_NodeArray items;
301         pDataNode->GetNodeList(items);
302         int32_t iCounts = items.GetSize();
303         if (iCounts > 0) {
304           wsNormalizeValue.clear();
305           CFX_WideString wsItem;
306           for (int32_t i = 0; i < iCounts; i++) {
307             items[i]->TryContent(wsItem);
308             wsItem = (iCounts == 1) ? wsItem : wsItem + L"\n";
309             wsNormalizeValue += wsItem;
310           }
311           CXFA_ExData exData = defValue.GetExData();
312           ASSERT(exData);
313           exData.SetContentType(iCounts == 1 ? L"text/plain" : L"text/xml");
314         }
315         FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
316                                       XFA_Element::ExData);
317       } else {
318         FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
319                                       XFA_Element::Text);
320       }
321       break;
322     case XFA_Element::CheckButton:
323       FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
324                                     XFA_Element::Text);
325       break;
326     case XFA_Element::ExclGroup: {
327       pWidgetData->SetSelectedMemberByValue(wsNormalizeValue.AsStringC(), false,
328                                             false, false);
329       break;
330     }
331     case XFA_Element::DateTimeEdit:
332       FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
333                                     XFA_Element::DateTime);
334       break;
335     case XFA_Element::NumericEdit: {
336       CFX_WideString wsPicture;
337       pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
338       if (wsPicture.IsEmpty()) {
339         CFX_WideString wsOutput;
340         pWidgetData->NormalizeNumStr(wsNormalizeValue, wsOutput);
341         wsNormalizeValue = wsOutput;
342       }
343       FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
344                                     XFA_Element::Float);
345       break;
346     }
347     case XFA_Element::Barcode:
348     case XFA_Element::Button:
349     case XFA_Element::PasswordEdit:
350     case XFA_Element::Signature:
351     case XFA_Element::TextEdit:
352     default:
353       FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
354                                     XFA_Element::Text);
355       break;
356   }
357 }
358 
GetGlobalBinding(CXFA_Document * pDocument,uint32_t dwNameHash)359 CXFA_Node* GetGlobalBinding(CXFA_Document* pDocument, uint32_t dwNameHash) {
360   auto it = pDocument->m_rgGlobalBinding.find(dwNameHash);
361   return it != pDocument->m_rgGlobalBinding.end() ? it->second : nullptr;
362 }
363 
RegisterGlobalBinding(CXFA_Document * pDocument,uint32_t dwNameHash,CXFA_Node * pDataNode)364 void RegisterGlobalBinding(CXFA_Document* pDocument,
365                            uint32_t dwNameHash,
366                            CXFA_Node* pDataNode) {
367   pDocument->m_rgGlobalBinding[dwNameHash] = pDataNode;
368 }
369 
ScopeMatchGlobalBinding(CXFA_Node * pDataScope,uint32_t dwNameHash,XFA_Element eMatchDataNodeType,bool bUpLevel)370 CXFA_Node* ScopeMatchGlobalBinding(CXFA_Node* pDataScope,
371                                    uint32_t dwNameHash,
372                                    XFA_Element eMatchDataNodeType,
373                                    bool bUpLevel) {
374   for (CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = nullptr;
375        pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
376        pLastDataScope = pCurDataScope,
377                  pCurDataScope =
378                      pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
379     for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash);
380          pDataChild;
381          pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
382       if (pDataChild == pLastDataScope ||
383           (eMatchDataNodeType != XFA_Element::DataModel &&
384            pDataChild->GetElementType() != eMatchDataNodeType) ||
385           pDataChild->HasBindItem()) {
386         continue;
387       }
388       return pDataChild;
389     }
390 
391     for (CXFA_Node* pDataChild =
392              pCurDataScope->GetFirstChildByClass(XFA_Element::DataGroup);
393          pDataChild; pDataChild = pDataChild->GetNextSameClassSibling(
394                          XFA_Element::DataGroup)) {
395       CXFA_Node* pDataNode = ScopeMatchGlobalBinding(pDataChild, dwNameHash,
396                                                      eMatchDataNodeType, false);
397       if (pDataNode)
398         return pDataNode;
399     }
400     if (!bUpLevel)
401       break;
402   }
403   return nullptr;
404 }
405 
FindGlobalDataNode(CXFA_Document * pDocument,CFX_WideStringC wsName,CXFA_Node * pDataScope,XFA_Element eMatchNodeType)406 CXFA_Node* FindGlobalDataNode(CXFA_Document* pDocument,
407                               CFX_WideStringC wsName,
408                               CXFA_Node* pDataScope,
409                               XFA_Element eMatchNodeType) {
410   if (wsName.IsEmpty())
411     return nullptr;
412 
413   uint32_t dwNameHash = FX_HashCode_GetW(wsName, false);
414   CXFA_Node* pBounded = GetGlobalBinding(pDocument, dwNameHash);
415   if (!pBounded) {
416     pBounded =
417         ScopeMatchGlobalBinding(pDataScope, dwNameHash, eMatchNodeType, true);
418     if (pBounded)
419       RegisterGlobalBinding(pDocument, dwNameHash, pBounded);
420   }
421   return pBounded;
422 }
423 
FindOnceDataNode(CXFA_Document * pDocument,CFX_WideStringC wsName,CXFA_Node * pDataScope,XFA_Element eMatchNodeType)424 CXFA_Node* FindOnceDataNode(CXFA_Document* pDocument,
425                             CFX_WideStringC wsName,
426                             CXFA_Node* pDataScope,
427                             XFA_Element eMatchNodeType) {
428   if (wsName.IsEmpty())
429     return nullptr;
430 
431   uint32_t dwNameHash = FX_HashCode_GetW(wsName, false);
432   CXFA_Node* pLastDataScope = nullptr;
433   for (CXFA_Node* pCurDataScope = pDataScope;
434        pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
435        pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
436     for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash);
437          pDataChild;
438          pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
439       if (pDataChild == pLastDataScope || pDataChild->HasBindItem() ||
440           (eMatchNodeType != XFA_Element::DataModel &&
441            pDataChild->GetElementType() != eMatchNodeType)) {
442         continue;
443       }
444       return pDataChild;
445     }
446     pLastDataScope = pCurDataScope;
447   }
448   return nullptr;
449 }
450 
FindDataRefDataNode(CXFA_Document * pDocument,CFX_WideStringC wsRef,CXFA_Node * pDataScope,XFA_Element eMatchNodeType,CXFA_Node * pTemplateNode,bool bForceBind,bool bUpLevel)451 CXFA_Node* FindDataRefDataNode(CXFA_Document* pDocument,
452                                CFX_WideStringC wsRef,
453                                CXFA_Node* pDataScope,
454                                XFA_Element eMatchNodeType,
455                                CXFA_Node* pTemplateNode,
456                                bool bForceBind,
457                                bool bUpLevel) {
458   uint32_t dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;
459   if (bUpLevel || wsRef != L"name")
460     dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
461 
462   XFA_RESOLVENODE_RS rs;
463   pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags,
464                                                 pTemplateNode);
465   if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll ||
466       rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll ||
467       rs.nodes.GetSize() > 1) {
468     return pDocument->GetNotBindNode(rs.nodes);
469   }
470 
471   if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
472     CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr;
473     CXFA_Node* pNode = ToNode(pObject);
474     return (bForceBind || !pNode || !pNode->HasBindItem()) ? pNode : nullptr;
475   }
476   return nullptr;
477 }
478 
NeedGenerateForm(CXFA_Node * pTemplateChild,bool bUseInstanceManager)479 bool NeedGenerateForm(CXFA_Node* pTemplateChild, bool bUseInstanceManager) {
480   XFA_Element eType = pTemplateChild->GetElementType();
481   if (eType == XFA_Element::Variables)
482     return true;
483   if (pTemplateChild->IsContainerNode())
484     return false;
485   if (eType == XFA_Element::Proto ||
486       (bUseInstanceManager && eType == XFA_Element::Occur)) {
487     return false;
488   }
489   return true;
490 }
491 
CloneOrMergeInstanceManager(CXFA_Document * pDocument,CXFA_Node * pFormParent,CXFA_Node * pTemplateNode,CXFA_NodeArray & subforms)492 CXFA_Node* CloneOrMergeInstanceManager(CXFA_Document* pDocument,
493                                        CXFA_Node* pFormParent,
494                                        CXFA_Node* pTemplateNode,
495                                        CXFA_NodeArray& subforms) {
496   CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
497   CFX_WideString wsInstMgrNodeName = L"_" + wsSubformName;
498   uint32_t dwInstNameHash =
499       FX_HashCode_GetW(wsInstMgrNodeName.AsStringC(), false);
500   CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
501       pDocument, XFA_Element::InstanceManager, dwInstNameHash, pFormParent);
502   if (pExistingNode) {
503     uint32_t dwNameHash = pTemplateNode->GetNameHash();
504     for (CXFA_Node* pNode =
505              pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling);
506          pNode;) {
507       XFA_Element eCurType = pNode->GetElementType();
508       if (eCurType == XFA_Element::InstanceManager)
509         break;
510 
511       if ((eCurType != XFA_Element::Subform) &&
512           (eCurType != XFA_Element::SubformSet)) {
513         pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
514         continue;
515       }
516       if (dwNameHash != pNode->GetNameHash())
517         break;
518 
519       CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
520       pFormParent->RemoveChild(pNode);
521       subforms.Add(pNode);
522       pNode = pNextNode;
523     }
524     pFormParent->RemoveChild(pExistingNode);
525     pFormParent->InsertChild(pExistingNode);
526     pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode);
527     pExistingNode->SetTemplateNode(pTemplateNode);
528     return pExistingNode;
529   }
530 
531   CXFA_Node* pNewNode =
532       pDocument->CreateNode(XFA_XDPPACKET_Form, XFA_Element::InstanceManager);
533   wsInstMgrNodeName = L"_" + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
534   pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName);
535   pFormParent->InsertChild(pNewNode, nullptr);
536   pNewNode->SetTemplateNode(pTemplateNode);
537   return pNewNode;
538 }
539 
FindMatchingDataNode(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pDataScope,bool & bAccessedDataDOM,bool bForceBind,CXFA_NodeIteratorTemplate<CXFA_Node,CXFA_TraverseStrategy_XFAContainerNode> * pIterator,bool & bSelfMatch,XFA_ATTRIBUTEENUM & eBindMatch,bool bUpLevel)540 CXFA_Node* FindMatchingDataNode(
541     CXFA_Document* pDocument,
542     CXFA_Node* pTemplateNode,
543     CXFA_Node* pDataScope,
544     bool& bAccessedDataDOM,
545     bool bForceBind,
546     CXFA_NodeIteratorTemplate<CXFA_Node,
547                               CXFA_TraverseStrategy_XFAContainerNode>*
548         pIterator,
549     bool& bSelfMatch,
550     XFA_ATTRIBUTEENUM& eBindMatch,
551     bool bUpLevel) {
552   bool bOwnIterator = false;
553   if (!pIterator) {
554     bOwnIterator = true;
555     pIterator = new CXFA_NodeIteratorTemplate<
556         CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode);
557   }
558 
559   CXFA_Node* pResult = nullptr;
560   for (CXFA_Node* pCurTemplateNode = pIterator->GetCurrent();
561        pCurTemplateNode;) {
562     XFA_Element eMatchNodeType;
563     switch (pCurTemplateNode->GetElementType()) {
564       case XFA_Element::Subform:
565         eMatchNodeType = XFA_Element::DataGroup;
566         break;
567       case XFA_Element::Field: {
568         eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode)
569                              ? XFA_Element::DataGroup
570                              : XFA_Element::DataValue;
571       } break;
572       case XFA_Element::ExclGroup:
573         eMatchNodeType = XFA_Element::DataValue;
574         break;
575       default:
576         pCurTemplateNode = pIterator->MoveToNext();
577         continue;
578     }
579     CXFA_Node* pTemplateNodeOccur =
580         pCurTemplateNode->GetFirstChildByClass(XFA_Element::Occur);
581     int32_t iMin, iMax, iInit;
582     if (pTemplateNodeOccur &&
583         GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) {
584       pCurTemplateNode = pIterator->MoveToNext();
585       continue;
586     }
587 
588     CXFA_Node* pTemplateNodeBind =
589         pCurTemplateNode->GetFirstChildByClass(XFA_Element::Bind);
590     XFA_ATTRIBUTEENUM eMatch =
591         pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
592                           : XFA_ATTRIBUTEENUM_Once;
593     eBindMatch = eMatch;
594     switch (eMatch) {
595       case XFA_ATTRIBUTEENUM_None:
596         pCurTemplateNode = pIterator->MoveToNext();
597         continue;
598       case XFA_ATTRIBUTEENUM_Global:
599         bAccessedDataDOM = true;
600         if (!bForceBind) {
601           pCurTemplateNode = pIterator->MoveToNext();
602           continue;
603         }
604         if (eMatchNodeType == XFA_Element::DataValue ||
605             (eMatchNodeType == XFA_Element::DataGroup &&
606              XFA_FieldIsMultiListBox(pTemplateNodeBind))) {
607           CXFA_Node* pGlobalBindNode = FindGlobalDataNode(
608               pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
609               pDataScope, eMatchNodeType);
610           if (!pGlobalBindNode) {
611             pCurTemplateNode = pIterator->MoveToNext();
612             continue;
613           }
614           pResult = pGlobalBindNode;
615           break;
616         }
617       case XFA_ATTRIBUTEENUM_Once: {
618         bAccessedDataDOM = true;
619         CXFA_Node* pOnceBindNode = FindOnceDataNode(
620             pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
621             pDataScope, eMatchNodeType);
622         if (!pOnceBindNode) {
623           pCurTemplateNode = pIterator->MoveToNext();
624           continue;
625         }
626         pResult = pOnceBindNode;
627         break;
628       }
629       case XFA_ATTRIBUTEENUM_DataRef: {
630         bAccessedDataDOM = true;
631         CXFA_Node* pDataRefBindNode = FindDataRefDataNode(
632             pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref),
633             pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel);
634         if (pDataRefBindNode &&
635             pDataRefBindNode->GetElementType() == eMatchNodeType) {
636           pResult = pDataRefBindNode;
637         }
638         if (!pResult) {
639           pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext();
640           continue;
641         }
642         break;
643       }
644       default:
645         break;
646     }
647     if (pCurTemplateNode == pTemplateNode && pResult)
648       bSelfMatch = true;
649     break;
650   }
651   if (bOwnIterator)
652     delete pIterator;
653   return pResult;
654 }
655 
SortRecurseRecord(CFX_ArrayTemplate<RecurseRecord> & rgRecords,CXFA_Node * pDataScope,bool bChoiceMode)656 void SortRecurseRecord(CFX_ArrayTemplate<RecurseRecord>& rgRecords,
657                        CXFA_Node* pDataScope,
658                        bool bChoiceMode) {
659   int32_t iCount = rgRecords.GetSize();
660   CFX_ArrayTemplate<RecurseRecord> rgResultRecord;
661   for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild);
662        pChildNode;
663        pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
664     for (int32_t i = 0; i < iCount; i++) {
665       CXFA_Node* pNode = rgRecords[i].pDataChild;
666       if (pChildNode == pNode) {
667         RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, pNode};
668         rgResultRecord.Add(sNewRecord);
669         rgRecords.RemoveAt(i);
670         iCount--;
671         break;
672       }
673     }
674     if (bChoiceMode && rgResultRecord.GetSize() > 0)
675       break;
676   }
677 
678   if (rgResultRecord.GetSize() > 0) {
679     if (!bChoiceMode) {
680       for (int32_t i = 0; i < iCount; i++) {
681         RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild,
682                                     rgRecords[i].pDataChild};
683         rgResultRecord.Add(sNewRecord);
684       }
685     }
686     rgRecords.RemoveAll();
687     rgRecords.Copy(rgResultRecord);
688   }
689 }
690 
CopyContainer_SubformSet(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pFormParentNode,CXFA_Node * pDataScope,bool bOneInstance,bool bDataMerge)691 CXFA_Node* CopyContainer_SubformSet(CXFA_Document* pDocument,
692                                     CXFA_Node* pTemplateNode,
693                                     CXFA_Node* pFormParentNode,
694                                     CXFA_Node* pDataScope,
695                                     bool bOneInstance,
696                                     bool bDataMerge) {
697   XFA_Element eType = pTemplateNode->GetElementType();
698   CXFA_Node* pOccurNode = nullptr;
699   CXFA_Node* pFirstInstance = nullptr;
700   bool bUseInstanceManager =
701       pFormParentNode->GetElementType() != XFA_Element::Area;
702   CXFA_Node* pInstMgrNode = nullptr;
703   CXFA_NodeArray subformArray;
704   CXFA_NodeArray* pSearchArray = nullptr;
705   if (!bOneInstance &&
706       (eType == XFA_Element::SubformSet || eType == XFA_Element::Subform)) {
707     pInstMgrNode = bUseInstanceManager ? CloneOrMergeInstanceManager(
708                                              pDocument, pFormParentNode,
709                                              pTemplateNode, subformArray)
710                                        : nullptr;
711     if (CXFA_Node* pOccurTemplateNode =
712             pTemplateNode->GetFirstChildByClass(XFA_Element::Occur)) {
713       pOccurNode = pInstMgrNode ? XFA_NodeMerge_CloneOrMergeContainer(
714                                       pDocument, pInstMgrNode,
715                                       pOccurTemplateNode, false, nullptr)
716                                 : pOccurTemplateNode;
717     } else if (pInstMgrNode) {
718       pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_Element::Occur);
719       if (pOccurNode)
720         pOccurNode->ClearFlag(XFA_NodeFlag_UnusedNode);
721     }
722     if (pInstMgrNode) {
723       pInstMgrNode->SetFlag(XFA_NodeFlag_Initialized, true);
724       pSearchArray = &subformArray;
725       if (pFormParentNode->GetElementType() == XFA_Element::PageArea) {
726         bOneInstance = true;
727         if (subformArray.GetSize() < 1)
728           pSearchArray = nullptr;
729       } else if ((pTemplateNode->GetNameHash() == 0) &&
730                  (subformArray.GetSize() < 1)) {
731         pSearchArray = nullptr;
732       }
733     }
734   }
735 
736   int32_t iMax = 1;
737   int32_t iInit = 1;
738   int32_t iMin = 1;
739   if (!bOneInstance)
740     GetOccurInfo(pOccurNode, iMin, iMax, iInit);
741 
742   XFA_ATTRIBUTEENUM eRelation =
743       eType == XFA_Element::SubformSet
744           ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation)
745           : XFA_ATTRIBUTEENUM_Ordered;
746   int32_t iCurRepeatIndex = 0;
747   XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None;
748   if (bDataMerge) {
749     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
750         sNodeIterator(pTemplateNode);
751     bool bAccessedDataDOM = false;
752     if (eType == XFA_Element::SubformSet || eType == XFA_Element::Area) {
753       sNodeIterator.MoveToNext();
754     } else {
755       std::map<CXFA_Node*, CXFA_Node*> subformMapArray;
756       CXFA_NodeArray nodeArray;
757       for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
758         bool bSelfMatch = false;
759         XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
760         CXFA_Node* pDataNode = FindMatchingDataNode(
761             pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, false,
762             &sNodeIterator, bSelfMatch, eBindMatch, true);
763         if (!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode)
764           break;
765 
766         eParentBindMatch = eBindMatch;
767         CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
768             pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
769         if (!pFirstInstance)
770           pFirstInstance = pSubformNode;
771 
772         CreateDataBinding(pSubformNode, pDataNode, true);
773         ASSERT(pSubformNode);
774         subformMapArray[pSubformNode] = pDataNode;
775         nodeArray.Add(pSubformNode);
776       }
777 
778       for (int32_t iIndex = 0; iIndex < nodeArray.GetSize(); iIndex++) {
779         CXFA_Node* pSubform = nodeArray[iIndex];
780         CXFA_Node* pDataNode = nullptr;
781         auto it = subformMapArray.find(pSubform);
782         if (it != subformMapArray.end())
783           pDataNode = it->second;
784         for (CXFA_Node* pTemplateChild =
785                  pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
786              pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
787                                  XFA_NODEITEM_NextSibling)) {
788           if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
789             XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform,
790                                                 pTemplateChild, true, nullptr);
791           } else if (pTemplateChild->IsContainerNode()) {
792             pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform,
793                                                pDataNode, false, true, false);
794           }
795         }
796       }
797       subformMapArray.clear();
798     }
799 
800     for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
801       bool bSelfMatch = false;
802       XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
803       if (!FindMatchingDataNode(pDocument, pTemplateNode, pDataScope,
804                                 bAccessedDataDOM, false, &sNodeIterator,
805                                 bSelfMatch, eBindMatch, true)) {
806         break;
807       }
808       if (eBindMatch == XFA_ATTRIBUTEENUM_DataRef &&
809           eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) {
810         break;
811       }
812 
813       if (eRelation == XFA_ATTRIBUTEENUM_Choice ||
814           eRelation == XFA_ATTRIBUTEENUM_Unordered) {
815         CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
816             pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
817         ASSERT(pSubformSetNode);
818         if (!pFirstInstance)
819           pFirstInstance = pSubformSetNode;
820 
821         CFX_ArrayTemplate<RecurseRecord> rgItemMatchList;
822         CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList;
823         for (CXFA_Node* pTemplateChild =
824                  pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
825              pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
826                                  XFA_NODEITEM_NextSibling)) {
827           if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
828             XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
829                                                 pTemplateChild, true, nullptr);
830           } else if (pTemplateChild->IsContainerNode()) {
831             bSelfMatch = false;
832             eBindMatch = XFA_ATTRIBUTEENUM_None;
833             if (eRelation != XFA_ATTRIBUTEENUM_Ordered) {
834               CXFA_Node* pDataMatch = FindMatchingDataNode(
835                   pDocument, pTemplateChild, pDataScope, bAccessedDataDOM,
836                   false, nullptr, bSelfMatch, eBindMatch, true);
837               if (pDataMatch) {
838                 RecurseRecord sNewRecord = {pTemplateChild, pDataMatch};
839                 if (bSelfMatch)
840                   rgItemMatchList.InsertAt(0, sNewRecord);
841                 else
842                   rgItemMatchList.Add(sNewRecord);
843               } else {
844                 rgItemUnmatchList.Add(pTemplateChild);
845               }
846             } else {
847               rgItemUnmatchList.Add(pTemplateChild);
848             }
849           }
850         }
851 
852         switch (eRelation) {
853           case XFA_ATTRIBUTEENUM_Choice: {
854             ASSERT(rgItemMatchList.GetSize());
855             SortRecurseRecord(rgItemMatchList, pDataScope, true);
856             pDocument->DataMerge_CopyContainer(
857                 rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope,
858                 false, true, true);
859             break;
860           }
861           case XFA_ATTRIBUTEENUM_Unordered: {
862             if (rgItemMatchList.GetSize()) {
863               SortRecurseRecord(rgItemMatchList, pDataScope, false);
864               for (int32_t i = 0, count = rgItemMatchList.GetSize(); i < count;
865                    i++) {
866                 pDocument->DataMerge_CopyContainer(
867                     rgItemMatchList[i].pTemplateChild, pSubformSetNode,
868                     pDataScope, false, true, true);
869               }
870             }
871             for (int32_t i = 0, count = rgItemUnmatchList.GetSize(); i < count;
872                  i++) {
873               pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i],
874                                                  pSubformSetNode, pDataScope,
875                                                  false, true, true);
876             }
877             break;
878           }
879           default:
880             break;
881         }
882       } else {
883         CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
884             pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
885         ASSERT(pSubformSetNode);
886         if (!pFirstInstance)
887           pFirstInstance = pSubformSetNode;
888 
889         for (CXFA_Node* pTemplateChild =
890                  pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
891              pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
892                                  XFA_NODEITEM_NextSibling)) {
893           if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
894             XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
895                                                 pTemplateChild, true, nullptr);
896           } else if (pTemplateChild->IsContainerNode()) {
897             pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
898                                                pDataScope, false, true, true);
899           }
900         }
901       }
902     }
903 
904     if (iCurRepeatIndex == 0 && bAccessedDataDOM == false) {
905       int32_t iLimit = iMax;
906       if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) {
907         iLimit = subformArray.GetSize();
908         if (iLimit < iMin)
909           iLimit = iInit;
910       }
911 
912       for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) {
913         if (pInstMgrNode) {
914           if (pSearchArray && pSearchArray->GetSize() < 1) {
915             if (pTemplateNode->GetNameHash() != 0)
916               break;
917             pSearchArray = nullptr;
918           }
919         } else if (!XFA_DataMerge_FindFormDOMInstance(
920                        pDocument, pTemplateNode->GetElementType(),
921                        pTemplateNode->GetNameHash(), pFormParentNode)) {
922           break;
923         }
924         CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
925             pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
926         ASSERT(pSubformNode);
927         if (!pFirstInstance)
928           pFirstInstance = pSubformNode;
929 
930         for (CXFA_Node* pTemplateChild =
931                  pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
932              pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
933                                  XFA_NODEITEM_NextSibling)) {
934           if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
935             XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode,
936                                                 pTemplateChild, true, nullptr);
937           } else if (pTemplateChild->IsContainerNode()) {
938             pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode,
939                                                pDataScope, false, true, true);
940           }
941         }
942       }
943     }
944   }
945 
946   int32_t iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin;
947   for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) {
948     CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
949         pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
950     ASSERT(pSubformSetNode);
951     if (!pFirstInstance)
952       pFirstInstance = pSubformSetNode;
953 
954     bool bFound = false;
955     for (CXFA_Node* pTemplateChild =
956              pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
957          pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
958                              XFA_NODEITEM_NextSibling)) {
959       if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
960         XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
961                                             pTemplateChild, true, nullptr);
962       } else if (pTemplateChild->IsContainerNode()) {
963         if (bFound && eRelation == XFA_ATTRIBUTEENUM_Choice)
964           continue;
965 
966         pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
967                                            pDataScope, false, bDataMerge, true);
968         bFound = true;
969       }
970     }
971   }
972   return pFirstInstance;
973 }
974 
CopyContainer_Field(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bDataMerge,bool bUpLevel)975 CXFA_Node* CopyContainer_Field(CXFA_Document* pDocument,
976                                CXFA_Node* pTemplateNode,
977                                CXFA_Node* pFormNode,
978                                CXFA_Node* pDataScope,
979                                bool bDataMerge,
980                                bool bUpLevel) {
981   CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer(
982       pDocument, pFormNode, pTemplateNode, false, nullptr);
983   ASSERT(pFieldNode);
984   for (CXFA_Node* pTemplateChildNode =
985            pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
986        pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem(
987                                XFA_NODEITEM_NextSibling)) {
988     if (NeedGenerateForm(pTemplateChildNode, true)) {
989       XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode,
990                                           pTemplateChildNode, true, nullptr);
991     } else if (pTemplateNode->GetElementType() == XFA_Element::ExclGroup &&
992                pTemplateChildNode->IsContainerNode()) {
993       if (pTemplateChildNode->GetElementType() == XFA_Element::Field) {
994         CopyContainer_Field(pDocument, pTemplateChildNode, pFieldNode, nullptr,
995                             false, true);
996       }
997     }
998   }
999   if (bDataMerge) {
1000     bool bAccessedDataDOM = false;
1001     bool bSelfMatch = false;
1002     XFA_ATTRIBUTEENUM eBindMatch;
1003     CXFA_Node* pDataNode = FindMatchingDataNode(
1004         pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, true, nullptr,
1005         bSelfMatch, eBindMatch, bUpLevel);
1006     if (pDataNode)
1007       CreateDataBinding(pFieldNode, pDataNode, true);
1008   } else {
1009     FormValueNode_MatchNoneCreateChild(pFieldNode);
1010   }
1011   return pFieldNode;
1012 }
1013 
MaybeCreateDataNode(CXFA_Document * pDocument,CXFA_Node * pDataParent,XFA_Element eNodeType,const CFX_WideString & wsName)1014 CXFA_Node* MaybeCreateDataNode(CXFA_Document* pDocument,
1015                                CXFA_Node* pDataParent,
1016                                XFA_Element eNodeType,
1017                                const CFX_WideString& wsName) {
1018   if (!pDataParent)
1019     return nullptr;
1020 
1021   CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode();
1022   if (!pParentDDNode) {
1023     CXFA_Node* pDataNode =
1024         pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
1025     pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
1026     pDataNode->CreateXMLMappingNode();
1027     pDataParent->InsertChild(pDataNode);
1028     pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
1029     return pDataNode;
1030   }
1031 
1032   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> sIterator(
1033       pParentDDNode);
1034   for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
1035        pDDGroupNode = sIterator.MoveToNext()) {
1036     if (pDDGroupNode != pParentDDNode) {
1037       if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
1038         continue;
1039 
1040       CFX_WideString wsNamespace;
1041       if (!pDDGroupNode->TryNamespace(wsNamespace) ||
1042           wsNamespace != L"http://ns.adobe.com/data-description/") {
1043         continue;
1044       }
1045     }
1046     CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName.AsStringC());
1047     if (!pDDNode)
1048       continue;
1049     if (pDDNode->GetElementType() != eNodeType)
1050       break;
1051 
1052     CXFA_Node* pDataNode =
1053         pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
1054     pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
1055     pDataNode->CreateXMLMappingNode();
1056     if (eNodeType == XFA_Element::DataValue &&
1057         pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) ==
1058             XFA_ATTRIBUTEENUM_MetaData) {
1059       pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
1060     }
1061     pDataParent->InsertChild(pDataNode);
1062     pDataNode->SetDataDescriptionNode(pDDNode);
1063     pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
1064     return pDataNode;
1065   }
1066   return nullptr;
1067 }
1068 
UpdateBindingRelations(CXFA_Document * pDocument,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bDataRef,bool bParentDataRef)1069 void UpdateBindingRelations(CXFA_Document* pDocument,
1070                             CXFA_Node* pFormNode,
1071                             CXFA_Node* pDataScope,
1072                             bool bDataRef,
1073                             bool bParentDataRef) {
1074   bool bMatchRef = true;
1075   XFA_Element eType = pFormNode->GetElementType();
1076   CXFA_Node* pDataNode = pFormNode->GetBindData();
1077   if (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup ||
1078       eType == XFA_Element::Field) {
1079     CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
1080     CXFA_Node* pTemplateNodeBind =
1081         pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_Element::Bind)
1082                       : nullptr;
1083     XFA_ATTRIBUTEENUM eMatch =
1084         pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
1085                           : XFA_ATTRIBUTEENUM_Once;
1086     switch (eMatch) {
1087       case XFA_ATTRIBUTEENUM_None:
1088         if (!bDataRef || bParentDataRef)
1089           FormValueNode_MatchNoneCreateChild(pFormNode);
1090         break;
1091       case XFA_ATTRIBUTEENUM_Once:
1092         if (!bDataRef || bParentDataRef) {
1093           if (!pDataNode) {
1094             if (pFormNode->GetNameHash() != 0 &&
1095                 pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) !=
1096                     XFA_ATTRIBUTEENUM_None) {
1097               XFA_Element eDataNodeType = (eType == XFA_Element::Subform ||
1098                                            XFA_FieldIsMultiListBox(pFormNode))
1099                                               ? XFA_Element::DataGroup
1100                                               : XFA_Element::DataValue;
1101               pDataNode = MaybeCreateDataNode(
1102                   pDocument, pDataScope, eDataNodeType,
1103                   CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name)));
1104               if (pDataNode)
1105                 CreateDataBinding(pFormNode, pDataNode, false);
1106             }
1107             if (!pDataNode)
1108               FormValueNode_MatchNoneCreateChild(pFormNode);
1109 
1110           } else {
1111             CXFA_Node* pDataParent =
1112                 pDataNode->GetNodeItem(XFA_NODEITEM_Parent);
1113             if (pDataParent != pDataScope) {
1114               ASSERT(pDataParent);
1115               pDataParent->RemoveChild(pDataNode);
1116               pDataScope->InsertChild(pDataNode);
1117             }
1118           }
1119         }
1120         break;
1121       case XFA_ATTRIBUTEENUM_Global:
1122         if (!bDataRef || bParentDataRef) {
1123           uint32_t dwNameHash = pFormNode->GetNameHash();
1124           if (dwNameHash != 0 && !pDataNode) {
1125             pDataNode = GetGlobalBinding(pDocument, dwNameHash);
1126             if (!pDataNode) {
1127               XFA_Element eDataNodeType = (eType == XFA_Element::Subform ||
1128                                            XFA_FieldIsMultiListBox(pFormNode))
1129                                               ? XFA_Element::DataGroup
1130                                               : XFA_Element::DataValue;
1131               CXFA_Node* pRecordNode =
1132                   ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
1133               pDataNode = MaybeCreateDataNode(
1134                   pDocument, pRecordNode, eDataNodeType,
1135                   CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name)));
1136               if (pDataNode) {
1137                 CreateDataBinding(pFormNode, pDataNode, false);
1138                 RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(),
1139                                       pDataNode);
1140               }
1141             } else {
1142               CreateDataBinding(pFormNode, pDataNode, true);
1143             }
1144           }
1145           if (!pDataNode)
1146             FormValueNode_MatchNoneCreateChild(pFormNode);
1147         }
1148         break;
1149       case XFA_ATTRIBUTEENUM_DataRef: {
1150         bMatchRef = bDataRef;
1151         bParentDataRef = true;
1152         if (!pDataNode && bDataRef) {
1153           CFX_WideStringC wsRef =
1154               pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);
1155           uint32_t dFlags =
1156               XFA_RESOLVENODE_Children | XFA_RESOLVENODE_CreateNode;
1157           XFA_RESOLVENODE_RS rs;
1158           pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs,
1159                                                         dFlags, pTemplateNode);
1160           CXFA_Object* pObject =
1161               (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr;
1162           pDataNode = ToNode(pObject);
1163           if (pDataNode) {
1164             CreateDataBinding(pFormNode, pDataNode,
1165                               rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes);
1166           } else {
1167             FormValueNode_MatchNoneCreateChild(pFormNode);
1168           }
1169         }
1170         break;
1171       }
1172       default:
1173         break;
1174     }
1175   }
1176 
1177   if (bMatchRef &&
1178       (eType == XFA_Element::Subform || eType == XFA_Element::SubformSet ||
1179        eType == XFA_Element::Area || eType == XFA_Element::PageArea ||
1180        eType == XFA_Element::PageSet)) {
1181     for (CXFA_Node* pFormChild =
1182              pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1183          pFormChild;
1184          pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1185       if (!pFormChild->IsContainerNode())
1186         continue;
1187       if (pFormChild->IsUnusedNode())
1188         continue;
1189 
1190       UpdateBindingRelations(pDocument, pFormChild,
1191                              pDataNode ? pDataNode : pDataScope, bDataRef,
1192                              bParentDataRef);
1193     }
1194   }
1195 }
1196 
UpdateDataRelation(CXFA_Node * pDataNode,CXFA_Node * pDataDescriptionNode)1197 void UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode) {
1198   ASSERT(pDataDescriptionNode);
1199   for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1200        pDataChild;
1201        pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1202     uint32_t dwNameHash = pDataChild->GetNameHash();
1203     if (!dwNameHash)
1204       continue;
1205 
1206     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
1207         sIterator(pDataDescriptionNode);
1208     for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
1209          pDDGroupNode = sIterator.MoveToNext()) {
1210       if (pDDGroupNode != pDataDescriptionNode) {
1211         if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
1212           continue;
1213 
1214         CFX_WideString wsNamespace;
1215         if (!pDDGroupNode->TryNamespace(wsNamespace) ||
1216             wsNamespace != L"http://ns.adobe.com/data-description/") {
1217           continue;
1218         }
1219       }
1220       CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash);
1221       if (!pDDNode)
1222         continue;
1223       if (pDDNode->GetElementType() != pDataChild->GetElementType())
1224         break;
1225 
1226       pDataChild->SetDataDescriptionNode(pDDNode);
1227       UpdateDataRelation(pDataChild, pDDNode);
1228       break;
1229     }
1230   }
1231 }
1232 
1233 }  // namespace
1234 
XFA_DataMerge_FindFormDOMInstance(CXFA_Document * pDocument,XFA_Element eType,uint32_t dwNameHash,CXFA_Node * pFormParent)1235 CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument,
1236                                              XFA_Element eType,
1237                                              uint32_t dwNameHash,
1238                                              CXFA_Node* pFormParent) {
1239   CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild);
1240   for (; pFormChild;
1241        pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1242     if (pFormChild->GetElementType() == eType &&
1243         pFormChild->GetNameHash() == dwNameHash && pFormChild->IsUnusedNode()) {
1244       return pFormChild;
1245     }
1246   }
1247   return nullptr;
1248 }
1249 
XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document * pDocument,CXFA_Node * pFormParent,CXFA_Node * pTemplateNode,bool bRecursive,CXFA_NodeArray * pSubformArray)1250 CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument,
1251                                                CXFA_Node* pFormParent,
1252                                                CXFA_Node* pTemplateNode,
1253                                                bool bRecursive,
1254                                                CXFA_NodeArray* pSubformArray) {
1255   CXFA_Node* pExistingNode = nullptr;
1256   if (!pSubformArray) {
1257     pExistingNode = XFA_DataMerge_FindFormDOMInstance(
1258         pDocument, pTemplateNode->GetElementType(),
1259         pTemplateNode->GetNameHash(), pFormParent);
1260   } else if (pSubformArray->GetSize() > 0) {
1261     pExistingNode = pSubformArray->GetAt(0);
1262     pSubformArray->RemoveAt(0);
1263   }
1264 
1265   if (pExistingNode) {
1266     if (pSubformArray) {
1267       pFormParent->InsertChild(pExistingNode);
1268     } else if (pExistingNode->IsContainerNode()) {
1269       pFormParent->RemoveChild(pExistingNode);
1270       pFormParent->InsertChild(pExistingNode);
1271     }
1272     pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode);
1273     pExistingNode->SetTemplateNode(pTemplateNode);
1274     if (bRecursive && pExistingNode->GetElementType() != XFA_Element::Items) {
1275       for (CXFA_Node* pTemplateChild =
1276                pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1277            pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
1278                                XFA_NODEITEM_NextSibling)) {
1279         if (NeedGenerateForm(pTemplateChild, true)) {
1280           XFA_NodeMerge_CloneOrMergeContainer(
1281               pDocument, pExistingNode, pTemplateChild, bRecursive, nullptr);
1282         }
1283       }
1284     }
1285     pExistingNode->SetFlag(XFA_NodeFlag_Initialized, true);
1286     return pExistingNode;
1287   }
1288 
1289   CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(false);
1290   pFormParent->InsertChild(pNewNode, nullptr);
1291   if (bRecursive) {
1292     for (CXFA_Node* pTemplateChild =
1293              pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1294          pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
1295                              XFA_NODEITEM_NextSibling)) {
1296       if (NeedGenerateForm(pTemplateChild, true)) {
1297         CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(true);
1298         pNewNode->InsertChild(pNewChild, nullptr);
1299       }
1300     }
1301   }
1302   return pNewNode;
1303 }
1304 
XFA_DataMerge_FindDataScope(CXFA_Node * pParentFormNode)1305 CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode) {
1306   for (CXFA_Node* pRootBoundNode = pParentFormNode;
1307        pRootBoundNode && pRootBoundNode->IsContainerNode();
1308        pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
1309     CXFA_Node* pDataScope = pRootBoundNode->GetBindData();
1310     if (pDataScope)
1311       return pDataScope;
1312   }
1313   return ToNode(
1314       pParentFormNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Data));
1315 }
1316 
DataMerge_CopyContainer(CXFA_Node * pTemplateNode,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bOneInstance,bool bDataMerge,bool bUpLevel)1317 CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
1318                                                   CXFA_Node* pFormNode,
1319                                                   CXFA_Node* pDataScope,
1320                                                   bool bOneInstance,
1321                                                   bool bDataMerge,
1322                                                   bool bUpLevel) {
1323   switch (pTemplateNode->GetElementType()) {
1324     case XFA_Element::SubformSet:
1325     case XFA_Element::Subform:
1326     case XFA_Element::Area:
1327     case XFA_Element::PageArea:
1328       return CopyContainer_SubformSet(this, pTemplateNode, pFormNode,
1329                                       pDataScope, bOneInstance, bDataMerge);
1330     case XFA_Element::ExclGroup:
1331     case XFA_Element::Field:
1332     case XFA_Element::Draw:
1333     case XFA_Element::ContentArea:
1334       return CopyContainer_Field(this, pTemplateNode, pFormNode, pDataScope,
1335                                  bDataMerge, bUpLevel);
1336     case XFA_Element::PageSet:
1337     case XFA_Element::Variables:
1338       break;
1339     default:
1340       ASSERT(false);
1341       break;
1342   }
1343   return nullptr;
1344 }
1345 
DataMerge_UpdateBindingRelations(CXFA_Node * pFormUpdateRoot)1346 void CXFA_Document::DataMerge_UpdateBindingRelations(
1347     CXFA_Node* pFormUpdateRoot) {
1348   CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope(
1349       pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent));
1350   if (!pDataScope)
1351     return;
1352 
1353   UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, false, false);
1354   UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, true, false);
1355 }
1356 
GetNotBindNode(CXFA_ObjArray & arrayNodes)1357 CXFA_Node* CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes) {
1358   for (int32_t i = 0; i < arrayNodes.GetSize(); i++) {
1359     CXFA_Node* pNode = arrayNodes[i]->AsNode();
1360     if (pNode && !pNode->HasBindItem())
1361       return pNode;
1362   }
1363   return nullptr;
1364 }
1365 
DoDataMerge()1366 void CXFA_Document::DoDataMerge() {
1367   CXFA_Node* pDatasetsRoot = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
1368   if (!pDatasetsRoot) {
1369     CFDE_XMLElement* pDatasetsXMLNode = new CFDE_XMLElement(L"xfa:datasets");
1370     pDatasetsXMLNode->SetString(L"xmlns:xfa",
1371                                 L"http://www.xfa.org/schema/xfa-data/1.0/");
1372     pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataModel);
1373     pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, L"datasets");
1374     m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode);
1375     m_pRootNode->InsertChild(pDatasetsRoot);
1376     pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);
1377   }
1378   CXFA_Node *pDataRoot = nullptr, *pDDRoot = nullptr;
1379   CFX_WideString wsDatasetsURI;
1380   pDatasetsRoot->TryNamespace(wsDatasetsURI);
1381   for (CXFA_Node* pChildNode =
1382            pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1383        pChildNode;
1384        pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1385     if (pChildNode->GetElementType() != XFA_Element::DataGroup)
1386       continue;
1387 
1388     CFX_WideString wsNamespaceURI;
1389     if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {
1390       if (!pChildNode->TryNamespace(wsNamespaceURI))
1391         continue;
1392       if (wsNamespaceURI == L"http://ns.adobe.com/data-description/")
1393         pDDRoot = pChildNode;
1394     } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {
1395       if (!pChildNode->TryNamespace(wsNamespaceURI))
1396         continue;
1397       if (wsNamespaceURI == wsDatasetsURI)
1398         pDataRoot = pChildNode;
1399     }
1400     if (pDataRoot && pDDRoot)
1401       break;
1402   }
1403 
1404   if (!pDataRoot) {
1405     CFDE_XMLElement* pDataRootXMLNode = new CFDE_XMLElement(L"xfa:data");
1406     pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup);
1407     pDataRoot->SetCData(XFA_ATTRIBUTE_Name, L"data");
1408     pDataRoot->SetXMLMappingNode(pDataRootXMLNode);
1409     pDatasetsRoot->InsertChild(pDataRoot);
1410   }
1411 
1412   CXFA_Node* pDataTopLevel =
1413       pDataRoot->GetFirstChildByClass(XFA_Element::DataGroup);
1414   uint32_t dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0;
1415   CXFA_Node* pTemplateRoot =
1416       m_pRootNode->GetFirstChildByClass(XFA_Element::Template);
1417   if (!pTemplateRoot)
1418     return;
1419 
1420   CXFA_Node* pTemplateChosen =
1421       dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash)
1422                       : nullptr;
1423   if (!pTemplateChosen ||
1424       pTemplateChosen->GetElementType() != XFA_Element::Subform) {
1425     pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_Element::Subform);
1426   }
1427   if (!pTemplateChosen)
1428     return;
1429 
1430   CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_Element::Form);
1431   bool bEmptyForm = false;
1432   if (!pFormRoot) {
1433     bEmptyForm = true;
1434     pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_Element::Form);
1435     ASSERT(pFormRoot);
1436     pFormRoot->SetCData(XFA_ATTRIBUTE_Name, L"form");
1437     m_pRootNode->InsertChild(pFormRoot, nullptr);
1438   } else {
1439     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
1440         sIterator(pFormRoot);
1441     for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
1442          pNode = sIterator.MoveToNext()) {
1443       pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
1444     }
1445   }
1446 
1447   CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
1448       this, pFormRoot, pTemplateChosen, false, nullptr);
1449   ASSERT(pSubformSetNode);
1450   if (!pDataTopLevel) {
1451     CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name);
1452     CFX_WideString wsDataTopLevelName(wsFormName.IsEmpty() ? L"form"
1453                                                            : wsFormName);
1454     CFDE_XMLElement* pDataTopLevelXMLNode =
1455         new CFDE_XMLElement(wsDataTopLevelName);
1456 
1457     pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup);
1458     pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName);
1459     pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode);
1460     CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1461     pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);
1462   }
1463 
1464   ASSERT(pDataTopLevel);
1465   CreateDataBinding(pSubformSetNode, pDataTopLevel, true);
1466   for (CXFA_Node* pTemplateChild =
1467            pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild);
1468        pTemplateChild;
1469        pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1470     if (NeedGenerateForm(pTemplateChild, true)) {
1471       XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild,
1472                                           true, nullptr);
1473     } else if (pTemplateChild->IsContainerNode()) {
1474       DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel,
1475                               false, true, true);
1476     }
1477   }
1478   if (pDDRoot)
1479     UpdateDataRelation(pDataRoot, pDDRoot);
1480 
1481   DataMerge_UpdateBindingRelations(pSubformSetNode);
1482   CXFA_Node* pPageSetNode =
1483       pSubformSetNode->GetFirstChildByClass(XFA_Element::PageSet);
1484   while (pPageSetNode) {
1485     m_pPendingPageSet.Add(pPageSetNode);
1486     CXFA_Node* pNextPageSetNode =
1487         pPageSetNode->GetNextSameClassSibling(XFA_Element::PageSet);
1488     pSubformSetNode->RemoveChild(pPageSetNode);
1489     pPageSetNode = pNextPageSetNode;
1490   }
1491 
1492   if (bEmptyForm)
1493     return;
1494 
1495   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
1496       pFormRoot);
1497   CXFA_Node* pNode = sIterator.MoveToNext();
1498   while (pNode) {
1499     if (pNode->IsUnusedNode()) {
1500       if (pNode->IsContainerNode() ||
1501           pNode->GetElementType() == XFA_Element::InstanceManager) {
1502         CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
1503         pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
1504         pNode = pNext;
1505       } else {
1506         pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
1507         pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1508         pNode = sIterator.MoveToNext();
1509       }
1510     } else {
1511       pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1512       pNode = sIterator.MoveToNext();
1513     }
1514   }
1515 }
1516 
DoDataRemerge(bool bDoDataMerge)1517 void CXFA_Document::DoDataRemerge(bool bDoDataMerge) {
1518   CXFA_Node* pFormRoot = ToNode(GetXFAObject(XFA_HASHCODE_Form));
1519   if (pFormRoot) {
1520     while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild))
1521       pFormRoot->RemoveChild(pNode);
1522     pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
1523   }
1524   m_rgGlobalBinding.clear();
1525   if (bDoDataMerge)
1526     DoDataMerge();
1527 
1528   CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor();
1529   pLayoutProcessor->SetForceReLayout(true);
1530 }
1531