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/cxfa_document_parser.h"
8 
9 #include <utility>
10 #include <vector>
11 
12 #include "core/fxcrt/autorestorer.h"
13 #include "core/fxcrt/cfx_readonlymemorystream.h"
14 #include "core/fxcrt/cfx_widetextbuf.h"
15 #include "core/fxcrt/fx_codepage.h"
16 #include "core/fxcrt/fx_extension.h"
17 #include "core/fxcrt/xml/cfx_xmlchardata.h"
18 #include "core/fxcrt/xml/cfx_xmldocument.h"
19 #include "core/fxcrt/xml/cfx_xmlelement.h"
20 #include "core/fxcrt/xml/cfx_xmlinstruction.h"
21 #include "core/fxcrt/xml/cfx_xmlnode.h"
22 #include "core/fxcrt/xml/cfx_xmlparser.h"
23 #include "core/fxcrt/xml/cfx_xmltext.h"
24 #include "fxjs/xfa/cjx_object.h"
25 #include "third_party/base/logging.h"
26 #include "third_party/base/optional.h"
27 #include "xfa/fxfa/fxfa.h"
28 #include "xfa/fxfa/parser/cxfa_document.h"
29 #include "xfa/fxfa/parser/cxfa_node.h"
30 #include "xfa/fxfa/parser/cxfa_subform.h"
31 #include "xfa/fxfa/parser/cxfa_template.h"
32 #include "xfa/fxfa/parser/xfa_basic_data.h"
33 #include "xfa/fxfa/parser/xfa_utils.h"
34 
35 namespace {
36 
GetDocumentNode(CFX_XMLNode * pRootNode)37 CFX_XMLNode* GetDocumentNode(CFX_XMLNode* pRootNode) {
38   for (CFX_XMLNode* pXMLNode = pRootNode->GetFirstChild(); pXMLNode;
39        pXMLNode = pXMLNode->GetNextSibling()) {
40     if (pXMLNode->GetType() == CFX_XMLNode::Type::kElement)
41       return pXMLNode;
42   }
43   return nullptr;
44 }
45 
MatchNodeName(CFX_XMLNode * pNode,WideStringView wsLocalTagName,WideStringView wsNamespaceURIPrefix,uint32_t eMatchFlags=XFA_XDPPACKET_FLAGS_NOMATCH)46 bool MatchNodeName(CFX_XMLNode* pNode,
47                    WideStringView wsLocalTagName,
48                    WideStringView wsNamespaceURIPrefix,
49                    uint32_t eMatchFlags = XFA_XDPPACKET_FLAGS_NOMATCH) {
50   CFX_XMLElement* pElement = ToXMLElement(pNode);
51   if (!pElement)
52     return false;
53 
54   WideString wsNodeStr = pElement->GetLocalTagName();
55   if (wsNodeStr != wsLocalTagName)
56     return false;
57 
58   wsNodeStr = pElement->GetNamespaceURI();
59   if (eMatchFlags & XFA_XDPPACKET_FLAGS_NOMATCH)
60     return true;
61   if (eMatchFlags & XFA_XDPPACKET_FLAGS_PREFIXMATCH) {
62     return wsNodeStr.First(wsNamespaceURIPrefix.GetLength()) ==
63            wsNamespaceURIPrefix;
64   }
65 
66   return wsNodeStr == wsNamespaceURIPrefix;
67 }
68 
GetAttributeLocalName(WideStringView wsAttributeName,WideString & wsLocalAttrName)69 bool GetAttributeLocalName(WideStringView wsAttributeName,
70                            WideString& wsLocalAttrName) {
71   WideString wsAttrName(wsAttributeName);
72   auto pos = wsAttrName.Find(L':', 0);
73   if (!pos.has_value()) {
74     wsLocalAttrName = std::move(wsAttrName);
75     return false;
76   }
77   wsLocalAttrName = wsAttrName.Last(wsAttrName.GetLength() - pos.value() - 1);
78   return true;
79 }
80 
ResolveAttribute(CFX_XMLElement * pElement,const WideString & wsAttrName,WideString & wsLocalAttrName,WideString & wsNamespaceURI)81 bool ResolveAttribute(CFX_XMLElement* pElement,
82                       const WideString& wsAttrName,
83                       WideString& wsLocalAttrName,
84                       WideString& wsNamespaceURI) {
85   WideString wsNSPrefix;
86   if (GetAttributeLocalName(wsAttrName.AsStringView(), wsLocalAttrName)) {
87     wsNSPrefix = wsAttrName.First(wsAttrName.GetLength() -
88                                   wsLocalAttrName.GetLength() - 1);
89   }
90   if (wsLocalAttrName.EqualsASCII("xmlns") || wsNSPrefix.EqualsASCII("xmlns") ||
91       wsNSPrefix.EqualsASCII("xml")) {
92     return false;
93   }
94   if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix,
95                                                   &wsNamespaceURI)) {
96     wsNamespaceURI.clear();
97     return false;
98   }
99   return true;
100 }
101 
FindAttributeWithNS(CFX_XMLElement * pElement,WideStringView wsLocalAttributeName,WideStringView wsNamespaceURIPrefix)102 Optional<WideString> FindAttributeWithNS(CFX_XMLElement* pElement,
103                                          WideStringView wsLocalAttributeName,
104                                          WideStringView wsNamespaceURIPrefix) {
105   WideString wsAttrNS;
106   for (auto it : pElement->GetAttributes()) {
107     auto pos = it.first.Find(L':', 0);
108     WideString wsNSPrefix;
109     if (!pos.has_value()) {
110       if (wsLocalAttributeName != it.first)
111         continue;
112     } else {
113       if (wsLocalAttributeName !=
114           it.first.Last(it.first.GetLength() - pos.value() - 1)) {
115         continue;
116       }
117       wsNSPrefix = it.first.First(pos.value());
118     }
119     if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix,
120                                                     &wsAttrNS) ||
121         wsAttrNS != wsNamespaceURIPrefix) {
122       continue;
123     }
124     return it.second;
125   }
126   return {};
127 }
128 
GetDataSetsFromXDP(CFX_XMLNode * pXMLDocumentNode)129 CFX_XMLNode* GetDataSetsFromXDP(CFX_XMLNode* pXMLDocumentNode) {
130   XFA_PACKETINFO datasets_packet =
131       XFA_GetPacketByIndex(XFA_PacketType::Datasets);
132   if (MatchNodeName(pXMLDocumentNode, datasets_packet.name, datasets_packet.uri,
133                     datasets_packet.flags)) {
134     return pXMLDocumentNode;
135   }
136   XFA_PACKETINFO xdp_packet = XFA_GetPacketByIndex(XFA_PacketType::Xdp);
137   if (!MatchNodeName(pXMLDocumentNode, xdp_packet.name, xdp_packet.uri,
138                      xdp_packet.flags)) {
139     return nullptr;
140   }
141   for (CFX_XMLNode* pDatasetsNode = pXMLDocumentNode->GetFirstChild();
142        pDatasetsNode; pDatasetsNode = pDatasetsNode->GetNextSibling()) {
143     if (MatchNodeName(pDatasetsNode, datasets_packet.name, datasets_packet.uri,
144                       datasets_packet.flags)) {
145       return pDatasetsNode;
146     }
147   }
148   return nullptr;
149 }
150 
IsStringAllWhitespace(WideString wsText)151 bool IsStringAllWhitespace(WideString wsText) {
152   wsText.TrimRight(L"\x20\x9\xD\xA");
153   return wsText.IsEmpty();
154 }
155 
ConvertXMLToPlainText(CFX_XMLElement * pRootXMLNode,WideString & wsOutput)156 void ConvertXMLToPlainText(CFX_XMLElement* pRootXMLNode, WideString& wsOutput) {
157   for (CFX_XMLNode* pXMLChild = pRootXMLNode->GetFirstChild(); pXMLChild;
158        pXMLChild = pXMLChild->GetNextSibling()) {
159     switch (pXMLChild->GetType()) {
160       case CFX_XMLNode::Type::kElement: {
161         WideString wsTextData = ToXMLElement(pXMLChild)->GetTextData();
162         wsTextData += L"\n";
163         wsOutput += wsTextData;
164         break;
165       }
166       case CFX_XMLNode::Type::kText:
167       case CFX_XMLNode::Type::kCharData: {
168         WideString wsText = ToXMLText(pXMLChild)->GetText();
169         if (IsStringAllWhitespace(wsText))
170           continue;
171         wsOutput = std::move(wsText);
172         break;
173       }
174       default:
175         NOTREACHED();
176         break;
177     }
178   }
179 }
180 
GetPlainTextFromRichText(CFX_XMLNode * pXMLNode)181 WideString GetPlainTextFromRichText(CFX_XMLNode* pXMLNode) {
182   if (!pXMLNode)
183     return WideString();
184 
185   WideString wsPlainText;
186   switch (pXMLNode->GetType()) {
187     case CFX_XMLNode::Type::kElement: {
188       CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLNode);
189       WideString wsTag = pXMLElement->GetLocalTagName();
190       uint32_t uTag = FX_HashCode_GetW(wsTag.AsStringView(), true);
191       if (uTag == 0x0001f714) {
192         wsPlainText += L"\n";
193       } else if (uTag == 0x00000070) {
194         if (!wsPlainText.IsEmpty()) {
195           wsPlainText += L"\n";
196         }
197       } else if (uTag == 0xa48ac63) {
198         if (!wsPlainText.IsEmpty() && wsPlainText.Back() != '\n') {
199           wsPlainText += L"\n";
200         }
201       }
202       break;
203     }
204     case CFX_XMLNode::Type::kText:
205     case CFX_XMLNode::Type::kCharData: {
206       WideString wsContent = ToXMLText(pXMLNode)->GetText();
207       wsPlainText += wsContent;
208       break;
209     }
210     default:
211       break;
212   }
213   for (CFX_XMLNode* pChildXML = pXMLNode->GetFirstChild(); pChildXML;
214        pChildXML = pChildXML->GetNextSibling()) {
215     wsPlainText += GetPlainTextFromRichText(pChildXML);
216   }
217 
218   return wsPlainText;
219 }
220 
221 }  // namespace
222 
XFA_RecognizeRichText(CFX_XMLElement * pRichTextXMLNode)223 bool XFA_RecognizeRichText(CFX_XMLElement* pRichTextXMLNode) {
224   return pRichTextXMLNode && pRichTextXMLNode->GetNamespaceURI().EqualsASCII(
225                                  "http://www.w3.org/1999/xhtml");
226 }
227 
CXFA_DocumentParser(CXFA_Document * pFactory)228 CXFA_DocumentParser::CXFA_DocumentParser(CXFA_Document* pFactory)
229     : m_pFactory(pFactory) {}
230 
231 CXFA_DocumentParser::~CXFA_DocumentParser() = default;
232 
Parse(const RetainPtr<IFX_SeekableReadStream> & pStream,XFA_PacketType ePacketID)233 bool CXFA_DocumentParser::Parse(
234     const RetainPtr<IFX_SeekableReadStream>& pStream,
235     XFA_PacketType ePacketID) {
236   xml_doc_ = LoadXML(pStream);
237   if (!xml_doc_)
238     return false;
239 
240   CFX_XMLNode* root = GetDocumentNode(xml_doc_->GetRoot());
241   if (!root)
242     return false;
243 
244   m_pRootNode = ParseAsXDPPacket(root, ePacketID);
245   return !!m_pRootNode;
246 }
247 
ParseXMLData(const ByteString & wsXML)248 CFX_XMLNode* CXFA_DocumentParser::ParseXMLData(const ByteString& wsXML) {
249   auto pStream = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(wsXML.raw_span());
250   xml_doc_ = LoadXML(pStream);
251   if (!xml_doc_)
252     return nullptr;
253   return GetDocumentNode(xml_doc_->GetRoot());
254 }
255 
LoadXML(const RetainPtr<IFX_SeekableReadStream> & pStream)256 std::unique_ptr<CFX_XMLDocument> CXFA_DocumentParser::LoadXML(
257     const RetainPtr<IFX_SeekableReadStream>& pStream) {
258   ASSERT(pStream);
259 
260   CFX_XMLParser parser(pStream);
261   std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
262   if (doc) {
263     doc->GetRoot()->InsertChildNode(doc->CreateNode<CFX_XMLInstruction>(L"xml"),
264                                     0);
265   }
266   return doc;
267 }
268 
ConstructXFANode(CXFA_Node * pXFANode,CFX_XMLNode * pXMLNode)269 void CXFA_DocumentParser::ConstructXFANode(CXFA_Node* pXFANode,
270                                            CFX_XMLNode* pXMLNode) {
271   XFA_PacketType ePacketID = pXFANode->GetPacketType();
272   if (ePacketID == XFA_PacketType::Datasets) {
273     if (pXFANode->GetElementType() == XFA_Element::DataValue) {
274       for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
275            pXMLChild = pXMLChild->GetNextSibling()) {
276         CFX_XMLNode::Type eNodeType = pXMLChild->GetType();
277         if (eNodeType == CFX_XMLNode::Type::kInstruction)
278           continue;
279 
280         if (eNodeType == CFX_XMLNode::Type::kElement) {
281           CXFA_Node* pXFAChild = m_pFactory->CreateNode(
282               XFA_PacketType::Datasets, XFA_Element::DataValue);
283           if (!pXFAChild)
284             return;
285 
286           CFX_XMLElement* child = static_cast<CFX_XMLElement*>(pXMLChild);
287           WideString wsNodeStr = child->GetLocalTagName();
288           pXFAChild->JSObject()->SetCData(XFA_Attribute::Name, wsNodeStr, false,
289                                           false);
290           WideString wsChildValue = GetPlainTextFromRichText(child);
291           if (!wsChildValue.IsEmpty())
292             pXFAChild->JSObject()->SetCData(XFA_Attribute::Value, wsChildValue,
293                                             false, false);
294 
295           pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
296           pXFAChild->SetXMLMappingNode(pXMLChild);
297           pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
298           break;
299         }
300       }
301       m_pRootNode = pXFANode;
302     } else {
303       m_pRootNode = DataLoader(pXFANode, pXMLNode, true);
304     }
305   } else if (pXFANode->IsContentNode()) {
306     ParseContentNode(pXFANode, pXMLNode, ePacketID);
307     m_pRootNode = pXFANode;
308   } else {
309     m_pRootNode = NormalLoader(pXFANode, pXMLNode, ePacketID, true);
310   }
311 }
312 
GetRootNode() const313 CXFA_Node* CXFA_DocumentParser::GetRootNode() const {
314   return m_pRootNode;
315 }
316 
ParseAsXDPPacket(CFX_XMLNode * pXMLDocumentNode,XFA_PacketType ePacketID)317 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket(CFX_XMLNode* pXMLDocumentNode,
318                                                  XFA_PacketType ePacketID) {
319   switch (ePacketID) {
320     case XFA_PacketType::Xdp:
321       return ParseAsXDPPacket_XDP(pXMLDocumentNode);
322     case XFA_PacketType::Config:
323       return ParseAsXDPPacket_Config(pXMLDocumentNode);
324     case XFA_PacketType::Template:
325       return ParseAsXDPPacket_Template(pXMLDocumentNode);
326     case XFA_PacketType::Form:
327       return ParseAsXDPPacket_Form(pXMLDocumentNode);
328     case XFA_PacketType::Datasets:
329       return ParseAsXDPPacket_Data(pXMLDocumentNode);
330     case XFA_PacketType::Xdc:
331       return ParseAsXDPPacket_Xdc(pXMLDocumentNode);
332     case XFA_PacketType::LocaleSet:
333       return ParseAsXDPPacket_LocaleConnectionSourceSet(
334           pXMLDocumentNode, XFA_PacketType::LocaleSet, XFA_Element::LocaleSet);
335     case XFA_PacketType::ConnectionSet:
336       return ParseAsXDPPacket_LocaleConnectionSourceSet(
337           pXMLDocumentNode, XFA_PacketType::ConnectionSet,
338           XFA_Element::ConnectionSet);
339     case XFA_PacketType::SourceSet:
340       return ParseAsXDPPacket_LocaleConnectionSourceSet(
341           pXMLDocumentNode, XFA_PacketType::SourceSet, XFA_Element::SourceSet);
342     default:
343       return ParseAsXDPPacket_User(pXMLDocumentNode);
344   }
345 }
346 
ParseAsXDPPacket_XDP(CFX_XMLNode * pXMLDocumentNode)347 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_XDP(
348     CFX_XMLNode* pXMLDocumentNode) {
349   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Xdp);
350   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
351     return nullptr;
352 
353   CXFA_Node* pXFARootNode =
354       m_pFactory->CreateNode(XFA_PacketType::Xdp, XFA_Element::Xfa);
355   if (!pXFARootNode)
356     return nullptr;
357 
358   m_pRootNode = pXFARootNode;
359   pXFARootNode->JSObject()->SetCData(XFA_Attribute::Name, L"xfa", false, false);
360 
361   for (auto it : ToXMLElement(pXMLDocumentNode)->GetAttributes()) {
362     if (it.first.EqualsASCII("uuid")) {
363       pXFARootNode->JSObject()->SetCData(XFA_Attribute::Uuid, it.second, false,
364                                          false);
365     } else if (it.first.EqualsASCII("timeStamp")) {
366       pXFARootNode->JSObject()->SetCData(XFA_Attribute::TimeStamp, it.second,
367                                          false, false);
368     }
369   }
370 
371   CFX_XMLNode* pXMLConfigDOMRoot = nullptr;
372   CXFA_Node* pXFAConfigDOMRoot = nullptr;
373   XFA_PACKETINFO config_packet = XFA_GetPacketByIndex(XFA_PacketType::Config);
374   for (CFX_XMLNode* pChildItem = pXMLDocumentNode->GetFirstChild(); pChildItem;
375        pChildItem = pChildItem->GetNextSibling()) {
376     if (!MatchNodeName(pChildItem, config_packet.name, config_packet.uri,
377                        config_packet.flags)) {
378       continue;
379     }
380     // TODO(tsepez): make GetFirstChildByName() take a name.
381     uint32_t hash = FX_HashCode_GetW(config_packet.name, false);
382     if (pXFARootNode->GetFirstChildByName(hash))
383       return nullptr;
384 
385     pXMLConfigDOMRoot = pChildItem;
386     pXFAConfigDOMRoot = ParseAsXDPPacket_Config(pXMLConfigDOMRoot);
387     if (pXFAConfigDOMRoot)
388       pXFARootNode->InsertChildAndNotify(pXFAConfigDOMRoot, nullptr);
389   }
390 
391   CFX_XMLNode* pXMLDatasetsDOMRoot = nullptr;
392   CFX_XMLNode* pXMLFormDOMRoot = nullptr;
393   CFX_XMLNode* pXMLTemplateDOMRoot = nullptr;
394   for (CFX_XMLNode* pChildItem = pXMLDocumentNode->GetFirstChild(); pChildItem;
395        pChildItem = pChildItem->GetNextSibling()) {
396     CFX_XMLElement* pElement = ToXMLElement(pChildItem);
397     if (!pElement || pElement == pXMLConfigDOMRoot)
398       continue;
399 
400     WideString wsPacketName = pElement->GetLocalTagName();
401     Optional<XFA_PACKETINFO> packet_info =
402         XFA_GetPacketByName(wsPacketName.AsStringView());
403     if (packet_info.has_value() && packet_info.value().uri &&
404         !MatchNodeName(pElement, packet_info.value().name,
405                        packet_info.value().uri, packet_info.value().flags)) {
406       packet_info = {};
407     }
408     XFA_PacketType ePacket = XFA_PacketType::User;
409     if (packet_info.has_value())
410       ePacket = packet_info.value().packet_type;
411     if (ePacket == XFA_PacketType::Xdp)
412       continue;
413     if (ePacket == XFA_PacketType::Datasets) {
414       if (pXMLDatasetsDOMRoot)
415         return nullptr;
416 
417       pXMLDatasetsDOMRoot = pElement;
418     } else if (ePacket == XFA_PacketType::Form) {
419       if (pXMLFormDOMRoot)
420         return nullptr;
421 
422       pXMLFormDOMRoot = pElement;
423     } else if (ePacket == XFA_PacketType::Template) {
424       // Found a duplicate template packet.
425       if (pXMLTemplateDOMRoot)
426         return nullptr;
427 
428       CXFA_Node* pPacketNode = ParseAsXDPPacket_Template(pElement);
429       if (pPacketNode) {
430         pXMLTemplateDOMRoot = pElement;
431         pXFARootNode->InsertChildAndNotify(pPacketNode, nullptr);
432       }
433     } else {
434       CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
435       if (pPacketNode) {
436         if (packet_info.has_value() &&
437             (packet_info.value().flags & XFA_XDPPACKET_FLAGS_SUPPORTONE) &&
438             pXFARootNode->GetFirstChildByName(
439                 FX_HashCode_GetW(packet_info.value().name, false))) {
440           return nullptr;
441         }
442         pXFARootNode->InsertChildAndNotify(pPacketNode, nullptr);
443       }
444     }
445   }
446 
447   // No template is found.
448   if (!pXMLTemplateDOMRoot)
449     return nullptr;
450 
451   if (pXMLDatasetsDOMRoot) {
452     CXFA_Node* pPacketNode =
453         ParseAsXDPPacket(pXMLDatasetsDOMRoot, XFA_PacketType::Datasets);
454     if (pPacketNode)
455       pXFARootNode->InsertChildAndNotify(pPacketNode, nullptr);
456   }
457   if (pXMLFormDOMRoot) {
458     CXFA_Node* pPacketNode =
459         ParseAsXDPPacket(pXMLFormDOMRoot, XFA_PacketType::Form);
460     if (pPacketNode)
461       pXFARootNode->InsertChildAndNotify(pPacketNode, nullptr);
462   }
463 
464   pXFARootNode->SetXMLMappingNode(pXMLDocumentNode);
465   return pXFARootNode;
466 }
467 
ParseAsXDPPacket_Config(CFX_XMLNode * pXMLDocumentNode)468 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Config(
469     CFX_XMLNode* pXMLDocumentNode) {
470   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Config);
471   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
472     return nullptr;
473 
474   CXFA_Node* pNode =
475       m_pFactory->CreateNode(XFA_PacketType::Config, XFA_Element::Config);
476   if (!pNode)
477     return nullptr;
478 
479   pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
480   if (!NormalLoader(pNode, pXMLDocumentNode, XFA_PacketType::Config, true))
481     return nullptr;
482 
483   pNode->SetXMLMappingNode(pXMLDocumentNode);
484   return pNode;
485 }
486 
ParseAsXDPPacket_Template(CFX_XMLNode * pXMLDocumentNode)487 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Template(
488     CFX_XMLNode* pXMLDocumentNode) {
489   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Template);
490   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
491     return nullptr;
492 
493   CXFA_Node* pNode =
494       m_pFactory->CreateNode(XFA_PacketType::Template, XFA_Element::Template);
495   if (!pNode)
496     return nullptr;
497 
498   pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
499 
500   CFX_XMLElement* pXMLDocumentElement = ToXMLElement(pXMLDocumentNode);
501   WideString wsNamespaceURI = pXMLDocumentElement->GetNamespaceURI();
502   if (wsNamespaceURI.IsEmpty())
503     wsNamespaceURI = pXMLDocumentElement->GetAttribute(L"xmlns:xfa");
504 
505   pNode->GetDocument()->RecognizeXFAVersionNumber(wsNamespaceURI);
506 
507   if (!NormalLoader(pNode, pXMLDocumentNode, XFA_PacketType::Template, true))
508     return nullptr;
509 
510   pNode->SetXMLMappingNode(pXMLDocumentNode);
511   return pNode;
512 }
513 
ParseAsXDPPacket_Form(CFX_XMLNode * pXMLDocumentNode)514 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Form(
515     CFX_XMLNode* pXMLDocumentNode) {
516   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Form);
517   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
518     return nullptr;
519 
520   CXFA_Node* pNode =
521       m_pFactory->CreateNode(XFA_PacketType::Form, XFA_Element::Form);
522   if (!pNode)
523     return nullptr;
524 
525   pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
526   CXFA_Template* pTemplateRoot =
527       m_pRootNode->GetFirstChildByClass<CXFA_Template>(XFA_Element::Template);
528   CXFA_Subform* pTemplateChosen =
529       pTemplateRoot ? pTemplateRoot->GetFirstChildByClass<CXFA_Subform>(
530                           XFA_Element::Subform)
531                     : nullptr;
532   bool bUseAttribute = true;
533   if (pTemplateChosen &&
534       pTemplateChosen->JSObject()->GetEnum(XFA_Attribute::RestoreState) !=
535           XFA_AttributeValue::Auto) {
536     bUseAttribute = false;
537   }
538   if (!NormalLoader(pNode, pXMLDocumentNode, XFA_PacketType::Form,
539                     bUseAttribute))
540     return nullptr;
541 
542   pNode->SetXMLMappingNode(pXMLDocumentNode);
543   return pNode;
544 }
545 
ParseAsXDPPacket_Data(CFX_XMLNode * pXMLDocumentNode)546 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Data(
547     CFX_XMLNode* pXMLDocumentNode) {
548   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Datasets);
549   CFX_XMLNode* pDatasetsXMLNode = GetDataSetsFromXDP(pXMLDocumentNode);
550   if (pDatasetsXMLNode) {
551     CXFA_Node* pNode = m_pFactory->CreateNode(XFA_PacketType::Datasets,
552                                               XFA_Element::DataModel);
553     if (!pNode)
554       return nullptr;
555 
556     pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
557     if (!DataLoader(pNode, pDatasetsXMLNode, false))
558       return nullptr;
559 
560     pNode->SetXMLMappingNode(pDatasetsXMLNode);
561     return pNode;
562   }
563 
564   CFX_XMLNode* pDataXMLNode = nullptr;
565   if (MatchNodeName(pXMLDocumentNode, L"data", packet.uri, packet.flags)) {
566     ToXMLElement(pXMLDocumentNode)->RemoveAttribute(L"xmlns:xfa");
567     pDataXMLNode = pXMLDocumentNode;
568   } else {
569     auto* pDataElement = xml_doc_->CreateNode<CFX_XMLElement>(L"xfa:data");
570     pXMLDocumentNode->RemoveSelfIfParented();
571 
572     CFX_XMLElement* pElement = ToXMLElement(pXMLDocumentNode);
573     pElement->RemoveAttribute(L"xmlns:xfa");
574 
575     // The node was either removed from the parent above, or already has no
576     // parent so we can take ownership.
577     pDataElement->AppendLastChild(pXMLDocumentNode);
578     pDataXMLNode = pDataElement;
579   }
580   if (!pDataXMLNode)
581     return nullptr;
582 
583   CXFA_Node* pNode =
584       m_pFactory->CreateNode(XFA_PacketType::Datasets, XFA_Element::DataGroup);
585   if (!pNode)
586     return nullptr;
587 
588   WideString wsLocalName = ToXMLElement(pDataXMLNode)->GetLocalTagName();
589   pNode->JSObject()->SetCData(XFA_Attribute::Name, wsLocalName, false, false);
590   if (!DataLoader(pNode, pDataXMLNode, true))
591     return nullptr;
592 
593   pNode->SetXMLMappingNode(pDataXMLNode);
594   return pNode;
595 }
596 
ParseAsXDPPacket_LocaleConnectionSourceSet(CFX_XMLNode * pXMLDocumentNode,XFA_PacketType packet_type,XFA_Element element)597 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_LocaleConnectionSourceSet(
598     CFX_XMLNode* pXMLDocumentNode,
599     XFA_PacketType packet_type,
600     XFA_Element element) {
601   XFA_PACKETINFO packet = XFA_GetPacketByIndex(packet_type);
602   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
603     return nullptr;
604 
605   CXFA_Node* pNode = m_pFactory->CreateNode(packet_type, element);
606   if (!pNode)
607     return nullptr;
608 
609   pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
610   if (!NormalLoader(pNode, pXMLDocumentNode, packet_type, true))
611     return nullptr;
612 
613   pNode->SetXMLMappingNode(pXMLDocumentNode);
614   return pNode;
615 }
616 
ParseAsXDPPacket_Xdc(CFX_XMLNode * pXMLDocumentNode)617 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Xdc(
618     CFX_XMLNode* pXMLDocumentNode) {
619   XFA_PACKETINFO packet = XFA_GetPacketByIndex(XFA_PacketType::Xdc);
620   if (!MatchNodeName(pXMLDocumentNode, packet.name, packet.uri, packet.flags))
621     return nullptr;
622 
623   CXFA_Node* pNode =
624       m_pFactory->CreateNode(XFA_PacketType::Xdc, XFA_Element::Xdc);
625   if (!pNode)
626     return nullptr;
627 
628   pNode->JSObject()->SetCData(XFA_Attribute::Name, packet.name, false, false);
629   pNode->SetXMLMappingNode(pXMLDocumentNode);
630   return pNode;
631 }
632 
ParseAsXDPPacket_User(CFX_XMLNode * pXMLDocumentNode)633 CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_User(
634     CFX_XMLNode* pXMLDocumentNode) {
635   CXFA_Node* pNode =
636       m_pFactory->CreateNode(XFA_PacketType::Xdp, XFA_Element::Packet);
637   if (!pNode)
638     return nullptr;
639 
640   WideString wsName = ToXMLElement(pXMLDocumentNode)->GetLocalTagName();
641   pNode->JSObject()->SetCData(XFA_Attribute::Name, wsName, false, false);
642   pNode->SetXMLMappingNode(pXMLDocumentNode);
643   return pNode;
644 }
645 
DataLoader(CXFA_Node * pXFANode,CFX_XMLNode * pXMLDoc,bool bDoTransform)646 CXFA_Node* CXFA_DocumentParser::DataLoader(CXFA_Node* pXFANode,
647                                            CFX_XMLNode* pXMLDoc,
648                                            bool bDoTransform) {
649   ParseDataGroup(pXFANode, pXMLDoc, XFA_PacketType::Datasets);
650   return pXFANode;
651 }
652 
NormalLoader(CXFA_Node * pXFANode,CFX_XMLNode * pXMLDoc,XFA_PacketType ePacketID,bool bUseAttribute)653 CXFA_Node* CXFA_DocumentParser::NormalLoader(CXFA_Node* pXFANode,
654                                              CFX_XMLNode* pXMLDoc,
655                                              XFA_PacketType ePacketID,
656                                              bool bUseAttribute) {
657   constexpr size_t kMaxExecuteRecursion = 1000;
658   if (m_ExecuteRecursionDepth > kMaxExecuteRecursion)
659     return nullptr;
660   AutoRestorer<size_t> restorer(&m_ExecuteRecursionDepth);
661   ++m_ExecuteRecursionDepth;
662 
663   bool bOneOfPropertyFound = false;
664   for (CFX_XMLNode* pXMLChild = pXMLDoc->GetFirstChild(); pXMLChild;
665        pXMLChild = pXMLChild->GetNextSibling()) {
666     switch (pXMLChild->GetType()) {
667       case CFX_XMLNode::Type::kElement: {
668         CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLChild);
669         WideString wsTagName = pXMLElement->GetLocalTagName();
670         XFA_Element eType = XFA_GetElementByName(wsTagName.AsStringView());
671         if (eType == XFA_Element::Unknown)
672           continue;
673 
674         if (pXFANode->HasPropertyFlags(
675                 eType,
676                 XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf)) {
677           if (bOneOfPropertyFound)
678             break;
679           bOneOfPropertyFound = true;
680         }
681 
682         CXFA_Node* pXFAChild = m_pFactory->CreateNode(ePacketID, eType);
683         if (!pXFAChild)
684           return nullptr;
685         if (ePacketID == XFA_PacketType::Config) {
686           pXFAChild->JSObject()->SetAttribute(XFA_Attribute::Name,
687                                               wsTagName.AsStringView(), false);
688         }
689 
690         bool IsNeedValue = true;
691         for (auto it : pXMLElement->GetAttributes()) {
692           WideString wsAttrName;
693           GetAttributeLocalName(it.first.AsStringView(), wsAttrName);
694           if (wsAttrName.EqualsASCII("nil") && it.second.EqualsASCII("true"))
695             IsNeedValue = false;
696 
697           Optional<XFA_ATTRIBUTEINFO> attr =
698               XFA_GetAttributeByName(wsAttrName.AsStringView());
699           if (!attr.has_value())
700             continue;
701 
702           if (!bUseAttribute && attr.value().attribute != XFA_Attribute::Name &&
703               attr.value().attribute != XFA_Attribute::Save) {
704             continue;
705           }
706           pXFAChild->JSObject()->SetAttribute(attr.value().attribute,
707                                               it.second.AsStringView(), false);
708         }
709         pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
710         if (eType == XFA_Element::Validate || eType == XFA_Element::Locale) {
711           if (ePacketID == XFA_PacketType::Config)
712             ParseContentNode(pXFAChild, pXMLElement, ePacketID);
713           else
714             NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
715 
716           break;
717         }
718         switch (pXFAChild->GetObjectType()) {
719           case XFA_ObjectType::ContentNode:
720           case XFA_ObjectType::TextNode:
721           case XFA_ObjectType::NodeC:
722           case XFA_ObjectType::NodeV:
723             if (IsNeedValue)
724               ParseContentNode(pXFAChild, pXMLElement, ePacketID);
725             break;
726           default:
727             NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
728             break;
729         }
730       } break;
731       case CFX_XMLNode::Type::kInstruction:
732         ParseInstruction(pXFANode, ToXMLInstruction(pXMLChild), ePacketID);
733         break;
734       default:
735         break;
736     }
737   }
738   return pXFANode;
739 }
740 
ParseContentNode(CXFA_Node * pXFANode,CFX_XMLNode * pXMLNode,XFA_PacketType ePacketID)741 void CXFA_DocumentParser::ParseContentNode(CXFA_Node* pXFANode,
742                                            CFX_XMLNode* pXMLNode,
743                                            XFA_PacketType ePacketID) {
744   XFA_Element element = XFA_Element::Sharptext;
745   if (pXFANode->GetElementType() == XFA_Element::ExData) {
746     WideString wsContentType =
747         pXFANode->JSObject()->GetCData(XFA_Attribute::ContentType);
748     if (wsContentType.EqualsASCII("text/html"))
749       element = XFA_Element::SharpxHTML;
750     else if (wsContentType.EqualsASCII("text/xml"))
751       element = XFA_Element::Sharpxml;
752   }
753   if (element == XFA_Element::SharpxHTML)
754     pXFANode->SetXMLMappingNode(pXMLNode);
755 
756   WideString wsValue;
757   for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
758        pXMLChild = pXMLChild->GetNextSibling()) {
759     CFX_XMLNode::Type eNodeType = pXMLChild->GetType();
760     if (eNodeType == CFX_XMLNode::Type::kInstruction)
761       continue;
762 
763     CFX_XMLElement* pElement = ToXMLElement(pXMLChild);
764     if (element == XFA_Element::SharpxHTML) {
765       if (!pElement)
766         break;
767       if (XFA_RecognizeRichText(pElement))
768         wsValue += GetPlainTextFromRichText(pElement);
769     } else if (element == XFA_Element::Sharpxml) {
770       if (!pElement)
771         break;
772       ConvertXMLToPlainText(pElement, wsValue);
773     } else {
774       if (pElement)
775         break;
776       CFX_XMLText* pText = ToXMLText(pXMLChild);
777       if (pText)
778         wsValue = pText->GetText();
779     }
780     break;
781   }
782   if (!wsValue.IsEmpty()) {
783     if (pXFANode->IsContentNode()) {
784       CXFA_Node* pContentRawDataNode =
785           m_pFactory->CreateNode(ePacketID, element);
786       ASSERT(pContentRawDataNode);
787       pContentRawDataNode->JSObject()->SetCData(XFA_Attribute::Value, wsValue,
788                                                 false, false);
789       pXFANode->InsertChildAndNotify(pContentRawDataNode, nullptr);
790     } else {
791       pXFANode->JSObject()->SetCData(XFA_Attribute::Value, wsValue, false,
792                                      false);
793     }
794   }
795 }
796 
ParseDataGroup(CXFA_Node * pXFANode,CFX_XMLNode * pXMLNode,XFA_PacketType ePacketID)797 void CXFA_DocumentParser::ParseDataGroup(CXFA_Node* pXFANode,
798                                          CFX_XMLNode* pXMLNode,
799                                          XFA_PacketType ePacketID) {
800   for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
801        pXMLChild = pXMLChild->GetNextSibling()) {
802     switch (pXMLChild->GetType()) {
803       case CFX_XMLNode::Type::kElement: {
804         CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLChild);
805         WideString wsNamespaceURI = pXMLElement->GetNamespaceURI();
806         if (wsNamespaceURI.EqualsASCII(
807                 "http://www.xfa.com/schema/xfa-package/") ||
808             wsNamespaceURI.EqualsASCII(
809                 "http://www.xfa.org/schema/xfa-package/") ||
810             wsNamespaceURI.EqualsASCII(
811                 "http://www.w3.org/2001/XMLSchema-instance")) {
812           continue;
813         }
814 
815         XFA_Element eNodeType = XFA_Element::DataModel;
816         if (eNodeType == XFA_Element::DataModel) {
817           Optional<WideString> wsDataNodeAttr =
818               FindAttributeWithNS(pXMLElement, L"dataNode",
819                                   L"http://www.xfa.org/schema/xfa-data/1.0/");
820           if (wsDataNodeAttr.has_value()) {
821             if (wsDataNodeAttr.value().EqualsASCII("dataGroup"))
822               eNodeType = XFA_Element::DataGroup;
823             else if (wsDataNodeAttr.value().EqualsASCII("dataValue"))
824               eNodeType = XFA_Element::DataValue;
825           }
826         }
827         if (eNodeType == XFA_Element::DataModel) {
828           Optional<WideString> wsContentType =
829               FindAttributeWithNS(pXMLElement, L"contentType",
830                                   L"http://www.xfa.org/schema/xfa-data/1.0/");
831           if (wsContentType.has_value() && !wsContentType.value().IsEmpty())
832             eNodeType = XFA_Element::DataValue;
833         }
834         if (eNodeType == XFA_Element::DataModel) {
835           for (CFX_XMLNode* pXMLDataChild = pXMLElement->GetFirstChild();
836                pXMLDataChild; pXMLDataChild = pXMLDataChild->GetNextSibling()) {
837             CFX_XMLElement* pElement = ToXMLElement(pXMLDataChild);
838             if (pElement && !XFA_RecognizeRichText(pElement)) {
839               eNodeType = XFA_Element::DataGroup;
840               break;
841             }
842           }
843         }
844         if (eNodeType == XFA_Element::DataModel)
845           eNodeType = XFA_Element::DataValue;
846 
847         CXFA_Node* pXFAChild =
848             m_pFactory->CreateNode(XFA_PacketType::Datasets, eNodeType);
849         if (!pXFAChild)
850           return;
851 
852         pXFAChild->JSObject()->SetCData(
853             XFA_Attribute::Name, pXMLElement->GetLocalTagName(), false, false);
854         bool bNeedValue = true;
855 
856         for (auto it : pXMLElement->GetAttributes()) {
857           WideString wsName;
858           WideString wsNS;
859           if (!ResolveAttribute(pXMLElement, it.first, wsName, wsNS)) {
860             continue;
861           }
862           if (wsName.EqualsASCII("nil") && it.second.EqualsASCII("true")) {
863             bNeedValue = false;
864             continue;
865           }
866           if (wsNS.EqualsASCII("http://www.xfa.com/schema/xfa-package/") ||
867               wsNS.EqualsASCII("http://www.xfa.org/schema/xfa-package/") ||
868               wsNS.EqualsASCII("http://www.w3.org/2001/XMLSchema-instance") ||
869               wsNS.EqualsASCII("http://www.xfa.org/schema/xfa-data/1.0/")) {
870             continue;
871           }
872           CXFA_Node* pXFAMetaData = m_pFactory->CreateNode(
873               XFA_PacketType::Datasets, XFA_Element::DataValue);
874           if (!pXFAMetaData)
875             return;
876 
877           pXFAMetaData->JSObject()->SetCData(XFA_Attribute::Name, wsName, false,
878                                              false);
879           pXFAMetaData->JSObject()->SetCData(XFA_Attribute::QualifiedName,
880                                              it.first, false, false);
881           pXFAMetaData->JSObject()->SetCData(XFA_Attribute::Value, it.second,
882                                              false, false);
883           pXFAMetaData->JSObject()->SetEnum(
884               XFA_Attribute::Contains, XFA_AttributeValue::MetaData, false);
885           pXFAChild->InsertChildAndNotify(pXFAMetaData, nullptr);
886           pXFAMetaData->SetXMLMappingNode(pXMLElement);
887           pXFAMetaData->SetFlag(XFA_NodeFlag_Initialized);
888         }
889 
890         if (!bNeedValue)
891           pXMLElement->RemoveAttribute(L"xsi:nil");
892 
893         pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
894         if (eNodeType == XFA_Element::DataGroup)
895           ParseDataGroup(pXFAChild, pXMLElement, ePacketID);
896         else if (bNeedValue)
897           ParseDataValue(pXFAChild, pXMLChild, XFA_PacketType::Datasets);
898 
899         pXFAChild->SetXMLMappingNode(pXMLElement);
900         pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
901         continue;
902       }
903       case CFX_XMLNode::Type::kCharData:
904       case CFX_XMLNode::Type::kText: {
905         CFX_XMLText* pXMLText = ToXMLText(pXMLChild);
906         WideString wsText = pXMLText->GetText();
907         if (IsStringAllWhitespace(wsText))
908           continue;
909 
910         CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_PacketType::Datasets,
911                                                       XFA_Element::DataValue);
912         if (!pXFAChild)
913           return;
914 
915         pXFAChild->JSObject()->SetCData(XFA_Attribute::Value, wsText, false,
916                                         false);
917         pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
918         pXFAChild->SetXMLMappingNode(pXMLText);
919         pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
920         continue;
921       }
922       default:
923         continue;
924     }
925   }
926 }
927 
ParseDataValue(CXFA_Node * pXFANode,CFX_XMLNode * pXMLNode,XFA_PacketType ePacketID)928 void CXFA_DocumentParser::ParseDataValue(CXFA_Node* pXFANode,
929                                          CFX_XMLNode* pXMLNode,
930                                          XFA_PacketType ePacketID) {
931   CFX_WideTextBuf wsValueTextBuf;
932   CFX_WideTextBuf wsCurValueTextBuf;
933   bool bMarkAsCompound = false;
934   CFX_XMLNode* pXMLCurValueNode = nullptr;
935   for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
936        pXMLChild = pXMLChild->GetNextSibling()) {
937     CFX_XMLNode::Type eNodeType = pXMLChild->GetType();
938     if (eNodeType == CFX_XMLNode::Type::kInstruction)
939       continue;
940 
941     CFX_XMLText* pText = ToXMLText(pXMLChild);
942     if (pText) {
943       WideString wsText = pText->GetText();
944       if (!pXMLCurValueNode)
945         pXMLCurValueNode = pXMLChild;
946       wsCurValueTextBuf << wsText;
947       continue;
948     }
949     if (XFA_RecognizeRichText(ToXMLElement(pXMLChild))) {
950       WideString wsText = GetPlainTextFromRichText(ToXMLElement(pXMLChild));
951       if (!pXMLCurValueNode)
952         pXMLCurValueNode = pXMLChild;
953       wsCurValueTextBuf << wsText;
954       continue;
955     }
956     bMarkAsCompound = true;
957     if (pXMLCurValueNode) {
958       WideString wsCurValue = wsCurValueTextBuf.MakeString();
959       if (!wsCurValue.IsEmpty()) {
960         CXFA_Node* pXFAChild =
961             m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
962         if (!pXFAChild)
963           return;
964 
965         pXFAChild->JSObject()->SetCData(XFA_Attribute::Name, WideString(),
966                                         false, false);
967         pXFAChild->JSObject()->SetCData(XFA_Attribute::Value, wsCurValue, false,
968                                         false);
969         pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
970         pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
971         pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
972         wsValueTextBuf << wsCurValue;
973         wsCurValueTextBuf.Clear();
974       }
975       pXMLCurValueNode = nullptr;
976     }
977     CXFA_Node* pXFAChild =
978         m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
979     if (!pXFAChild)
980       return;
981 
982     WideString wsNodeStr = ToXMLElement(pXMLChild)->GetLocalTagName();
983     pXFAChild->JSObject()->SetCData(XFA_Attribute::Name, wsNodeStr, false,
984                                     false);
985     ParseDataValue(pXFAChild, pXMLChild, ePacketID);
986     pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
987     pXFAChild->SetXMLMappingNode(pXMLChild);
988     pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
989     WideString wsCurValue =
990         pXFAChild->JSObject()->GetCData(XFA_Attribute::Value);
991     wsValueTextBuf << wsCurValue;
992   }
993 
994   if (pXMLCurValueNode) {
995     WideString wsCurValue = wsCurValueTextBuf.MakeString();
996     if (!wsCurValue.IsEmpty()) {
997       if (bMarkAsCompound) {
998         CXFA_Node* pXFAChild =
999             m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
1000         if (!pXFAChild)
1001           return;
1002 
1003         pXFAChild->JSObject()->SetCData(XFA_Attribute::Name, WideString(),
1004                                         false, false);
1005         pXFAChild->JSObject()->SetCData(XFA_Attribute::Value, wsCurValue, false,
1006                                         false);
1007         pXFANode->InsertChildAndNotify(pXFAChild, nullptr);
1008         pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
1009         pXFAChild->SetFlag(XFA_NodeFlag_Initialized);
1010       }
1011       wsValueTextBuf << wsCurValue;
1012       wsCurValueTextBuf.Clear();
1013     }
1014     pXMLCurValueNode = nullptr;
1015   }
1016   WideString wsNodeValue = wsValueTextBuf.MakeString();
1017   pXFANode->JSObject()->SetCData(XFA_Attribute::Value, wsNodeValue, false,
1018                                  false);
1019 }
1020 
ParseInstruction(CXFA_Node * pXFANode,CFX_XMLInstruction * pXMLInstruction,XFA_PacketType ePacketID)1021 void CXFA_DocumentParser::ParseInstruction(CXFA_Node* pXFANode,
1022                                            CFX_XMLInstruction* pXMLInstruction,
1023                                            XFA_PacketType ePacketID) {
1024   const std::vector<WideString>& target_data = pXMLInstruction->GetTargetData();
1025   if (pXMLInstruction->IsOriginalXFAVersion()) {
1026     if (target_data.size() > 1 &&
1027         (pXFANode->GetDocument()->RecognizeXFAVersionNumber(target_data[0]) !=
1028          XFA_VERSION_UNKNOWN) &&
1029         target_data[1].EqualsASCII("v2.7-scripting:1")) {
1030       pXFANode->GetDocument()->set_is_scripting();
1031     }
1032     return;
1033   }
1034   if (pXMLInstruction->IsAcrobat()) {
1035     if (target_data.size() > 1 && target_data[0].EqualsASCII("JavaScript") &&
1036         target_data[1].EqualsASCII("strictScoping")) {
1037       pXFANode->GetDocument()->set_is_strict_scoping();
1038     }
1039   }
1040 }
1041