xref: /aosp_15_r20/external/pdfium/xfa/fxfa/parser/xfa_utils.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_utils.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
10*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
11*3ac0a46fSAndroid Build Coastguard Worker 
12*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/cfx_memorystream.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_codepage.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_extension.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/widetext_buffer.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmlchardata.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmlelement.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmlnode.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmltext.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cjx_object.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_localemgr.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_measurement.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_ui.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_value.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_basic_data.h"
29*3ac0a46fSAndroid Build Coastguard Worker 
30*3ac0a46fSAndroid Build Coastguard Worker namespace {
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker const char kFormNS[] = "http://www.xfa.org/schema/xfa-form/";
33*3ac0a46fSAndroid Build Coastguard Worker 
ExportEncodeAttribute(const WideString & str)34*3ac0a46fSAndroid Build Coastguard Worker WideString ExportEncodeAttribute(const WideString& str) {
35*3ac0a46fSAndroid Build Coastguard Worker   WideString textBuf;
36*3ac0a46fSAndroid Build Coastguard Worker   textBuf.Reserve(str.GetLength());  // Result always at least as big as input.
37*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < str.GetLength(); i++) {
38*3ac0a46fSAndroid Build Coastguard Worker     switch (str[i]) {
39*3ac0a46fSAndroid Build Coastguard Worker       case '&':
40*3ac0a46fSAndroid Build Coastguard Worker         textBuf += L"&amp;";
41*3ac0a46fSAndroid Build Coastguard Worker         break;
42*3ac0a46fSAndroid Build Coastguard Worker       case '<':
43*3ac0a46fSAndroid Build Coastguard Worker         textBuf += L"&lt;";
44*3ac0a46fSAndroid Build Coastguard Worker         break;
45*3ac0a46fSAndroid Build Coastguard Worker       case '>':
46*3ac0a46fSAndroid Build Coastguard Worker         textBuf += L"&gt;";
47*3ac0a46fSAndroid Build Coastguard Worker         break;
48*3ac0a46fSAndroid Build Coastguard Worker       case '\'':
49*3ac0a46fSAndroid Build Coastguard Worker         textBuf += L"&apos;";
50*3ac0a46fSAndroid Build Coastguard Worker         break;
51*3ac0a46fSAndroid Build Coastguard Worker       case '\"':
52*3ac0a46fSAndroid Build Coastguard Worker         textBuf += L"&quot;";
53*3ac0a46fSAndroid Build Coastguard Worker         break;
54*3ac0a46fSAndroid Build Coastguard Worker       default:
55*3ac0a46fSAndroid Build Coastguard Worker         textBuf += str[i];
56*3ac0a46fSAndroid Build Coastguard Worker     }
57*3ac0a46fSAndroid Build Coastguard Worker   }
58*3ac0a46fSAndroid Build Coastguard Worker   return textBuf;
59*3ac0a46fSAndroid Build Coastguard Worker }
60*3ac0a46fSAndroid Build Coastguard Worker 
IsXMLValidChar(wchar_t ch)61*3ac0a46fSAndroid Build Coastguard Worker bool IsXMLValidChar(wchar_t ch) {
62*3ac0a46fSAndroid Build Coastguard Worker   return ch == 0x09 || ch == 0x0A || ch == 0x0D ||
63*3ac0a46fSAndroid Build Coastguard Worker          (ch >= 0x20 && ch <= 0xD7FF) || (ch >= 0xE000 && ch <= 0xFFFD);
64*3ac0a46fSAndroid Build Coastguard Worker }
65*3ac0a46fSAndroid Build Coastguard Worker 
ExportEncodeContent(const WideString & str)66*3ac0a46fSAndroid Build Coastguard Worker WideString ExportEncodeContent(const WideString& str) {
67*3ac0a46fSAndroid Build Coastguard Worker   WideTextBuffer textBuf;
68*3ac0a46fSAndroid Build Coastguard Worker   size_t iLen = str.GetLength();
69*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < iLen; i++) {
70*3ac0a46fSAndroid Build Coastguard Worker     wchar_t ch = str[i];
71*3ac0a46fSAndroid Build Coastguard Worker     if (!IsXMLValidChar(ch))
72*3ac0a46fSAndroid Build Coastguard Worker       continue;
73*3ac0a46fSAndroid Build Coastguard Worker 
74*3ac0a46fSAndroid Build Coastguard Worker     if (ch == '&') {
75*3ac0a46fSAndroid Build Coastguard Worker       textBuf << "&amp;";
76*3ac0a46fSAndroid Build Coastguard Worker     } else if (ch == '<') {
77*3ac0a46fSAndroid Build Coastguard Worker       textBuf << "&lt;";
78*3ac0a46fSAndroid Build Coastguard Worker     } else if (ch == '>') {
79*3ac0a46fSAndroid Build Coastguard Worker       textBuf << "&gt;";
80*3ac0a46fSAndroid Build Coastguard Worker     } else if (ch == '\'') {
81*3ac0a46fSAndroid Build Coastguard Worker       textBuf << "&apos;";
82*3ac0a46fSAndroid Build Coastguard Worker     } else if (ch == '\"') {
83*3ac0a46fSAndroid Build Coastguard Worker       textBuf << "&quot;";
84*3ac0a46fSAndroid Build Coastguard Worker     } else if (ch == ' ') {
85*3ac0a46fSAndroid Build Coastguard Worker       if (i && str[i - 1] != ' ') {
86*3ac0a46fSAndroid Build Coastguard Worker         textBuf.AppendChar(' ');
87*3ac0a46fSAndroid Build Coastguard Worker       } else {
88*3ac0a46fSAndroid Build Coastguard Worker         textBuf << "&#x20;";
89*3ac0a46fSAndroid Build Coastguard Worker       }
90*3ac0a46fSAndroid Build Coastguard Worker     } else {
91*3ac0a46fSAndroid Build Coastguard Worker       textBuf.AppendChar(str[i]);
92*3ac0a46fSAndroid Build Coastguard Worker     }
93*3ac0a46fSAndroid Build Coastguard Worker   }
94*3ac0a46fSAndroid Build Coastguard Worker   return textBuf.MakeString();
95*3ac0a46fSAndroid Build Coastguard Worker }
96*3ac0a46fSAndroid Build Coastguard Worker 
AttributeSaveInDataModel(CXFA_Node * pNode,XFA_Attribute eAttribute)97*3ac0a46fSAndroid Build Coastguard Worker bool AttributeSaveInDataModel(CXFA_Node* pNode, XFA_Attribute eAttribute) {
98*3ac0a46fSAndroid Build Coastguard Worker   bool bSaveInDataModel = false;
99*3ac0a46fSAndroid Build Coastguard Worker   if (pNode->GetElementType() != XFA_Element::Image)
100*3ac0a46fSAndroid Build Coastguard Worker     return bSaveInDataModel;
101*3ac0a46fSAndroid Build Coastguard Worker 
102*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pValueNode = pNode->GetParent();
103*3ac0a46fSAndroid Build Coastguard Worker   if (!pValueNode || pValueNode->GetElementType() != XFA_Element::Value)
104*3ac0a46fSAndroid Build Coastguard Worker     return bSaveInDataModel;
105*3ac0a46fSAndroid Build Coastguard Worker 
106*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pFieldNode = pValueNode->GetParent();
107*3ac0a46fSAndroid Build Coastguard Worker   if (pFieldNode && pFieldNode->GetBindData() &&
108*3ac0a46fSAndroid Build Coastguard Worker       eAttribute == XFA_Attribute::Href) {
109*3ac0a46fSAndroid Build Coastguard Worker     bSaveInDataModel = true;
110*3ac0a46fSAndroid Build Coastguard Worker   }
111*3ac0a46fSAndroid Build Coastguard Worker   return bSaveInDataModel;
112*3ac0a46fSAndroid Build Coastguard Worker }
113*3ac0a46fSAndroid Build Coastguard Worker 
ContentNodeNeedtoExport(CXFA_Node * pContentNode)114*3ac0a46fSAndroid Build Coastguard Worker bool ContentNodeNeedtoExport(CXFA_Node* pContentNode) {
115*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<WideString> wsContent =
116*3ac0a46fSAndroid Build Coastguard Worker       pContentNode->JSObject()->TryContent(false, false);
117*3ac0a46fSAndroid Build Coastguard Worker   if (!wsContent.has_value())
118*3ac0a46fSAndroid Build Coastguard Worker     return false;
119*3ac0a46fSAndroid Build Coastguard Worker 
120*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(pContentNode->IsContentNode());
121*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pParentNode = pContentNode->GetParent();
122*3ac0a46fSAndroid Build Coastguard Worker   if (!pParentNode || pParentNode->GetElementType() != XFA_Element::Value)
123*3ac0a46fSAndroid Build Coastguard Worker     return true;
124*3ac0a46fSAndroid Build Coastguard Worker 
125*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pGrandParentNode = pParentNode->GetParent();
126*3ac0a46fSAndroid Build Coastguard Worker   if (!pGrandParentNode || !pGrandParentNode->IsContainerNode())
127*3ac0a46fSAndroid Build Coastguard Worker     return true;
128*3ac0a46fSAndroid Build Coastguard Worker   if (!pGrandParentNode->GetBindData())
129*3ac0a46fSAndroid Build Coastguard Worker     return false;
130*3ac0a46fSAndroid Build Coastguard Worker   if (pGrandParentNode->GetFFWidgetType() == XFA_FFWidgetType::kPasswordEdit)
131*3ac0a46fSAndroid Build Coastguard Worker     return false;
132*3ac0a46fSAndroid Build Coastguard Worker   return true;
133*3ac0a46fSAndroid Build Coastguard Worker }
134*3ac0a46fSAndroid Build Coastguard Worker 
SaveAttribute(CXFA_Node * pNode,XFA_Attribute eName,WideStringView wsName,bool bProto)135*3ac0a46fSAndroid Build Coastguard Worker WideString SaveAttribute(CXFA_Node* pNode,
136*3ac0a46fSAndroid Build Coastguard Worker                          XFA_Attribute eName,
137*3ac0a46fSAndroid Build Coastguard Worker                          WideStringView wsName,
138*3ac0a46fSAndroid Build Coastguard Worker                          bool bProto) {
139*3ac0a46fSAndroid Build Coastguard Worker   if (!bProto && !pNode->JSObject()->HasAttribute(eName))
140*3ac0a46fSAndroid Build Coastguard Worker     return WideString();
141*3ac0a46fSAndroid Build Coastguard Worker 
142*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<WideString> value =
143*3ac0a46fSAndroid Build Coastguard Worker       pNode->JSObject()->TryAttribute(eName, false);
144*3ac0a46fSAndroid Build Coastguard Worker   if (!value.has_value())
145*3ac0a46fSAndroid Build Coastguard Worker     return WideString();
146*3ac0a46fSAndroid Build Coastguard Worker 
147*3ac0a46fSAndroid Build Coastguard Worker   WideString wsEncoded = ExportEncodeAttribute(value.value());
148*3ac0a46fSAndroid Build Coastguard Worker   return WideString{L" ", wsName, L"=\"", wsEncoded.AsStringView(), L"\""};
149*3ac0a46fSAndroid Build Coastguard Worker }
150*3ac0a46fSAndroid Build Coastguard Worker 
RegenerateFormFile_Changed(CXFA_Node * pNode,WideTextBuffer & buf,bool bSaveXML)151*3ac0a46fSAndroid Build Coastguard Worker void RegenerateFormFile_Changed(CXFA_Node* pNode,
152*3ac0a46fSAndroid Build Coastguard Worker                                 WideTextBuffer& buf,
153*3ac0a46fSAndroid Build Coastguard Worker                                 bool bSaveXML) {
154*3ac0a46fSAndroid Build Coastguard Worker   WideString wsAttrs;
155*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0;; ++i) {
156*3ac0a46fSAndroid Build Coastguard Worker     XFA_Attribute attr = pNode->GetAttribute(i);
157*3ac0a46fSAndroid Build Coastguard Worker     if (attr == XFA_Attribute::Unknown)
158*3ac0a46fSAndroid Build Coastguard Worker       break;
159*3ac0a46fSAndroid Build Coastguard Worker 
160*3ac0a46fSAndroid Build Coastguard Worker     if (attr == XFA_Attribute::Name ||
161*3ac0a46fSAndroid Build Coastguard Worker         (AttributeSaveInDataModel(pNode, attr) && !bSaveXML)) {
162*3ac0a46fSAndroid Build Coastguard Worker       continue;
163*3ac0a46fSAndroid Build Coastguard Worker     }
164*3ac0a46fSAndroid Build Coastguard Worker     WideString wsAttr = WideString::FromASCII(XFA_AttributeToName(attr));
165*3ac0a46fSAndroid Build Coastguard Worker     wsAttrs += SaveAttribute(pNode, attr, wsAttr.AsStringView(), bSaveXML);
166*3ac0a46fSAndroid Build Coastguard Worker   }
167*3ac0a46fSAndroid Build Coastguard Worker 
168*3ac0a46fSAndroid Build Coastguard Worker   WideString wsChildren;
169*3ac0a46fSAndroid Build Coastguard Worker   switch (pNode->GetObjectType()) {
170*3ac0a46fSAndroid Build Coastguard Worker     case XFA_ObjectType::ContentNode: {
171*3ac0a46fSAndroid Build Coastguard Worker       if (!bSaveXML && !ContentNodeNeedtoExport(pNode))
172*3ac0a46fSAndroid Build Coastguard Worker         break;
173*3ac0a46fSAndroid Build Coastguard Worker 
174*3ac0a46fSAndroid Build Coastguard Worker       CXFA_Node* pRawValueNode = pNode->GetFirstChild();
175*3ac0a46fSAndroid Build Coastguard Worker       while (pRawValueNode &&
176*3ac0a46fSAndroid Build Coastguard Worker              pRawValueNode->GetElementType() != XFA_Element::SharpxHTML &&
177*3ac0a46fSAndroid Build Coastguard Worker              pRawValueNode->GetElementType() != XFA_Element::Sharptext &&
178*3ac0a46fSAndroid Build Coastguard Worker              pRawValueNode->GetElementType() != XFA_Element::Sharpxml) {
179*3ac0a46fSAndroid Build Coastguard Worker         pRawValueNode = pRawValueNode->GetNextSibling();
180*3ac0a46fSAndroid Build Coastguard Worker       }
181*3ac0a46fSAndroid Build Coastguard Worker       if (!pRawValueNode)
182*3ac0a46fSAndroid Build Coastguard Worker         break;
183*3ac0a46fSAndroid Build Coastguard Worker 
184*3ac0a46fSAndroid Build Coastguard Worker       absl::optional<WideString> contentType =
185*3ac0a46fSAndroid Build Coastguard Worker           pNode->JSObject()->TryAttribute(XFA_Attribute::ContentType, false);
186*3ac0a46fSAndroid Build Coastguard Worker       if (pRawValueNode->GetElementType() == XFA_Element::SharpxHTML &&
187*3ac0a46fSAndroid Build Coastguard Worker           contentType.has_value() &&
188*3ac0a46fSAndroid Build Coastguard Worker           contentType.value().EqualsASCII("text/html")) {
189*3ac0a46fSAndroid Build Coastguard Worker         CFX_XMLNode* pExDataXML = pNode->GetXMLMappingNode();
190*3ac0a46fSAndroid Build Coastguard Worker         if (!pExDataXML)
191*3ac0a46fSAndroid Build Coastguard Worker           break;
192*3ac0a46fSAndroid Build Coastguard Worker 
193*3ac0a46fSAndroid Build Coastguard Worker         CFX_XMLNode* pRichTextXML = pExDataXML->GetFirstChild();
194*3ac0a46fSAndroid Build Coastguard Worker         if (!pRichTextXML)
195*3ac0a46fSAndroid Build Coastguard Worker           break;
196*3ac0a46fSAndroid Build Coastguard Worker 
197*3ac0a46fSAndroid Build Coastguard Worker         auto pMemStream = pdfium::MakeRetain<CFX_MemoryStream>();
198*3ac0a46fSAndroid Build Coastguard Worker         pRichTextXML->Save(pMemStream);
199*3ac0a46fSAndroid Build Coastguard Worker         wsChildren +=
200*3ac0a46fSAndroid Build Coastguard Worker             WideString::FromUTF8(ByteStringView(pMemStream->GetSpan()));
201*3ac0a46fSAndroid Build Coastguard Worker       } else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml &&
202*3ac0a46fSAndroid Build Coastguard Worker                  contentType.has_value() &&
203*3ac0a46fSAndroid Build Coastguard Worker                  contentType.value().EqualsASCII("text/xml")) {
204*3ac0a46fSAndroid Build Coastguard Worker         absl::optional<WideString> rawValue =
205*3ac0a46fSAndroid Build Coastguard Worker             pRawValueNode->JSObject()->TryAttribute(XFA_Attribute::Value,
206*3ac0a46fSAndroid Build Coastguard Worker                                                     false);
207*3ac0a46fSAndroid Build Coastguard Worker         if (!rawValue.has_value() || rawValue->IsEmpty())
208*3ac0a46fSAndroid Build Coastguard Worker           break;
209*3ac0a46fSAndroid Build Coastguard Worker 
210*3ac0a46fSAndroid Build Coastguard Worker         std::vector<WideString> wsSelTextArray =
211*3ac0a46fSAndroid Build Coastguard Worker             fxcrt::Split(rawValue.value(), L'\n');
212*3ac0a46fSAndroid Build Coastguard Worker 
213*3ac0a46fSAndroid Build Coastguard Worker         CXFA_Node* pParentNode = pNode->GetParent();
214*3ac0a46fSAndroid Build Coastguard Worker         CXFA_Node* pGrandparentNode = pParentNode->GetParent();
215*3ac0a46fSAndroid Build Coastguard Worker         WideString bodyTagName =
216*3ac0a46fSAndroid Build Coastguard Worker             pGrandparentNode->JSObject()->GetCData(XFA_Attribute::Name);
217*3ac0a46fSAndroid Build Coastguard Worker         if (bodyTagName.IsEmpty())
218*3ac0a46fSAndroid Build Coastguard Worker           bodyTagName = L"ListBox1";
219*3ac0a46fSAndroid Build Coastguard Worker 
220*3ac0a46fSAndroid Build Coastguard Worker         buf << "<" << bodyTagName << " xmlns=\"\">\n";
221*3ac0a46fSAndroid Build Coastguard Worker         for (const WideString& text : wsSelTextArray)
222*3ac0a46fSAndroid Build Coastguard Worker           buf << "<value>" << ExportEncodeContent(text) << "</value>\n";
223*3ac0a46fSAndroid Build Coastguard Worker         buf << "</" << bodyTagName << ">\n";
224*3ac0a46fSAndroid Build Coastguard Worker         wsChildren += buf.AsStringView();
225*3ac0a46fSAndroid Build Coastguard Worker         buf.Clear();
226*3ac0a46fSAndroid Build Coastguard Worker       } else {
227*3ac0a46fSAndroid Build Coastguard Worker         WideString wsValue =
228*3ac0a46fSAndroid Build Coastguard Worker             pRawValueNode->JSObject()->GetCData(XFA_Attribute::Value);
229*3ac0a46fSAndroid Build Coastguard Worker         wsChildren += ExportEncodeContent(wsValue);
230*3ac0a46fSAndroid Build Coastguard Worker       }
231*3ac0a46fSAndroid Build Coastguard Worker       break;
232*3ac0a46fSAndroid Build Coastguard Worker     }
233*3ac0a46fSAndroid Build Coastguard Worker     case XFA_ObjectType::TextNode:
234*3ac0a46fSAndroid Build Coastguard Worker     case XFA_ObjectType::NodeC:
235*3ac0a46fSAndroid Build Coastguard Worker     case XFA_ObjectType::NodeV: {
236*3ac0a46fSAndroid Build Coastguard Worker       WideString wsValue = pNode->JSObject()->GetCData(XFA_Attribute::Value);
237*3ac0a46fSAndroid Build Coastguard Worker       wsChildren += ExportEncodeContent(wsValue);
238*3ac0a46fSAndroid Build Coastguard Worker       break;
239*3ac0a46fSAndroid Build Coastguard Worker     }
240*3ac0a46fSAndroid Build Coastguard Worker     default:
241*3ac0a46fSAndroid Build Coastguard Worker       if (pNode->GetElementType() == XFA_Element::Items) {
242*3ac0a46fSAndroid Build Coastguard Worker         CXFA_Node* pTemplateNode = pNode->GetTemplateNodeIfExists();
243*3ac0a46fSAndroid Build Coastguard Worker         if (!pTemplateNode ||
244*3ac0a46fSAndroid Build Coastguard Worker             pTemplateNode->CountChildren(XFA_Element::Unknown, false) !=
245*3ac0a46fSAndroid Build Coastguard Worker                 pNode->CountChildren(XFA_Element::Unknown, false)) {
246*3ac0a46fSAndroid Build Coastguard Worker           bSaveXML = true;
247*3ac0a46fSAndroid Build Coastguard Worker         }
248*3ac0a46fSAndroid Build Coastguard Worker       }
249*3ac0a46fSAndroid Build Coastguard Worker       WideTextBuffer newBuf;
250*3ac0a46fSAndroid Build Coastguard Worker       CXFA_Node* pChildNode = pNode->GetFirstChild();
251*3ac0a46fSAndroid Build Coastguard Worker       while (pChildNode) {
252*3ac0a46fSAndroid Build Coastguard Worker         RegenerateFormFile_Changed(pChildNode, newBuf, bSaveXML);
253*3ac0a46fSAndroid Build Coastguard Worker         wsChildren += newBuf.AsStringView();
254*3ac0a46fSAndroid Build Coastguard Worker         newBuf.Clear();
255*3ac0a46fSAndroid Build Coastguard Worker         pChildNode = pChildNode->GetNextSibling();
256*3ac0a46fSAndroid Build Coastguard Worker       }
257*3ac0a46fSAndroid Build Coastguard Worker       if (!bSaveXML && !wsChildren.IsEmpty() &&
258*3ac0a46fSAndroid Build Coastguard Worker           pNode->GetElementType() == XFA_Element::Items) {
259*3ac0a46fSAndroid Build Coastguard Worker         wsChildren.clear();
260*3ac0a46fSAndroid Build Coastguard Worker         bSaveXML = true;
261*3ac0a46fSAndroid Build Coastguard Worker         CXFA_Node* pChild = pNode->GetFirstChild();
262*3ac0a46fSAndroid Build Coastguard Worker         while (pChild) {
263*3ac0a46fSAndroid Build Coastguard Worker           RegenerateFormFile_Changed(pChild, newBuf, bSaveXML);
264*3ac0a46fSAndroid Build Coastguard Worker           wsChildren += newBuf.AsStringView();
265*3ac0a46fSAndroid Build Coastguard Worker           newBuf.Clear();
266*3ac0a46fSAndroid Build Coastguard Worker           pChild = pChild->GetNextSibling();
267*3ac0a46fSAndroid Build Coastguard Worker         }
268*3ac0a46fSAndroid Build Coastguard Worker       }
269*3ac0a46fSAndroid Build Coastguard Worker       break;
270*3ac0a46fSAndroid Build Coastguard Worker   }
271*3ac0a46fSAndroid Build Coastguard Worker 
272*3ac0a46fSAndroid Build Coastguard Worker   if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() ||
273*3ac0a46fSAndroid Build Coastguard Worker       pNode->JSObject()->HasAttribute(XFA_Attribute::Name)) {
274*3ac0a46fSAndroid Build Coastguard Worker     WideString wsElement = WideString::FromASCII(pNode->GetClassName());
275*3ac0a46fSAndroid Build Coastguard Worker     buf << "<";
276*3ac0a46fSAndroid Build Coastguard Worker     buf << wsElement;
277*3ac0a46fSAndroid Build Coastguard Worker     buf << SaveAttribute(pNode, XFA_Attribute::Name, L"name", true);
278*3ac0a46fSAndroid Build Coastguard Worker     buf << wsAttrs;
279*3ac0a46fSAndroid Build Coastguard Worker     if (wsChildren.IsEmpty()) {
280*3ac0a46fSAndroid Build Coastguard Worker       buf << "/>\n";
281*3ac0a46fSAndroid Build Coastguard Worker     } else {
282*3ac0a46fSAndroid Build Coastguard Worker       buf << ">\n" << wsChildren << "</" << wsElement << ">\n";
283*3ac0a46fSAndroid Build Coastguard Worker     }
284*3ac0a46fSAndroid Build Coastguard Worker   }
285*3ac0a46fSAndroid Build Coastguard Worker }
286*3ac0a46fSAndroid Build Coastguard Worker 
RegenerateFormFile_Container(CXFA_Node * pNode,const RetainPtr<IFX_SeekableStream> & pStream,bool bSaveXML)287*3ac0a46fSAndroid Build Coastguard Worker void RegenerateFormFile_Container(CXFA_Node* pNode,
288*3ac0a46fSAndroid Build Coastguard Worker                                   const RetainPtr<IFX_SeekableStream>& pStream,
289*3ac0a46fSAndroid Build Coastguard Worker                                   bool bSaveXML) {
290*3ac0a46fSAndroid Build Coastguard Worker   XFA_Element eType = pNode->GetElementType();
291*3ac0a46fSAndroid Build Coastguard Worker   if (eType == XFA_Element::Field || eType == XFA_Element::Draw ||
292*3ac0a46fSAndroid Build Coastguard Worker       !pNode->IsContainerNode()) {
293*3ac0a46fSAndroid Build Coastguard Worker     WideTextBuffer buf;
294*3ac0a46fSAndroid Build Coastguard Worker     RegenerateFormFile_Changed(pNode, buf, bSaveXML);
295*3ac0a46fSAndroid Build Coastguard Worker     size_t nLen = buf.GetLength();
296*3ac0a46fSAndroid Build Coastguard Worker     if (nLen > 0)
297*3ac0a46fSAndroid Build Coastguard Worker       pStream->WriteString(buf.MakeString().ToUTF8().AsStringView());
298*3ac0a46fSAndroid Build Coastguard Worker     return;
299*3ac0a46fSAndroid Build Coastguard Worker   }
300*3ac0a46fSAndroid Build Coastguard Worker 
301*3ac0a46fSAndroid Build Coastguard Worker   WideString wsElement = WideString::FromASCII(pNode->GetClassName());
302*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString("<");
303*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString(wsElement.ToUTF8().AsStringView());
304*3ac0a46fSAndroid Build Coastguard Worker 
305*3ac0a46fSAndroid Build Coastguard Worker   WideString wsOutput =
306*3ac0a46fSAndroid Build Coastguard Worker       SaveAttribute(pNode, XFA_Attribute::Name, L"name", true);
307*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0;; ++i) {
308*3ac0a46fSAndroid Build Coastguard Worker     XFA_Attribute attr = pNode->GetAttribute(i);
309*3ac0a46fSAndroid Build Coastguard Worker     if (attr == XFA_Attribute::Unknown)
310*3ac0a46fSAndroid Build Coastguard Worker       break;
311*3ac0a46fSAndroid Build Coastguard Worker     if (attr == XFA_Attribute::Name)
312*3ac0a46fSAndroid Build Coastguard Worker       continue;
313*3ac0a46fSAndroid Build Coastguard Worker 
314*3ac0a46fSAndroid Build Coastguard Worker     WideString wsAttr = WideString::FromASCII(XFA_AttributeToName(attr));
315*3ac0a46fSAndroid Build Coastguard Worker     wsOutput += SaveAttribute(pNode, attr, wsAttr.AsStringView(), false);
316*3ac0a46fSAndroid Build Coastguard Worker   }
317*3ac0a46fSAndroid Build Coastguard Worker 
318*3ac0a46fSAndroid Build Coastguard Worker   if (!wsOutput.IsEmpty())
319*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString(wsOutput.ToUTF8().AsStringView());
320*3ac0a46fSAndroid Build Coastguard Worker 
321*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pChildNode = pNode->GetFirstChild();
322*3ac0a46fSAndroid Build Coastguard Worker   if (!pChildNode) {
323*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString(" />\n");
324*3ac0a46fSAndroid Build Coastguard Worker     return;
325*3ac0a46fSAndroid Build Coastguard Worker   }
326*3ac0a46fSAndroid Build Coastguard Worker 
327*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString(">\n");
328*3ac0a46fSAndroid Build Coastguard Worker   while (pChildNode) {
329*3ac0a46fSAndroid Build Coastguard Worker     RegenerateFormFile_Container(pChildNode, pStream, bSaveXML);
330*3ac0a46fSAndroid Build Coastguard Worker     pChildNode = pChildNode->GetNextSibling();
331*3ac0a46fSAndroid Build Coastguard Worker   }
332*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString("</");
333*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString(wsElement.ToUTF8().AsStringView());
334*3ac0a46fSAndroid Build Coastguard Worker   pStream->WriteString(">\n");
335*3ac0a46fSAndroid Build Coastguard Worker }
336*3ac0a46fSAndroid Build Coastguard Worker 
RecognizeXFAVersionNumber(CXFA_Node * pTemplateRoot)337*3ac0a46fSAndroid Build Coastguard Worker WideString RecognizeXFAVersionNumber(CXFA_Node* pTemplateRoot) {
338*3ac0a46fSAndroid Build Coastguard Worker   if (!pTemplateRoot)
339*3ac0a46fSAndroid Build Coastguard Worker     return WideString();
340*3ac0a46fSAndroid Build Coastguard Worker 
341*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<WideString> templateNS =
342*3ac0a46fSAndroid Build Coastguard Worker       pTemplateRoot->JSObject()->TryNamespace();
343*3ac0a46fSAndroid Build Coastguard Worker   if (!templateNS.has_value())
344*3ac0a46fSAndroid Build Coastguard Worker     return WideString();
345*3ac0a46fSAndroid Build Coastguard Worker 
346*3ac0a46fSAndroid Build Coastguard Worker   XFA_VERSION eVersion =
347*3ac0a46fSAndroid Build Coastguard Worker       pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(
348*3ac0a46fSAndroid Build Coastguard Worker           templateNS.value());
349*3ac0a46fSAndroid Build Coastguard Worker   if (eVersion == XFA_VERSION_UNKNOWN)
350*3ac0a46fSAndroid Build Coastguard Worker     eVersion = XFA_VERSION_DEFAULT;
351*3ac0a46fSAndroid Build Coastguard Worker 
352*3ac0a46fSAndroid Build Coastguard Worker   return WideString::Format(L"%i.%i", eVersion / 100, eVersion % 100);
353*3ac0a46fSAndroid Build Coastguard Worker }
354*3ac0a46fSAndroid Build Coastguard Worker 
355*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
356*3ac0a46fSAndroid Build Coastguard Worker 
XFA_GetLocaleValue(const CXFA_Node * pNode)357*3ac0a46fSAndroid Build Coastguard Worker CXFA_LocaleValue XFA_GetLocaleValue(const CXFA_Node* pNode) {
358*3ac0a46fSAndroid Build Coastguard Worker   const auto* pNodeValue =
359*3ac0a46fSAndroid Build Coastguard Worker       pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
360*3ac0a46fSAndroid Build Coastguard Worker   if (!pNodeValue)
361*3ac0a46fSAndroid Build Coastguard Worker     return CXFA_LocaleValue();
362*3ac0a46fSAndroid Build Coastguard Worker 
363*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
364*3ac0a46fSAndroid Build Coastguard Worker   if (!pValueChild)
365*3ac0a46fSAndroid Build Coastguard Worker     return CXFA_LocaleValue();
366*3ac0a46fSAndroid Build Coastguard Worker 
367*3ac0a46fSAndroid Build Coastguard Worker   return CXFA_LocaleValue(XFA_GetLocaleValueType(pValueChild->GetElementType()),
368*3ac0a46fSAndroid Build Coastguard Worker                           pNode->GetRawValue(),
369*3ac0a46fSAndroid Build Coastguard Worker                           pNode->GetDocument()->GetLocaleMgr());
370*3ac0a46fSAndroid Build Coastguard Worker }
371*3ac0a46fSAndroid Build Coastguard Worker 
XFA_GetLocaleValueType(XFA_Element element)372*3ac0a46fSAndroid Build Coastguard Worker CXFA_LocaleValue::ValueType XFA_GetLocaleValueType(XFA_Element element) {
373*3ac0a46fSAndroid Build Coastguard Worker   switch (element) {
374*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Decimal:
375*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kDecimal;
376*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Float:
377*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kFloat;
378*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Date:
379*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kDate;
380*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Time:
381*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kTime;
382*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::DateTime:
383*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kDateTime;
384*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Boolean:
385*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kBoolean;
386*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Integer:
387*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kInteger;
388*3ac0a46fSAndroid Build Coastguard Worker     case XFA_Element::Text:
389*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kText;
390*3ac0a46fSAndroid Build Coastguard Worker     default:
391*3ac0a46fSAndroid Build Coastguard Worker       return CXFA_LocaleValue::ValueType::kNull;
392*3ac0a46fSAndroid Build Coastguard Worker   }
393*3ac0a46fSAndroid Build Coastguard Worker }
394*3ac0a46fSAndroid Build Coastguard Worker 
XFA_FDEExtension_ResolveNamespaceQualifier(CFX_XMLElement * pNode,const WideString & wsQualifier,WideString * wsNamespaceURI)395*3ac0a46fSAndroid Build Coastguard Worker bool XFA_FDEExtension_ResolveNamespaceQualifier(CFX_XMLElement* pNode,
396*3ac0a46fSAndroid Build Coastguard Worker                                                 const WideString& wsQualifier,
397*3ac0a46fSAndroid Build Coastguard Worker                                                 WideString* wsNamespaceURI) {
398*3ac0a46fSAndroid Build Coastguard Worker   if (!pNode)
399*3ac0a46fSAndroid Build Coastguard Worker     return false;
400*3ac0a46fSAndroid Build Coastguard Worker 
401*3ac0a46fSAndroid Build Coastguard Worker   CFX_XMLNode* pFakeRoot = pNode->GetRoot();
402*3ac0a46fSAndroid Build Coastguard Worker   WideString wsNSAttribute;
403*3ac0a46fSAndroid Build Coastguard Worker   bool bRet = false;
404*3ac0a46fSAndroid Build Coastguard Worker   if (wsQualifier.IsEmpty()) {
405*3ac0a46fSAndroid Build Coastguard Worker     wsNSAttribute = L"xmlns";
406*3ac0a46fSAndroid Build Coastguard Worker     bRet = true;
407*3ac0a46fSAndroid Build Coastguard Worker   } else {
408*3ac0a46fSAndroid Build Coastguard Worker     wsNSAttribute = L"xmlns:" + wsQualifier;
409*3ac0a46fSAndroid Build Coastguard Worker   }
410*3ac0a46fSAndroid Build Coastguard Worker   for (CFX_XMLNode* pParent = pNode; pParent != pFakeRoot;
411*3ac0a46fSAndroid Build Coastguard Worker        pParent = pParent->GetParent()) {
412*3ac0a46fSAndroid Build Coastguard Worker     CFX_XMLElement* pElement = ToXMLElement(pParent);
413*3ac0a46fSAndroid Build Coastguard Worker     if (pElement && pElement->HasAttribute(wsNSAttribute)) {
414*3ac0a46fSAndroid Build Coastguard Worker       *wsNamespaceURI = pElement->GetAttribute(wsNSAttribute);
415*3ac0a46fSAndroid Build Coastguard Worker       return true;
416*3ac0a46fSAndroid Build Coastguard Worker     }
417*3ac0a46fSAndroid Build Coastguard Worker   }
418*3ac0a46fSAndroid Build Coastguard Worker   wsNamespaceURI->clear();
419*3ac0a46fSAndroid Build Coastguard Worker   return bRet;
420*3ac0a46fSAndroid Build Coastguard Worker }
421*3ac0a46fSAndroid Build Coastguard Worker 
XFA_DataExporter_DealWithDataGroupNode(CXFA_Node * pDataNode)422*3ac0a46fSAndroid Build Coastguard Worker void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode) {
423*3ac0a46fSAndroid Build Coastguard Worker   if (!pDataNode || pDataNode->GetElementType() == XFA_Element::DataValue)
424*3ac0a46fSAndroid Build Coastguard Worker     return;
425*3ac0a46fSAndroid Build Coastguard Worker 
426*3ac0a46fSAndroid Build Coastguard Worker   int32_t iChildNum = 0;
427*3ac0a46fSAndroid Build Coastguard Worker   for (CXFA_Node* pChildNode = pDataNode->GetFirstChild(); pChildNode;
428*3ac0a46fSAndroid Build Coastguard Worker        pChildNode = pChildNode->GetNextSibling()) {
429*3ac0a46fSAndroid Build Coastguard Worker     iChildNum++;
430*3ac0a46fSAndroid Build Coastguard Worker     XFA_DataExporter_DealWithDataGroupNode(pChildNode);
431*3ac0a46fSAndroid Build Coastguard Worker   }
432*3ac0a46fSAndroid Build Coastguard Worker 
433*3ac0a46fSAndroid Build Coastguard Worker   if (pDataNode->GetElementType() != XFA_Element::DataGroup)
434*3ac0a46fSAndroid Build Coastguard Worker     return;
435*3ac0a46fSAndroid Build Coastguard Worker 
436*3ac0a46fSAndroid Build Coastguard Worker   CFX_XMLElement* pElement = ToXMLElement(pDataNode->GetXMLMappingNode());
437*3ac0a46fSAndroid Build Coastguard Worker   if (iChildNum > 0) {
438*3ac0a46fSAndroid Build Coastguard Worker     pElement->RemoveAttribute(L"xfa:dataNode");
439*3ac0a46fSAndroid Build Coastguard Worker     return;
440*3ac0a46fSAndroid Build Coastguard Worker   }
441*3ac0a46fSAndroid Build Coastguard Worker   pElement->SetAttribute(L"xfa:dataNode", L"dataGroup");
442*3ac0a46fSAndroid Build Coastguard Worker }
443*3ac0a46fSAndroid Build Coastguard Worker 
XFA_DataExporter_RegenerateFormFile(CXFA_Node * pNode,const RetainPtr<IFX_SeekableStream> & pStream,bool bSaveXML)444*3ac0a46fSAndroid Build Coastguard Worker void XFA_DataExporter_RegenerateFormFile(
445*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Node* pNode,
446*3ac0a46fSAndroid Build Coastguard Worker     const RetainPtr<IFX_SeekableStream>& pStream,
447*3ac0a46fSAndroid Build Coastguard Worker     bool bSaveXML) {
448*3ac0a46fSAndroid Build Coastguard Worker   if (pNode->IsModelNode()) {
449*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString("<form xmlns=\"");
450*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString(kFormNS);
451*3ac0a46fSAndroid Build Coastguard Worker 
452*3ac0a46fSAndroid Build Coastguard Worker     WideString wsVersionNumber = RecognizeXFAVersionNumber(
453*3ac0a46fSAndroid Build Coastguard Worker         ToNode(pNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Template)));
454*3ac0a46fSAndroid Build Coastguard Worker     if (wsVersionNumber.IsEmpty())
455*3ac0a46fSAndroid Build Coastguard Worker       wsVersionNumber = L"2.8";
456*3ac0a46fSAndroid Build Coastguard Worker 
457*3ac0a46fSAndroid Build Coastguard Worker     wsVersionNumber += L"/\">\n";
458*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString(wsVersionNumber.ToUTF8().AsStringView());
459*3ac0a46fSAndroid Build Coastguard Worker 
460*3ac0a46fSAndroid Build Coastguard Worker     CXFA_Node* pChildNode = pNode->GetFirstChild();
461*3ac0a46fSAndroid Build Coastguard Worker     while (pChildNode) {
462*3ac0a46fSAndroid Build Coastguard Worker       RegenerateFormFile_Container(pChildNode, pStream, false);
463*3ac0a46fSAndroid Build Coastguard Worker       pChildNode = pChildNode->GetNextSibling();
464*3ac0a46fSAndroid Build Coastguard Worker     }
465*3ac0a46fSAndroid Build Coastguard Worker     pStream->WriteString("</form>\n");
466*3ac0a46fSAndroid Build Coastguard Worker   } else {
467*3ac0a46fSAndroid Build Coastguard Worker     RegenerateFormFile_Container(pNode, pStream, bSaveXML);
468*3ac0a46fSAndroid Build Coastguard Worker   }
469*3ac0a46fSAndroid Build Coastguard Worker }
470*3ac0a46fSAndroid Build Coastguard Worker 
XFA_FieldIsMultiListBox(const CXFA_Node * pFieldNode)471*3ac0a46fSAndroid Build Coastguard Worker bool XFA_FieldIsMultiListBox(const CXFA_Node* pFieldNode) {
472*3ac0a46fSAndroid Build Coastguard Worker   if (!pFieldNode)
473*3ac0a46fSAndroid Build Coastguard Worker     return false;
474*3ac0a46fSAndroid Build Coastguard Worker 
475*3ac0a46fSAndroid Build Coastguard Worker   const auto* pUIChild =
476*3ac0a46fSAndroid Build Coastguard Worker       pFieldNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
477*3ac0a46fSAndroid Build Coastguard Worker   if (!pUIChild)
478*3ac0a46fSAndroid Build Coastguard Worker     return false;
479*3ac0a46fSAndroid Build Coastguard Worker 
480*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pFirstChild = pUIChild->GetFirstChild();
481*3ac0a46fSAndroid Build Coastguard Worker   if (!pFirstChild ||
482*3ac0a46fSAndroid Build Coastguard Worker       pFirstChild->GetElementType() != XFA_Element::ChoiceList) {
483*3ac0a46fSAndroid Build Coastguard Worker     return false;
484*3ac0a46fSAndroid Build Coastguard Worker   }
485*3ac0a46fSAndroid Build Coastguard Worker 
486*3ac0a46fSAndroid Build Coastguard Worker   return pFirstChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
487*3ac0a46fSAndroid Build Coastguard Worker          XFA_AttributeValue::MultiSelect;
488*3ac0a46fSAndroid Build Coastguard Worker }
489*3ac0a46fSAndroid Build Coastguard Worker 
XFA_MapRotation(int32_t nRotation)490*3ac0a46fSAndroid Build Coastguard Worker int32_t XFA_MapRotation(int32_t nRotation) {
491*3ac0a46fSAndroid Build Coastguard Worker   nRotation = nRotation % 360;
492*3ac0a46fSAndroid Build Coastguard Worker   nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
493*3ac0a46fSAndroid Build Coastguard Worker   return nRotation;
494*3ac0a46fSAndroid Build Coastguard Worker }
495*3ac0a46fSAndroid Build Coastguard Worker 
XFA_EventErrorAccumulate(XFA_EventError * pAcc,XFA_EventError eNew)496*3ac0a46fSAndroid Build Coastguard Worker void XFA_EventErrorAccumulate(XFA_EventError* pAcc, XFA_EventError eNew) {
497*3ac0a46fSAndroid Build Coastguard Worker   if (*pAcc == XFA_EventError::kNotExist || eNew == XFA_EventError::kError)
498*3ac0a46fSAndroid Build Coastguard Worker     *pAcc = eNew;
499*3ac0a46fSAndroid Build Coastguard Worker }
500