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