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_node.h"
8 
9 #include <algorithm>
10 #include <map>
11 #include <memory>
12 #include <set>
13 #include <utility>
14 #include <vector>
15 
16 #include "core/fxcrt/autorestorer.h"
17 #include "core/fxcrt/cfx_readonlymemorystream.h"
18 #include "core/fxcrt/fx_codepage.h"
19 #include "core/fxcrt/fx_extension.h"
20 #include "core/fxcrt/xml/cfx_xmldocument.h"
21 #include "core/fxcrt/xml/cfx_xmlelement.h"
22 #include "core/fxcrt/xml/cfx_xmlnode.h"
23 #include "core/fxcrt/xml/cfx_xmltext.h"
24 #include "core/fxge/dib/cfx_dibitmap.h"
25 #include "core/fxge/fx_font.h"
26 #include "fxjs/xfa/cfxjse_engine.h"
27 #include "fxjs/xfa/cfxjse_value.h"
28 #include "fxjs/xfa/cjx_node.h"
29 #include "third_party/base/compiler_specific.h"
30 #include "third_party/base/logging.h"
31 #include "third_party/base/ptr_util.h"
32 #include "third_party/base/span.h"
33 #include "third_party/base/stl_util.h"
34 #include "xfa/fde/cfde_textout.h"
35 #include "xfa/fgas/crt/cfgas_decimal.h"
36 #include "xfa/fgas/crt/locale_iface.h"
37 #include "xfa/fgas/font/cfgas_fontmgr.h"
38 #include "xfa/fgas/font/cfgas_gefont.h"
39 #include "xfa/fxfa/cxfa_eventparam.h"
40 #include "xfa/fxfa/cxfa_ffapp.h"
41 #include "xfa/fxfa/cxfa_ffdocview.h"
42 #include "xfa/fxfa/cxfa_ffnotify.h"
43 #include "xfa/fxfa/cxfa_fontmgr.h"
44 #include "xfa/fxfa/cxfa_textprovider.h"
45 #include "xfa/fxfa/parser/cxfa_accessiblecontent.h"
46 #include "xfa/fxfa/parser/cxfa_acrobat.h"
47 #include "xfa/fxfa/parser/cxfa_acrobat7.h"
48 #include "xfa/fxfa/parser/cxfa_adbe_jsconsole.h"
49 #include "xfa/fxfa/parser/cxfa_adbe_jsdebugger.h"
50 #include "xfa/fxfa/parser/cxfa_addsilentprint.h"
51 #include "xfa/fxfa/parser/cxfa_addviewerpreferences.h"
52 #include "xfa/fxfa/parser/cxfa_adjustdata.h"
53 #include "xfa/fxfa/parser/cxfa_adobeextensionlevel.h"
54 #include "xfa/fxfa/parser/cxfa_agent.h"
55 #include "xfa/fxfa/parser/cxfa_alwaysembed.h"
56 #include "xfa/fxfa/parser/cxfa_amd.h"
57 #include "xfa/fxfa/parser/cxfa_appearancefilter.h"
58 #include "xfa/fxfa/parser/cxfa_arc.h"
59 #include "xfa/fxfa/parser/cxfa_area.h"
60 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
61 #include "xfa/fxfa/parser/cxfa_assist.h"
62 #include "xfa/fxfa/parser/cxfa_attachnodelist.h"
63 #include "xfa/fxfa/parser/cxfa_attributes.h"
64 #include "xfa/fxfa/parser/cxfa_autosave.h"
65 #include "xfa/fxfa/parser/cxfa_barcode.h"
66 #include "xfa/fxfa/parser/cxfa_base.h"
67 #include "xfa/fxfa/parser/cxfa_batchoutput.h"
68 #include "xfa/fxfa/parser/cxfa_behavioroverride.h"
69 #include "xfa/fxfa/parser/cxfa_bind.h"
70 #include "xfa/fxfa/parser/cxfa_binditems.h"
71 #include "xfa/fxfa/parser/cxfa_bookend.h"
72 #include "xfa/fxfa/parser/cxfa_boolean.h"
73 #include "xfa/fxfa/parser/cxfa_border.h"
74 #include "xfa/fxfa/parser/cxfa_break.h"
75 #include "xfa/fxfa/parser/cxfa_breakafter.h"
76 #include "xfa/fxfa/parser/cxfa_breakbefore.h"
77 #include "xfa/fxfa/parser/cxfa_button.h"
78 #include "xfa/fxfa/parser/cxfa_cache.h"
79 #include "xfa/fxfa/parser/cxfa_calculate.h"
80 #include "xfa/fxfa/parser/cxfa_calendarsymbols.h"
81 #include "xfa/fxfa/parser/cxfa_caption.h"
82 #include "xfa/fxfa/parser/cxfa_certificate.h"
83 #include "xfa/fxfa/parser/cxfa_certificates.h"
84 #include "xfa/fxfa/parser/cxfa_change.h"
85 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
86 #include "xfa/fxfa/parser/cxfa_choicelist.h"
87 #include "xfa/fxfa/parser/cxfa_color.h"
88 #include "xfa/fxfa/parser/cxfa_comb.h"
89 #include "xfa/fxfa/parser/cxfa_command.h"
90 #include "xfa/fxfa/parser/cxfa_common.h"
91 #include "xfa/fxfa/parser/cxfa_compress.h"
92 #include "xfa/fxfa/parser/cxfa_compression.h"
93 #include "xfa/fxfa/parser/cxfa_compresslogicalstructure.h"
94 #include "xfa/fxfa/parser/cxfa_compressobjectstream.h"
95 #include "xfa/fxfa/parser/cxfa_config.h"
96 #include "xfa/fxfa/parser/cxfa_conformance.h"
97 #include "xfa/fxfa/parser/cxfa_connect.h"
98 #include "xfa/fxfa/parser/cxfa_connectionset.h"
99 #include "xfa/fxfa/parser/cxfa_connectstring.h"
100 #include "xfa/fxfa/parser/cxfa_contentarea.h"
101 #include "xfa/fxfa/parser/cxfa_contentcopy.h"
102 #include "xfa/fxfa/parser/cxfa_copies.h"
103 #include "xfa/fxfa/parser/cxfa_corner.h"
104 #include "xfa/fxfa/parser/cxfa_creator.h"
105 #include "xfa/fxfa/parser/cxfa_currencysymbol.h"
106 #include "xfa/fxfa/parser/cxfa_currencysymbols.h"
107 #include "xfa/fxfa/parser/cxfa_currentpage.h"
108 #include "xfa/fxfa/parser/cxfa_data.h"
109 #include "xfa/fxfa/parser/cxfa_datagroup.h"
110 #include "xfa/fxfa/parser/cxfa_datamodel.h"
111 #include "xfa/fxfa/parser/cxfa_datavalue.h"
112 #include "xfa/fxfa/parser/cxfa_date.h"
113 #include "xfa/fxfa/parser/cxfa_datepattern.h"
114 #include "xfa/fxfa/parser/cxfa_datepatterns.h"
115 #include "xfa/fxfa/parser/cxfa_datetime.h"
116 #include "xfa/fxfa/parser/cxfa_datetimeedit.h"
117 #include "xfa/fxfa/parser/cxfa_datetimesymbols.h"
118 #include "xfa/fxfa/parser/cxfa_day.h"
119 #include "xfa/fxfa/parser/cxfa_daynames.h"
120 #include "xfa/fxfa/parser/cxfa_debug.h"
121 #include "xfa/fxfa/parser/cxfa_decimal.h"
122 #include "xfa/fxfa/parser/cxfa_defaulttypeface.h"
123 #include "xfa/fxfa/parser/cxfa_defaultui.h"
124 #include "xfa/fxfa/parser/cxfa_delete.h"
125 #include "xfa/fxfa/parser/cxfa_delta.h"
126 #include "xfa/fxfa/parser/cxfa_deltas.h"
127 #include "xfa/fxfa/parser/cxfa_desc.h"
128 #include "xfa/fxfa/parser/cxfa_destination.h"
129 #include "xfa/fxfa/parser/cxfa_digestmethod.h"
130 #include "xfa/fxfa/parser/cxfa_digestmethods.h"
131 #include "xfa/fxfa/parser/cxfa_document.h"
132 #include "xfa/fxfa/parser/cxfa_document_parser.h"
133 #include "xfa/fxfa/parser/cxfa_documentassembly.h"
134 #include "xfa/fxfa/parser/cxfa_draw.h"
135 #include "xfa/fxfa/parser/cxfa_driver.h"
136 #include "xfa/fxfa/parser/cxfa_dsigdata.h"
137 #include "xfa/fxfa/parser/cxfa_duplexoption.h"
138 #include "xfa/fxfa/parser/cxfa_dynamicrender.h"
139 #include "xfa/fxfa/parser/cxfa_edge.h"
140 #include "xfa/fxfa/parser/cxfa_effectiveinputpolicy.h"
141 #include "xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h"
142 #include "xfa/fxfa/parser/cxfa_embed.h"
143 #include "xfa/fxfa/parser/cxfa_encoding.h"
144 #include "xfa/fxfa/parser/cxfa_encodings.h"
145 #include "xfa/fxfa/parser/cxfa_encrypt.h"
146 #include "xfa/fxfa/parser/cxfa_encryption.h"
147 #include "xfa/fxfa/parser/cxfa_encryptionlevel.h"
148 #include "xfa/fxfa/parser/cxfa_encryptionmethod.h"
149 #include "xfa/fxfa/parser/cxfa_encryptionmethods.h"
150 #include "xfa/fxfa/parser/cxfa_enforce.h"
151 #include "xfa/fxfa/parser/cxfa_equate.h"
152 #include "xfa/fxfa/parser/cxfa_equaterange.h"
153 #include "xfa/fxfa/parser/cxfa_era.h"
154 #include "xfa/fxfa/parser/cxfa_eranames.h"
155 #include "xfa/fxfa/parser/cxfa_event.h"
156 #include "xfa/fxfa/parser/cxfa_exclgroup.h"
157 #include "xfa/fxfa/parser/cxfa_exclude.h"
158 #include "xfa/fxfa/parser/cxfa_excludens.h"
159 #include "xfa/fxfa/parser/cxfa_exdata.h"
160 #include "xfa/fxfa/parser/cxfa_execute.h"
161 #include "xfa/fxfa/parser/cxfa_exobject.h"
162 #include "xfa/fxfa/parser/cxfa_extras.h"
163 #include "xfa/fxfa/parser/cxfa_field.h"
164 #include "xfa/fxfa/parser/cxfa_fill.h"
165 #include "xfa/fxfa/parser/cxfa_filter.h"
166 #include "xfa/fxfa/parser/cxfa_fliplabel.h"
167 #include "xfa/fxfa/parser/cxfa_float.h"
168 #include "xfa/fxfa/parser/cxfa_font.h"
169 #include "xfa/fxfa/parser/cxfa_fontinfo.h"
170 #include "xfa/fxfa/parser/cxfa_form.h"
171 #include "xfa/fxfa/parser/cxfa_format.h"
172 #include "xfa/fxfa/parser/cxfa_formfieldfilling.h"
173 #include "xfa/fxfa/parser/cxfa_groupparent.h"
174 #include "xfa/fxfa/parser/cxfa_handler.h"
175 #include "xfa/fxfa/parser/cxfa_hyphenation.h"
176 #include "xfa/fxfa/parser/cxfa_ifempty.h"
177 #include "xfa/fxfa/parser/cxfa_image.h"
178 #include "xfa/fxfa/parser/cxfa_imageedit.h"
179 #include "xfa/fxfa/parser/cxfa_includexdpcontent.h"
180 #include "xfa/fxfa/parser/cxfa_incrementalload.h"
181 #include "xfa/fxfa/parser/cxfa_incrementalmerge.h"
182 #include "xfa/fxfa/parser/cxfa_insert.h"
183 #include "xfa/fxfa/parser/cxfa_instancemanager.h"
184 #include "xfa/fxfa/parser/cxfa_integer.h"
185 #include "xfa/fxfa/parser/cxfa_interactive.h"
186 #include "xfa/fxfa/parser/cxfa_issuers.h"
187 #include "xfa/fxfa/parser/cxfa_items.h"
188 #include "xfa/fxfa/parser/cxfa_jog.h"
189 #include "xfa/fxfa/parser/cxfa_keep.h"
190 #include "xfa/fxfa/parser/cxfa_keyusage.h"
191 #include "xfa/fxfa/parser/cxfa_labelprinter.h"
192 #include "xfa/fxfa/parser/cxfa_layout.h"
193 #include "xfa/fxfa/parser/cxfa_level.h"
194 #include "xfa/fxfa/parser/cxfa_line.h"
195 #include "xfa/fxfa/parser/cxfa_linear.h"
196 #include "xfa/fxfa/parser/cxfa_linearized.h"
197 #include "xfa/fxfa/parser/cxfa_locale.h"
198 #include "xfa/fxfa/parser/cxfa_localeset.h"
199 #include "xfa/fxfa/parser/cxfa_localevalue.h"
200 #include "xfa/fxfa/parser/cxfa_lockdocument.h"
201 #include "xfa/fxfa/parser/cxfa_log.h"
202 #include "xfa/fxfa/parser/cxfa_manifest.h"
203 #include "xfa/fxfa/parser/cxfa_map.h"
204 #include "xfa/fxfa/parser/cxfa_margin.h"
205 #include "xfa/fxfa/parser/cxfa_mdp.h"
206 #include "xfa/fxfa/parser/cxfa_measurement.h"
207 #include "xfa/fxfa/parser/cxfa_medium.h"
208 #include "xfa/fxfa/parser/cxfa_mediuminfo.h"
209 #include "xfa/fxfa/parser/cxfa_meridiem.h"
210 #include "xfa/fxfa/parser/cxfa_meridiemnames.h"
211 #include "xfa/fxfa/parser/cxfa_message.h"
212 #include "xfa/fxfa/parser/cxfa_messaging.h"
213 #include "xfa/fxfa/parser/cxfa_mode.h"
214 #include "xfa/fxfa/parser/cxfa_modifyannots.h"
215 #include "xfa/fxfa/parser/cxfa_month.h"
216 #include "xfa/fxfa/parser/cxfa_monthnames.h"
217 #include "xfa/fxfa/parser/cxfa_msgid.h"
218 #include "xfa/fxfa/parser/cxfa_nameattr.h"
219 #include "xfa/fxfa/parser/cxfa_neverembed.h"
220 #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
221 #include "xfa/fxfa/parser/cxfa_numberofcopies.h"
222 #include "xfa/fxfa/parser/cxfa_numberpattern.h"
223 #include "xfa/fxfa/parser/cxfa_numberpatterns.h"
224 #include "xfa/fxfa/parser/cxfa_numbersymbol.h"
225 #include "xfa/fxfa/parser/cxfa_numbersymbols.h"
226 #include "xfa/fxfa/parser/cxfa_numericedit.h"
227 #include "xfa/fxfa/parser/cxfa_occur.h"
228 #include "xfa/fxfa/parser/cxfa_oid.h"
229 #include "xfa/fxfa/parser/cxfa_oids.h"
230 #include "xfa/fxfa/parser/cxfa_openaction.h"
231 #include "xfa/fxfa/parser/cxfa_operation.h"
232 #include "xfa/fxfa/parser/cxfa_output.h"
233 #include "xfa/fxfa/parser/cxfa_outputbin.h"
234 #include "xfa/fxfa/parser/cxfa_outputxsl.h"
235 #include "xfa/fxfa/parser/cxfa_overflow.h"
236 #include "xfa/fxfa/parser/cxfa_overprint.h"
237 #include "xfa/fxfa/parser/cxfa_packet.h"
238 #include "xfa/fxfa/parser/cxfa_packets.h"
239 #include "xfa/fxfa/parser/cxfa_pagearea.h"
240 #include "xfa/fxfa/parser/cxfa_pageoffset.h"
241 #include "xfa/fxfa/parser/cxfa_pagerange.h"
242 #include "xfa/fxfa/parser/cxfa_pageset.h"
243 #include "xfa/fxfa/parser/cxfa_pagination.h"
244 #include "xfa/fxfa/parser/cxfa_paginationoverride.h"
245 #include "xfa/fxfa/parser/cxfa_para.h"
246 #include "xfa/fxfa/parser/cxfa_part.h"
247 #include "xfa/fxfa/parser/cxfa_password.h"
248 #include "xfa/fxfa/parser/cxfa_passwordedit.h"
249 #include "xfa/fxfa/parser/cxfa_pattern.h"
250 #include "xfa/fxfa/parser/cxfa_pcl.h"
251 #include "xfa/fxfa/parser/cxfa_pdf.h"
252 #include "xfa/fxfa/parser/cxfa_pdfa.h"
253 #include "xfa/fxfa/parser/cxfa_permissions.h"
254 #include "xfa/fxfa/parser/cxfa_picktraybypdfsize.h"
255 #include "xfa/fxfa/parser/cxfa_picture.h"
256 #include "xfa/fxfa/parser/cxfa_plaintextmetadata.h"
257 #include "xfa/fxfa/parser/cxfa_presence.h"
258 #include "xfa/fxfa/parser/cxfa_present.h"
259 #include "xfa/fxfa/parser/cxfa_print.h"
260 #include "xfa/fxfa/parser/cxfa_printername.h"
261 #include "xfa/fxfa/parser/cxfa_printhighquality.h"
262 #include "xfa/fxfa/parser/cxfa_printscaling.h"
263 #include "xfa/fxfa/parser/cxfa_producer.h"
264 #include "xfa/fxfa/parser/cxfa_proto.h"
265 #include "xfa/fxfa/parser/cxfa_ps.h"
266 #include "xfa/fxfa/parser/cxfa_psmap.h"
267 #include "xfa/fxfa/parser/cxfa_query.h"
268 #include "xfa/fxfa/parser/cxfa_radial.h"
269 #include "xfa/fxfa/parser/cxfa_range.h"
270 #include "xfa/fxfa/parser/cxfa_reason.h"
271 #include "xfa/fxfa/parser/cxfa_reasons.h"
272 #include "xfa/fxfa/parser/cxfa_record.h"
273 #include "xfa/fxfa/parser/cxfa_recordset.h"
274 #include "xfa/fxfa/parser/cxfa_rectangle.h"
275 #include "xfa/fxfa/parser/cxfa_ref.h"
276 #include "xfa/fxfa/parser/cxfa_relevant.h"
277 #include "xfa/fxfa/parser/cxfa_rename.h"
278 #include "xfa/fxfa/parser/cxfa_renderpolicy.h"
279 #include "xfa/fxfa/parser/cxfa_rootelement.h"
280 #include "xfa/fxfa/parser/cxfa_runscripts.h"
281 #include "xfa/fxfa/parser/cxfa_script.h"
282 #include "xfa/fxfa/parser/cxfa_scriptmodel.h"
283 #include "xfa/fxfa/parser/cxfa_select.h"
284 #include "xfa/fxfa/parser/cxfa_setproperty.h"
285 #include "xfa/fxfa/parser/cxfa_severity.h"
286 #include "xfa/fxfa/parser/cxfa_sharptext.h"
287 #include "xfa/fxfa/parser/cxfa_sharpxhtml.h"
288 #include "xfa/fxfa/parser/cxfa_sharpxml.h"
289 #include "xfa/fxfa/parser/cxfa_signature.h"
290 #include "xfa/fxfa/parser/cxfa_signatureproperties.h"
291 #include "xfa/fxfa/parser/cxfa_signdata.h"
292 #include "xfa/fxfa/parser/cxfa_signing.h"
293 #include "xfa/fxfa/parser/cxfa_silentprint.h"
294 #include "xfa/fxfa/parser/cxfa_soapaction.h"
295 #include "xfa/fxfa/parser/cxfa_soapaddress.h"
296 #include "xfa/fxfa/parser/cxfa_solid.h"
297 #include "xfa/fxfa/parser/cxfa_source.h"
298 #include "xfa/fxfa/parser/cxfa_sourceset.h"
299 #include "xfa/fxfa/parser/cxfa_speak.h"
300 #include "xfa/fxfa/parser/cxfa_staple.h"
301 #include "xfa/fxfa/parser/cxfa_startnode.h"
302 #include "xfa/fxfa/parser/cxfa_startpage.h"
303 #include "xfa/fxfa/parser/cxfa_stipple.h"
304 #include "xfa/fxfa/parser/cxfa_stroke.h"
305 #include "xfa/fxfa/parser/cxfa_subform.h"
306 #include "xfa/fxfa/parser/cxfa_subformset.h"
307 #include "xfa/fxfa/parser/cxfa_subjectdn.h"
308 #include "xfa/fxfa/parser/cxfa_subjectdns.h"
309 #include "xfa/fxfa/parser/cxfa_submit.h"
310 #include "xfa/fxfa/parser/cxfa_submitformat.h"
311 #include "xfa/fxfa/parser/cxfa_submiturl.h"
312 #include "xfa/fxfa/parser/cxfa_subsetbelow.h"
313 #include "xfa/fxfa/parser/cxfa_suppressbanner.h"
314 #include "xfa/fxfa/parser/cxfa_tagged.h"
315 #include "xfa/fxfa/parser/cxfa_template.h"
316 #include "xfa/fxfa/parser/cxfa_templatecache.h"
317 #include "xfa/fxfa/parser/cxfa_text.h"
318 #include "xfa/fxfa/parser/cxfa_textedit.h"
319 #include "xfa/fxfa/parser/cxfa_threshold.h"
320 #include "xfa/fxfa/parser/cxfa_time.h"
321 #include "xfa/fxfa/parser/cxfa_timepattern.h"
322 #include "xfa/fxfa/parser/cxfa_timepatterns.h"
323 #include "xfa/fxfa/parser/cxfa_timestamp.h"
324 #include "xfa/fxfa/parser/cxfa_to.h"
325 #include "xfa/fxfa/parser/cxfa_tooltip.h"
326 #include "xfa/fxfa/parser/cxfa_trace.h"
327 #include "xfa/fxfa/parser/cxfa_transform.h"
328 #include "xfa/fxfa/parser/cxfa_traversal.h"
329 #include "xfa/fxfa/parser/cxfa_traverse.h"
330 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h"
331 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfanode.h"
332 #include "xfa/fxfa/parser/cxfa_type.h"
333 #include "xfa/fxfa/parser/cxfa_typeface.h"
334 #include "xfa/fxfa/parser/cxfa_typefaces.h"
335 #include "xfa/fxfa/parser/cxfa_ui.h"
336 #include "xfa/fxfa/parser/cxfa_update.h"
337 #include "xfa/fxfa/parser/cxfa_uri.h"
338 #include "xfa/fxfa/parser/cxfa_user.h"
339 #include "xfa/fxfa/parser/cxfa_validate.h"
340 #include "xfa/fxfa/parser/cxfa_validateapprovalsignatures.h"
341 #include "xfa/fxfa/parser/cxfa_validationmessaging.h"
342 #include "xfa/fxfa/parser/cxfa_value.h"
343 #include "xfa/fxfa/parser/cxfa_variables.h"
344 #include "xfa/fxfa/parser/cxfa_version.h"
345 #include "xfa/fxfa/parser/cxfa_versioncontrol.h"
346 #include "xfa/fxfa/parser/cxfa_viewerpreferences.h"
347 #include "xfa/fxfa/parser/cxfa_webclient.h"
348 #include "xfa/fxfa/parser/cxfa_whitespace.h"
349 #include "xfa/fxfa/parser/cxfa_window.h"
350 #include "xfa/fxfa/parser/cxfa_wsdladdress.h"
351 #include "xfa/fxfa/parser/cxfa_wsdlconnection.h"
352 #include "xfa/fxfa/parser/cxfa_xdc.h"
353 #include "xfa/fxfa/parser/cxfa_xdp.h"
354 #include "xfa/fxfa/parser/cxfa_xfa.h"
355 #include "xfa/fxfa/parser/cxfa_xmlconnection.h"
356 #include "xfa/fxfa/parser/cxfa_xsdconnection.h"
357 #include "xfa/fxfa/parser/cxfa_xsl.h"
358 #include "xfa/fxfa/parser/cxfa_zpl.h"
359 #include "xfa/fxfa/parser/xfa_basic_data.h"
360 #include "xfa/fxfa/parser/xfa_utils.h"
361 
362 class CXFA_FieldLayoutData;
363 class CXFA_ImageEditData;
364 class CXFA_ImageLayoutData;
365 class CXFA_TextEditData;
366 class CXFA_TextLayoutData;
367 
368 namespace {
369 
370 constexpr uint8_t kMaxExecuteRecursion = 2;
371 
372 constexpr uint8_t g_inv_base64[128] = {
373     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
374     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
375     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
376     255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
377     255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
378     10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
379     25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
380     34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
381     49,  50,  51,  255, 255, 255, 255, 255,
382 };
383 
GetInvBase64(uint8_t x)384 inline uint8_t GetInvBase64(uint8_t x) {
385   return (x & 128) == 0 ? g_inv_base64[x] : 255;
386 }
387 
XFA_RemoveBase64Whitespace(pdfium::span<const uint8_t> spStr)388 std::vector<uint8_t> XFA_RemoveBase64Whitespace(
389     pdfium::span<const uint8_t> spStr) {
390   std::vector<uint8_t> result;
391   result.reserve(spStr.size());
392   for (uint8_t ch : spStr) {
393     if (GetInvBase64(ch) != 255 || ch == '=')
394       result.push_back(ch);
395   }
396   return result;
397 }
398 
XFA_Base64Decode(const ByteString & bsStr)399 std::vector<uint8_t> XFA_Base64Decode(const ByteString& bsStr) {
400   std::vector<uint8_t> result;
401   if (bsStr.IsEmpty())
402     return result;
403 
404   std::vector<uint8_t> buffer = XFA_RemoveBase64Whitespace(bsStr.raw_span());
405   result.reserve(3 * (buffer.size() / 4));
406 
407   uint32_t dwLimb = 0;
408   for (size_t i = 0; i + 3 < buffer.size(); i += 4) {
409     if (buffer[i] == '=' || buffer[i + 1] == '=' || buffer[i + 2] == '=' ||
410         buffer[i + 3] == '=') {
411       if (buffer[i] == '=' || buffer[i + 1] == '=') {
412         break;
413       }
414       if (buffer[i + 2] == '=') {
415         dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 6) |
416                  ((uint32_t)g_inv_base64[buffer[i + 1]]);
417         result.push_back((uint8_t)(dwLimb >> 4) & 0xFF);
418       } else {
419         dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 12) |
420                  ((uint32_t)g_inv_base64[buffer[i + 1]] << 6) |
421                  ((uint32_t)g_inv_base64[buffer[i + 2]]);
422         result.push_back((uint8_t)(dwLimb >> 10) & 0xFF);
423         result.push_back((uint8_t)(dwLimb >> 2) & 0xFF);
424       }
425     } else {
426       dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 18) |
427                ((uint32_t)g_inv_base64[buffer[i + 1]] << 12) |
428                ((uint32_t)g_inv_base64[buffer[i + 2]] << 6) |
429                ((uint32_t)g_inv_base64[buffer[i + 3]]);
430       result.push_back((uint8_t)(dwLimb >> 16) & 0xff);
431       result.push_back((uint8_t)(dwLimb >> 8) & 0xff);
432       result.push_back((uint8_t)(dwLimb)&0xff);
433     }
434   }
435   return result;
436 }
437 
XFA_GetImageType(const WideString & wsType)438 FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
439   WideString wsContentType(wsType);
440   if (wsContentType.EqualsASCIINoCase("image/jpg"))
441     return FXCODEC_IMAGE_JPG;
442 
443 #ifdef PDF_ENABLE_XFA_BMP
444   if (wsContentType.EqualsASCIINoCase("image/bmp"))
445     return FXCODEC_IMAGE_BMP;
446 #endif  // PDF_ENABLE_XFA_BMP
447 
448 #ifdef PDF_ENABLE_XFA_GIF
449   if (wsContentType.EqualsASCIINoCase("image/gif"))
450     return FXCODEC_IMAGE_GIF;
451 #endif  // PDF_ENABLE_XFA_GIF
452 
453 #ifdef PDF_ENABLE_XFA_PNG
454   if (wsContentType.EqualsASCIINoCase("image/png"))
455     return FXCODEC_IMAGE_PNG;
456 #endif  // PDF_ENABLE_XFA_PNG
457 
458 #ifdef PDF_ENABLE_XFA_TIFF
459   if (wsContentType.EqualsASCII("image/tif"))
460     return FXCODEC_IMAGE_TIFF;
461 #endif  // PDF_ENABLE_XFA_TIFF
462 
463   return FXCODEC_IMAGE_UNKNOWN;
464 }
465 
XFA_LoadImageData(CXFA_FFDoc * pDoc,CXFA_Image * pImage,bool & bNameImage,int32_t & iImageXDpi,int32_t & iImageYDpi)466 RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
467                                           CXFA_Image* pImage,
468                                           bool& bNameImage,
469                                           int32_t& iImageXDpi,
470                                           int32_t& iImageYDpi) {
471   WideString wsHref = pImage->GetHref();
472   WideString wsImage = pImage->GetContent();
473   if (wsHref.IsEmpty() && wsImage.IsEmpty())
474     return nullptr;
475 
476   FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
477   ByteString bsData;  // Must outlive |pImageFileRead|.
478   std::vector<uint8_t> buffer;  // Must outlive |pImageFileRead|.
479   RetainPtr<IFX_SeekableReadStream> pImageFileRead;
480   if (wsImage.GetLength() > 0) {
481     XFA_AttributeValue iEncoding = pImage->GetTransferEncoding();
482     if (iEncoding == XFA_AttributeValue::Base64) {
483       bsData = wsImage.ToUTF8();
484       buffer = XFA_Base64Decode(bsData);
485       if (!buffer.empty())
486         pImageFileRead = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(buffer);
487     } else {
488       bsData = wsImage.ToDefANSI();
489       pImageFileRead =
490           pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(bsData.raw_span());
491     }
492   } else {
493     WideString wsURL = wsHref;
494     if (!(wsURL.First(7).EqualsASCII("http://") ||
495           wsURL.First(6).EqualsASCII("ftp://"))) {
496       RetainPtr<CFX_DIBitmap> pBitmap =
497           pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
498       if (pBitmap) {
499         bNameImage = true;
500         return pBitmap;
501       }
502     }
503     pImageFileRead = pDoc->GetDocEnvironment()->OpenLinkedFile(pDoc, wsURL);
504   }
505   if (!pImageFileRead)
506     return nullptr;
507 
508   bNameImage = false;
509   RetainPtr<CFX_DIBitmap> pBitmap =
510       XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
511   return pBitmap;
512 }
513 
SplitDateTime(const WideString & wsDateTime,WideString & wsDate,WideString & wsTime)514 bool SplitDateTime(const WideString& wsDateTime,
515                    WideString& wsDate,
516                    WideString& wsTime) {
517   wsDate.clear();
518   wsTime.clear();
519   if (wsDateTime.IsEmpty())
520     return false;
521 
522   auto nSplitIndex = wsDateTime.Find('T');
523   if (!nSplitIndex.has_value())
524     nSplitIndex = wsDateTime.Find(' ');
525   if (!nSplitIndex.has_value())
526     return false;
527 
528   wsDate = wsDateTime.First(nSplitIndex.value());
529   if (!wsDate.IsEmpty()) {
530     if (!std::any_of(wsDate.begin(), wsDate.end(),
531                      [](wchar_t c) { return FXSYS_IsDecimalDigit(c); })) {
532       return false;
533     }
534   }
535   wsTime = wsDateTime.Last(wsDateTime.GetLength() - nSplitIndex.value() - 1);
536   if (!wsTime.IsEmpty()) {
537     if (!std::any_of(wsTime.begin(), wsTime.end(),
538                      [](wchar_t c) { return FXSYS_IsDecimalDigit(c); })) {
539       return false;
540     }
541   }
542   return true;
543 }
544 
NodesSortedByDocumentIdx(const std::set<CXFA_Node * > & rgNodeSet)545 std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
546     const std::set<CXFA_Node*>& rgNodeSet) {
547   if (rgNodeSet.empty())
548     return std::vector<CXFA_Node*>();
549 
550   std::vector<CXFA_Node*> rgNodeArray;
551   CXFA_Node* pCommonParent = (*rgNodeSet.begin())->GetParent();
552   for (CXFA_Node* pNode = pCommonParent->GetFirstChild(); pNode;
553        pNode = pNode->GetNextSibling()) {
554     if (pdfium::ContainsValue(rgNodeSet, pNode))
555       rgNodeArray.push_back(pNode);
556   }
557   return rgNodeArray;
558 }
559 
560 using CXFA_NodeSetPair = std::pair<std::set<CXFA_Node*>, std::set<CXFA_Node*>>;
561 using CXFA_NodeSetPairMap =
562     std::map<uint32_t, std::unique_ptr<CXFA_NodeSetPair>>;
563 using CXFA_NodeSetPairMapMap =
564     std::map<CXFA_Node*, std::unique_ptr<CXFA_NodeSetPairMap>>;
565 
NodeSetPairForNode(CXFA_Node * pNode,CXFA_NodeSetPairMapMap * pMap)566 CXFA_NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode,
567                                      CXFA_NodeSetPairMapMap* pMap) {
568   CXFA_Node* pParentNode = pNode->GetParent();
569   uint32_t dwNameHash = pNode->GetNameHash();
570   if (!pParentNode || !dwNameHash)
571     return nullptr;
572 
573   if (!(*pMap)[pParentNode])
574     (*pMap)[pParentNode] = pdfium::MakeUnique<CXFA_NodeSetPairMap>();
575 
576   CXFA_NodeSetPairMap* pNodeSetPairMap = (*pMap)[pParentNode].get();
577   if (!(*pNodeSetPairMap)[dwNameHash])
578     (*pNodeSetPairMap)[dwNameHash] = pdfium::MakeUnique<CXFA_NodeSetPair>();
579 
580   return (*pNodeSetPairMap)[dwNameHash].get();
581 }
582 
ReorderDataNodes(const std::set<CXFA_Node * > & sSet1,const std::set<CXFA_Node * > & sSet2,bool bInsertBefore)583 void ReorderDataNodes(const std::set<CXFA_Node*>& sSet1,
584                       const std::set<CXFA_Node*>& sSet2,
585                       bool bInsertBefore) {
586   CXFA_NodeSetPairMapMap rgMap;
587   for (CXFA_Node* pNode : sSet1) {
588     CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
589     if (pNodeSetPair)
590       pNodeSetPair->first.insert(pNode);
591   }
592   for (CXFA_Node* pNode : sSet2) {
593     CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
594     if (pNodeSetPair) {
595       if (pdfium::ContainsValue(pNodeSetPair->first, pNode))
596         pNodeSetPair->first.erase(pNode);
597       else
598         pNodeSetPair->second.insert(pNode);
599     }
600   }
601   for (const auto& iter1 : rgMap) {
602     CXFA_NodeSetPairMap* pNodeSetPairMap = iter1.second.get();
603     if (!pNodeSetPairMap)
604       continue;
605 
606     for (const auto& iter2 : *pNodeSetPairMap) {
607       CXFA_NodeSetPair* pNodeSetPair = iter2.second.get();
608       if (!pNodeSetPair)
609         continue;
610       if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) {
611         std::vector<CXFA_Node*> rgNodeArray1 =
612             NodesSortedByDocumentIdx(pNodeSetPair->first);
613         std::vector<CXFA_Node*> rgNodeArray2 =
614             NodesSortedByDocumentIdx(pNodeSetPair->second);
615         CXFA_Node* pParentNode = nullptr;
616         CXFA_Node* pBeforeNode = nullptr;
617         if (bInsertBefore) {
618           pBeforeNode = rgNodeArray2.front();
619           pParentNode = pBeforeNode->GetParent();
620         } else {
621           CXFA_Node* pLastNode = rgNodeArray2.back();
622           pParentNode = pLastNode->GetParent();
623           pBeforeNode = pLastNode->GetNextSibling();
624         }
625         for (auto* pCurNode : rgNodeArray1) {
626           pParentNode->RemoveChildAndNotify(pCurNode, true);
627           pParentNode->InsertChildAndNotify(pCurNode, pBeforeNode);
628         }
629       }
630     }
631     pNodeSetPairMap->clear();
632   }
633 }
634 
GetEdgeThickness(const std::vector<CXFA_Stroke * > & strokes,bool b3DStyle,int32_t nIndex)635 float GetEdgeThickness(const std::vector<CXFA_Stroke*>& strokes,
636                        bool b3DStyle,
637                        int32_t nIndex) {
638   float fThickness = 0.0f;
639   CXFA_Stroke* stroke = strokes[nIndex * 2 + 1];
640   if (stroke->IsVisible()) {
641     if (nIndex == 0)
642       fThickness += 2.5f;
643 
644     fThickness += stroke->GetThickness() * (b3DStyle ? 4 : 2);
645   }
646   return fThickness;
647 }
648 
FormatNumStr(const WideString & wsValue,LocaleIface * pLocale)649 WideString FormatNumStr(const WideString& wsValue, LocaleIface* pLocale) {
650   if (wsValue.IsEmpty())
651     return WideString();
652 
653   WideString wsSrcNum = wsValue;
654   WideString wsGroupSymbol = pLocale->GetGroupingSymbol();
655   bool bNeg = false;
656   if (wsSrcNum[0] == '-') {
657     bNeg = true;
658     wsSrcNum.Delete(0, 1);
659   }
660 
661   auto dot_index = wsSrcNum.Find('.');
662   dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
663 
664   if (dot_index.value() < 1)
665     return WideString();
666 
667   size_t nPos = dot_index.value() % 3;
668   WideString wsOutput;
669   for (size_t i = 0; i < dot_index.value(); i++) {
670     if (i % 3 == nPos && i != 0)
671       wsOutput += wsGroupSymbol;
672 
673     wsOutput += wsSrcNum[i];
674   }
675   if (dot_index.value() < wsSrcNum.GetLength()) {
676     wsOutput += pLocale->GetDecimalSymbol();
677     wsOutput += wsSrcNum.Last(wsSrcNum.GetLength() - dot_index.value() - 1);
678   }
679   if (bNeg)
680     return pLocale->GetMinusSymbol() + wsOutput;
681 
682   return wsOutput;
683 }
684 
685 CXFA_Node* FindFirstSiblingNamedInList(CXFA_Node* parent,
686                                        uint32_t dwNameHash,
687                                        uint32_t dwFilter);
688 CXFA_Node* FindFirstSiblingOfClassInList(CXFA_Node* parent,
689                                          XFA_Element element,
690                                          uint32_t dwFilter);
691 
FindFirstSiblingNamed(CXFA_Node * parent,uint32_t dwNameHash)692 CXFA_Node* FindFirstSiblingNamed(CXFA_Node* parent, uint32_t dwNameHash) {
693   CXFA_Node* result = FindFirstSiblingNamedInList(parent, dwNameHash,
694                                                   XFA_NODEFILTER_Properties);
695   if (result)
696     return result;
697 
698   return FindFirstSiblingNamedInList(parent, dwNameHash,
699                                      XFA_NODEFILTER_Children);
700 }
701 
FindFirstSiblingNamedInList(CXFA_Node * parent,uint32_t dwNameHash,uint32_t dwFilter)702 CXFA_Node* FindFirstSiblingNamedInList(CXFA_Node* parent,
703                                        uint32_t dwNameHash,
704                                        uint32_t dwFilter) {
705   for (CXFA_Node* child : parent->GetNodeListWithFilter(dwFilter)) {
706     if (child->GetNameHash() == dwNameHash)
707       return child;
708 
709     CXFA_Node* result = FindFirstSiblingNamed(child, dwNameHash);
710     if (result)
711       return result;
712   }
713   return nullptr;
714 }
715 
FindFirstSiblingOfClass(CXFA_Node * parent,XFA_Element element)716 CXFA_Node* FindFirstSiblingOfClass(CXFA_Node* parent, XFA_Element element) {
717   CXFA_Node* result =
718       FindFirstSiblingOfClassInList(parent, element, XFA_NODEFILTER_Properties);
719   if (result)
720     return result;
721 
722   return FindFirstSiblingOfClassInList(parent, element,
723                                        XFA_NODEFILTER_Children);
724 }
725 
FindFirstSiblingOfClassInList(CXFA_Node * parent,XFA_Element element,uint32_t dwFilter)726 CXFA_Node* FindFirstSiblingOfClassInList(CXFA_Node* parent,
727                                          XFA_Element element,
728                                          uint32_t dwFilter) {
729   for (CXFA_Node* child : parent->GetNodeListWithFilter(dwFilter)) {
730     if (child->GetElementType() == element)
731       return child;
732 
733     CXFA_Node* result = FindFirstSiblingOfClass(child, element);
734     if (result)
735       return result;
736   }
737   return nullptr;
738 }
739 
GetNameExpressionSinglePath(CXFA_Node * pNode)740 WideString GetNameExpressionSinglePath(CXFA_Node* pNode) {
741   const bool bIsProperty = pNode->IsProperty();
742   const bool bIsClassIndex =
743       pNode->IsUnnamed() ||
744       (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
745   const wchar_t* pszFormat;
746   WideString ws;
747   if (bIsClassIndex) {
748     pszFormat = L"#%ls[%zu]";
749     ws = WideString::FromASCII(pNode->GetClassName());
750   } else {
751     pszFormat = L"%ls[%zu]";
752     ws = pNode->JSObject()->GetCData(XFA_Attribute::Name);
753     ws.Replace(L".", L"\\.");
754   }
755 
756   return WideString::Format(pszFormat, ws.c_str(),
757                             pNode->GetIndex(bIsProperty, bIsClassIndex));
758 }
759 
TraverseSiblings(CXFA_Node * parent,uint32_t dwNameHash,std::vector<CXFA_Node * > * pSiblings,bool bIsClassName,bool bIsFindProperty)760 void TraverseSiblings(CXFA_Node* parent,
761                       uint32_t dwNameHash,
762                       std::vector<CXFA_Node*>* pSiblings,
763                       bool bIsClassName,
764                       bool bIsFindProperty) {
765   ASSERT(parent);
766   ASSERT(pSiblings);
767 
768   if (bIsFindProperty) {
769     for (CXFA_Node* child :
770          parent->GetNodeListWithFilter(XFA_NODEFILTER_Properties)) {
771       if (bIsClassName) {
772         if (child->GetClassHashCode() == dwNameHash)
773           pSiblings->push_back(child);
774       } else {
775         if (child->GetNameHash() == dwNameHash) {
776           if (child->GetElementType() != XFA_Element::PageSet &&
777               child->GetElementType() != XFA_Element::Extras &&
778               child->GetElementType() != XFA_Element::Items) {
779             pSiblings->push_back(child);
780           }
781         }
782       }
783       if (child->IsUnnamed() &&
784           child->GetElementType() == XFA_Element::PageSet) {
785         TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
786       }
787     }
788     if (!pSiblings->empty())
789       return;
790   }
791   for (CXFA_Node* child :
792        parent->GetNodeListWithFilter(XFA_NODEFILTER_Children)) {
793     if (child->GetElementType() == XFA_Element::Variables)
794       continue;
795 
796     if (bIsClassName) {
797       if (child->GetClassHashCode() == dwNameHash)
798         pSiblings->push_back(child);
799     } else {
800       if (child->GetNameHash() == dwNameHash)
801         pSiblings->push_back(child);
802     }
803 
804     if (child->IsTransparent() &&
805         child->GetElementType() != XFA_Element::PageSet) {
806       TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
807     }
808   }
809 }
810 
811 }  // namespace
812 
813 class CXFA_WidgetLayoutData {
814  public:
815   CXFA_WidgetLayoutData() = default;
816   virtual ~CXFA_WidgetLayoutData() = default;
817 
AsFieldLayoutData()818   virtual CXFA_FieldLayoutData* AsFieldLayoutData() { return nullptr; }
AsImageLayoutData()819   virtual CXFA_ImageLayoutData* AsImageLayoutData() { return nullptr; }
AsTextLayoutData()820   virtual CXFA_TextLayoutData* AsTextLayoutData() { return nullptr; }
821 
822   float m_fWidgetHeight = -1.0f;
823 };
824 
825 class CXFA_TextLayoutData final : public CXFA_WidgetLayoutData {
826  public:
827   CXFA_TextLayoutData() = default;
828   ~CXFA_TextLayoutData() override = default;
829 
AsTextLayoutData()830   CXFA_TextLayoutData* AsTextLayoutData() override { return this; }
831 
GetTextLayout() const832   CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
GetTextProvider() const833   CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
834 
LoadText(CXFA_FFDoc * doc,CXFA_Node * pNode)835   void LoadText(CXFA_FFDoc* doc, CXFA_Node* pNode) {
836     if (m_pTextLayout)
837       return;
838 
839     m_pTextProvider =
840         pdfium::MakeUnique<CXFA_TextProvider>(pNode, XFA_TEXTPROVIDERTYPE_Text);
841     m_pTextLayout =
842         pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pTextProvider.get());
843   }
844 
845  private:
846   std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
847   std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
848 };
849 
850 class CXFA_ImageLayoutData final : public CXFA_WidgetLayoutData {
851  public:
852   CXFA_ImageLayoutData() = default;
853   ~CXFA_ImageLayoutData() override = default;
854 
AsImageLayoutData()855   CXFA_ImageLayoutData* AsImageLayoutData() override { return this; }
856 
LoadImageData(CXFA_FFDoc * doc,CXFA_Node * pNode)857   bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
858     if (m_pDIBitmap)
859       return true;
860 
861     CXFA_Value* value = pNode->GetFormValueIfExists();
862     if (!value)
863       return false;
864 
865     CXFA_Image* image = value->GetImageIfExists();
866     if (!image)
867       return false;
868 
869     pNode->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
870                                            m_iImageXDpi, m_iImageYDpi));
871     return !!m_pDIBitmap;
872   }
873 
874   bool m_bNamedImage = false;
875   int32_t m_iImageXDpi = 0;
876   int32_t m_iImageYDpi = 0;
877   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
878 };
879 
880 class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
881  public:
882   CXFA_FieldLayoutData() = default;
883   ~CXFA_FieldLayoutData() override = default;
884 
AsFieldLayoutData()885   CXFA_FieldLayoutData* AsFieldLayoutData() override { return this; }
886 
AsImageEditData()887   virtual CXFA_ImageEditData* AsImageEditData() { return nullptr; }
AsTextEditData()888   virtual CXFA_TextEditData* AsTextEditData() { return nullptr; }
889 
LoadCaption(CXFA_FFDoc * doc,CXFA_Node * pNode)890   bool LoadCaption(CXFA_FFDoc* doc, CXFA_Node* pNode) {
891     if (m_pCapTextLayout)
892       return true;
893     CXFA_Caption* caption = pNode->GetCaptionIfExists();
894     if (!caption || caption->IsHidden())
895       return false;
896 
897     m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
898         pNode, XFA_TEXTPROVIDERTYPE_Caption);
899     m_pCapTextLayout =
900         pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
901     return true;
902   }
903 
904   std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
905   std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
906   std::unique_ptr<CFDE_TextOut> m_pTextOut;
907   std::vector<float> m_FieldSplitArray;
908 };
909 
910 class CXFA_TextEditData final : public CXFA_FieldLayoutData {
911  public:
912   CXFA_TextEditData() = default;
913   ~CXFA_TextEditData() override = default;
914 
AsTextEditData()915   CXFA_TextEditData* AsTextEditData() override { return this; }
916 };
917 
918 class CXFA_ImageEditData final : public CXFA_FieldLayoutData {
919  public:
920   CXFA_ImageEditData() = default;
921   ~CXFA_ImageEditData() override = default;
922 
AsImageEditData()923   CXFA_ImageEditData* AsImageEditData() override { return this; }
924 
LoadImageData(CXFA_FFDoc * doc,CXFA_Node * pNode)925   bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
926     if (m_pDIBitmap)
927       return true;
928 
929     CXFA_Value* value = pNode->GetFormValueIfExists();
930     if (!value)
931       return false;
932 
933     CXFA_Image* image = value->GetImageIfExists();
934     if (!image)
935       return false;
936 
937     pNode->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
938                                                m_iImageXDpi, m_iImageYDpi));
939     return !!m_pDIBitmap;
940   }
941 
942   bool m_bNamedImage = false;
943   int32_t m_iImageXDpi = 0;
944   int32_t m_iImageYDpi = 0;
945   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
946 };
947 
CXFA_Node(CXFA_Document * pDoc,XFA_PacketType ePacket,uint32_t validPackets,XFA_ObjectType oType,XFA_Element eType,pdfium::span<const PropertyData> properties,pdfium::span<const AttributeData> attributes,std::unique_ptr<CJX_Object> js_object)948 CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
949                      XFA_PacketType ePacket,
950                      uint32_t validPackets,
951                      XFA_ObjectType oType,
952                      XFA_Element eType,
953                      pdfium::span<const PropertyData> properties,
954                      pdfium::span<const AttributeData> attributes,
955                      std::unique_ptr<CJX_Object> js_object)
956     : CXFA_Object(pDoc, oType, eType, std::move(js_object)),
957       m_Properties(properties),
958       m_Attributes(attributes),
959       m_ValidPackets(validPackets),
960       m_ePacket(ePacket) {
961   ASSERT(m_pDocument);
962 }
963 
964 CXFA_Node::~CXFA_Node() = default;
965 
Clone(bool bRecursive)966 CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
967   CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
968   if (!pClone)
969     return nullptr;
970 
971   JSObject()->MergeAllData(pClone);
972   pClone->UpdateNameHash();
973   if (IsNeedSavingXMLNode()) {
974     CFX_XMLNode* pCloneXML;
975     if (IsAttributeInXML()) {
976       WideString wsName = JSObject()
977                               ->TryAttribute(XFA_Attribute::Name, false)
978                               .value_or(WideString());
979       auto* pCloneXMLElement =
980           GetXMLDocument()->CreateNode<CFX_XMLElement>(wsName);
981 
982       WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
983       if (!wsValue.IsEmpty()) {
984         auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(wsValue);
985         pCloneXMLElement->AppendLastChild(text);
986       }
987 
988       pCloneXML = pCloneXMLElement;
989       pClone->JSObject()->SetEnum(XFA_Attribute::Contains,
990                                   XFA_AttributeValue::Unknown, false);
991     } else {
992       pCloneXML = xml_node_->Clone(GetXMLDocument());
993     }
994     pClone->SetXMLMappingNode(pCloneXML);
995   }
996   if (bRecursive) {
997     for (CXFA_Node* pChild = GetFirstChild(); pChild;
998          pChild = pChild->GetNextSibling()) {
999       pClone->InsertChildAndNotify(pChild->Clone(bRecursive), nullptr);
1000     }
1001   }
1002   pClone->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1003   pClone->SetBindingNode(nullptr);
1004   return pClone;
1005 }
1006 
GetNextContainerSibling() const1007 CXFA_Node* CXFA_Node::GetNextContainerSibling() const {
1008   for (auto* pNode = GetNextSibling(); pNode; pNode = pNode->GetNextSibling()) {
1009     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1010       return pNode;
1011   }
1012   return nullptr;
1013 }
1014 
GetPrevContainerSibling() const1015 CXFA_Node* CXFA_Node::GetPrevContainerSibling() const {
1016   for (auto* pNode = GetPrevSibling(); pNode; pNode = pNode->GetPrevSibling()) {
1017     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1018       return pNode;
1019   }
1020   return nullptr;
1021 }
1022 
GetFirstContainerChild() const1023 CXFA_Node* CXFA_Node::GetFirstContainerChild() const {
1024   for (auto* pNode = GetFirstChild(); pNode; pNode = pNode->GetNextSibling()) {
1025     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1026       return pNode;
1027   }
1028   return nullptr;
1029 }
1030 
GetContainerParent() const1031 CXFA_Node* CXFA_Node::GetContainerParent() const {
1032   for (auto* pNode = GetParent(); pNode; pNode = pNode->GetParent()) {
1033     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1034       return pNode;
1035   }
1036   return nullptr;
1037 }
1038 
IsValidInPacket(XFA_PacketType packet) const1039 bool CXFA_Node::IsValidInPacket(XFA_PacketType packet) const {
1040   return !!(m_ValidPackets & (1 << static_cast<uint8_t>(packet)));
1041 }
1042 
GetPropertyData(XFA_Element property) const1043 const CXFA_Node::PropertyData* CXFA_Node::GetPropertyData(
1044     XFA_Element property) const {
1045   ASSERT(property != XFA_Element::Unknown);
1046   for (const auto& prop : m_Properties) {
1047     if (prop.property == property)
1048       return &prop;
1049   }
1050   return nullptr;
1051 }
1052 
HasProperty(XFA_Element property) const1053 bool CXFA_Node::HasProperty(XFA_Element property) const {
1054   return !!GetPropertyData(property);
1055 }
1056 
HasPropertyFlags(XFA_Element property,uint8_t flags) const1057 bool CXFA_Node::HasPropertyFlags(XFA_Element property, uint8_t flags) const {
1058   const PropertyData* data = GetPropertyData(property);
1059   return data && !!(data->flags & flags);
1060 }
1061 
PropertyOccuranceCount(XFA_Element property) const1062 uint8_t CXFA_Node::PropertyOccuranceCount(XFA_Element property) const {
1063   const PropertyData* data = GetPropertyData(property);
1064   return data ? data->occurance_count : 0;
1065 }
1066 
GetProperty(int32_t index,XFA_Element eProperty) const1067 std::pair<CXFA_Node*, int32_t> CXFA_Node::GetProperty(
1068     int32_t index,
1069     XFA_Element eProperty) const {
1070   if (index < 0 || index >= PropertyOccuranceCount(eProperty))
1071     return {nullptr, 0};
1072 
1073   int32_t iCount = 0;
1074   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1075        pNode = pNode->GetNextSibling()) {
1076     if (pNode->GetElementType() == eProperty) {
1077       iCount++;
1078       if (iCount > index)
1079         return {pNode, iCount};
1080     }
1081   }
1082   return {nullptr, iCount};
1083 }
1084 
GetOrCreateProperty(int32_t index,XFA_Element eProperty)1085 CXFA_Node* CXFA_Node::GetOrCreateProperty(int32_t index,
1086                                           XFA_Element eProperty) {
1087   if (index < 0 || index >= PropertyOccuranceCount(eProperty))
1088     return nullptr;
1089 
1090   int32_t iCount = 0;
1091   CXFA_Node* node;
1092   std::tie(node, iCount) = GetProperty(index, eProperty);
1093   if (node)
1094     return node;
1095 
1096   if (HasPropertyFlags(eProperty, XFA_PROPERTYFLAG_OneOf)) {
1097     for (CXFA_Node* pNode = GetFirstChild(); pNode;
1098          pNode = pNode->GetNextSibling()) {
1099       if (HasPropertyFlags(pNode->GetElementType(), XFA_PROPERTYFLAG_OneOf)) {
1100         return nullptr;
1101       }
1102     }
1103   }
1104 
1105   CXFA_Node* pNewNode = nullptr;
1106   for (; iCount <= index; ++iCount) {
1107     pNewNode = GetDocument()->CreateNode(GetPacketType(), eProperty);
1108     if (!pNewNode)
1109       return nullptr;
1110 
1111     InsertChildAndNotify(pNewNode, nullptr);
1112     pNewNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1113   }
1114   return pNewNode;
1115 }
1116 
GetFirstPropertyWithFlag(uint8_t flag) const1117 Optional<XFA_Element> CXFA_Node::GetFirstPropertyWithFlag(uint8_t flag) const {
1118   for (const auto& prop : m_Properties) {
1119     if (prop.flags & flag)
1120       return prop.property;
1121   }
1122   return {};
1123 }
1124 
GetAttributeData(XFA_Attribute attr) const1125 const CXFA_Node::AttributeData* CXFA_Node::GetAttributeData(
1126     XFA_Attribute attr) const {
1127   ASSERT(attr != XFA_Attribute::Unknown);
1128   for (const auto& cur_attr : m_Attributes) {
1129     if (cur_attr.attribute == attr)
1130       return &cur_attr;
1131   }
1132   return nullptr;
1133 }
1134 
HasAttribute(XFA_Attribute attr) const1135 bool CXFA_Node::HasAttribute(XFA_Attribute attr) const {
1136   return !!GetAttributeData(attr);
1137 }
1138 
GetAttribute(size_t i) const1139 XFA_Attribute CXFA_Node::GetAttribute(size_t i) const {
1140   return i < m_Attributes.size() ? m_Attributes[i].attribute
1141                                  : XFA_Attribute::Unknown;
1142 }
1143 
GetAttributeType(XFA_Attribute type) const1144 XFA_AttributeType CXFA_Node::GetAttributeType(XFA_Attribute type) const {
1145   const AttributeData* data = GetAttributeData(type);
1146   return data ? data->type : XFA_AttributeType::CData;
1147 }
1148 
GetNodeListForType(XFA_Element eTypeFilter)1149 std::vector<CXFA_Node*> CXFA_Node::GetNodeListForType(XFA_Element eTypeFilter) {
1150   std::vector<CXFA_Node*> nodes;
1151   for (CXFA_Node* pChild = GetFirstChild(); pChild;
1152        pChild = pChild->GetNextSibling()) {
1153     if (pChild->GetElementType() == eTypeFilter)
1154       nodes.push_back(pChild);
1155   }
1156   return nodes;
1157 }
1158 
GetNodeListWithFilter(uint32_t dwTypeFilter)1159 std::vector<CXFA_Node*> CXFA_Node::GetNodeListWithFilter(
1160     uint32_t dwTypeFilter) {
1161   std::vector<CXFA_Node*> nodes;
1162   if (dwTypeFilter == (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
1163     for (CXFA_Node* pChild = GetFirstChild(); pChild;
1164          pChild = pChild->GetNextSibling())
1165       nodes.push_back(pChild);
1166     return nodes;
1167   }
1168 
1169   if (dwTypeFilter == 0)
1170     return nodes;
1171 
1172   bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children);
1173   bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties);
1174   bool bFilterOneOfProperties = !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty);
1175   for (CXFA_Node* pChild = GetFirstChild(); pChild;
1176        pChild = pChild->GetNextSibling()) {
1177     if (HasProperty(pChild->GetElementType())) {
1178       if (bFilterProperties) {
1179         nodes.push_back(pChild);
1180       } else if (bFilterOneOfProperties &&
1181                  HasPropertyFlags(pChild->GetElementType(),
1182                                   XFA_PROPERTYFLAG_OneOf)) {
1183         nodes.push_back(pChild);
1184       } else if (bFilterChildren &&
1185                  (pChild->GetElementType() == XFA_Element::Variables ||
1186                   pChild->GetElementType() == XFA_Element::PageSet)) {
1187         nodes.push_back(pChild);
1188       }
1189     } else if (bFilterChildren) {
1190       nodes.push_back(pChild);
1191     }
1192   }
1193 
1194   if (!bFilterOneOfProperties || !nodes.empty())
1195     return nodes;
1196 
1197   Optional<XFA_Element> property =
1198       GetFirstPropertyWithFlag(XFA_PROPERTYFLAG_DefaultOneOf);
1199   if (!property.has_value())
1200     return nodes;
1201 
1202   CXFA_Node* pNewNode =
1203       m_pDocument->CreateNode(GetPacketType(), property.value());
1204   if (pNewNode) {
1205     InsertChildAndNotify(pNewNode, nullptr);
1206     pNewNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1207     nodes.push_back(pNewNode);
1208   }
1209   return nodes;
1210 }
1211 
CreateSamePacketNode(XFA_Element eType)1212 CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_Element eType) {
1213   CXFA_Node* pNode = m_pDocument->CreateNode(m_ePacket, eType);
1214   if (!pNode)
1215     return nullptr;
1216 
1217   pNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1218   return pNode;
1219 }
1220 
CloneTemplateToForm(bool bRecursive)1221 CXFA_Node* CXFA_Node::CloneTemplateToForm(bool bRecursive) {
1222   ASSERT(m_ePacket == XFA_PacketType::Template);
1223   CXFA_Node* pClone =
1224       m_pDocument->CreateNode(XFA_PacketType::Form, m_elementType);
1225   if (!pClone)
1226     return nullptr;
1227 
1228   pClone->SetTemplateNode(this);
1229   pClone->UpdateNameHash();
1230   pClone->SetXMLMappingNode(GetXMLMappingNode());
1231   if (bRecursive) {
1232     for (CXFA_Node* pChild = GetFirstChild(); pChild;
1233          pChild = pChild->GetNextSibling()) {
1234       pClone->InsertChildAndNotify(pChild->CloneTemplateToForm(bRecursive),
1235                                    nullptr);
1236     }
1237   }
1238   pClone->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1239   return pClone;
1240 }
1241 
GetTemplateNodeIfExists() const1242 CXFA_Node* CXFA_Node::GetTemplateNodeIfExists() const {
1243   return m_pAuxNode;
1244 }
1245 
SetTemplateNode(CXFA_Node * pTemplateNode)1246 void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
1247   m_pAuxNode = pTemplateNode;
1248 }
1249 
GetBindData()1250 CXFA_Node* CXFA_Node::GetBindData() {
1251   ASSERT(GetPacketType() == XFA_PacketType::Form);
1252   return GetBindingNode();
1253 }
1254 
AddBindItem(CXFA_Node * pFormNode)1255 int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
1256   ASSERT(pFormNode);
1257 
1258   if (BindsFormItems()) {
1259     bool found = false;
1260     for (auto* v : binding_nodes_) {
1261       if (v == pFormNode) {
1262         found = true;
1263         break;
1264       }
1265     }
1266     if (!found)
1267       binding_nodes_.emplace_back(pFormNode);
1268     return pdfium::CollectionSize<int32_t>(binding_nodes_);
1269   }
1270 
1271   CXFA_Node* pOldFormItem = GetBindingNode();
1272   if (!pOldFormItem) {
1273     SetBindingNode(pFormNode);
1274     return 1;
1275   }
1276   if (pOldFormItem == pFormNode)
1277     return 1;
1278 
1279   std::vector<CXFA_Node*> items;
1280   items.push_back(pOldFormItem);
1281   items.push_back(pFormNode);
1282   binding_nodes_ = std::move(items);
1283 
1284   m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
1285   return 2;
1286 }
1287 
RemoveBindItem(CXFA_Node * pFormNode)1288 int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
1289   if (BindsFormItems()) {
1290     auto it =
1291         std::find(binding_nodes_.begin(), binding_nodes_.end(), pFormNode);
1292     if (it != binding_nodes_.end())
1293       binding_nodes_.erase(it);
1294 
1295     if (binding_nodes_.size() == 1) {
1296       m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
1297       return 1;
1298     }
1299     return pdfium::CollectionSize<int32_t>(binding_nodes_);
1300   }
1301 
1302   CXFA_Node* pOldFormItem = GetBindingNode();
1303   if (pOldFormItem != pFormNode)
1304     return pOldFormItem ? 1 : 0;
1305 
1306   SetBindingNode(nullptr);
1307   return 0;
1308 }
1309 
HasBindItem() const1310 bool CXFA_Node::HasBindItem() const {
1311   return GetPacketType() == XFA_PacketType::Datasets && GetBindingNode();
1312 }
1313 
GetContainerNode()1314 CXFA_Node* CXFA_Node::GetContainerNode() {
1315   if (GetPacketType() != XFA_PacketType::Form)
1316     return nullptr;
1317   XFA_Element eType = GetElementType();
1318   if (eType == XFA_Element::ExclGroup)
1319     return nullptr;
1320   CXFA_Node* pParentNode = GetParent();
1321   if (pParentNode && pParentNode->GetElementType() == XFA_Element::ExclGroup)
1322     return nullptr;
1323 
1324   if (eType == XFA_Element::Field) {
1325     if (IsChoiceListMultiSelect())
1326       return nullptr;
1327 
1328     WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
1329     if (!wsPicture.IsEmpty())
1330       return this;
1331 
1332     CXFA_Node* pDataNode = GetBindData();
1333     if (!pDataNode)
1334       return nullptr;
1335 
1336     CXFA_Node* pFieldNode = nullptr;
1337     for (auto* pFormNode : pDataNode->GetBindItemsCopy()) {
1338       if (!pFormNode || pFormNode->HasRemovedChildren())
1339         continue;
1340       pFieldNode = pFormNode->IsWidgetReady() ? pFormNode : nullptr;
1341       if (pFieldNode)
1342         wsPicture = pFieldNode->GetPictureContent(XFA_VALUEPICTURE_DataBind);
1343       if (!wsPicture.IsEmpty())
1344         break;
1345 
1346       pFieldNode = nullptr;
1347     }
1348     return pFieldNode;
1349   }
1350 
1351   CXFA_Node* pGrandNode = pParentNode ? pParentNode->GetParent() : nullptr;
1352   CXFA_Node* pValueNode =
1353       (pParentNode && pParentNode->GetElementType() == XFA_Element::Value)
1354           ? pParentNode
1355           : nullptr;
1356   if (!pValueNode) {
1357     pValueNode =
1358         (pGrandNode && pGrandNode->GetElementType() == XFA_Element::Value)
1359             ? pGrandNode
1360             : nullptr;
1361   }
1362   CXFA_Node* pParentOfValueNode =
1363       pValueNode ? pValueNode->GetParent() : nullptr;
1364   return pParentOfValueNode ? pParentOfValueNode->GetContainerNode() : nullptr;
1365 }
1366 
GetLocale()1367 LocaleIface* CXFA_Node::GetLocale() {
1368   Optional<WideString> localeName = GetLocaleName();
1369   if (!localeName.has_value())
1370     return nullptr;
1371   if (localeName.value().EqualsASCII("ambient"))
1372     return GetDocument()->GetLocaleMgr()->GetDefLocale();
1373   return GetDocument()->GetLocaleMgr()->GetLocaleByName(localeName.value());
1374 }
1375 
GetLocaleName()1376 Optional<WideString> CXFA_Node::GetLocaleName() {
1377   CXFA_Node* pForm = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form));
1378   if (!pForm)
1379     return {};
1380 
1381   CXFA_Subform* pTopSubform =
1382       pForm->GetFirstChildByClass<CXFA_Subform>(XFA_Element::Subform);
1383   if (!pTopSubform)
1384     return {};
1385 
1386   CXFA_Node* pLocaleNode = this;
1387   do {
1388     Optional<WideString> localeName =
1389         pLocaleNode->JSObject()->TryCData(XFA_Attribute::Locale, false);
1390     if (localeName)
1391       return localeName;
1392 
1393     pLocaleNode = pLocaleNode->GetParent();
1394   } while (pLocaleNode && pLocaleNode != pTopSubform);
1395 
1396   CXFA_Node* pConfig = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
1397   WideString wsLocaleName =
1398       GetDocument()->GetLocaleMgr()->GetConfigLocaleName(pConfig);
1399   if (!wsLocaleName.IsEmpty())
1400     return wsLocaleName;
1401 
1402   if (pTopSubform) {
1403     Optional<WideString> localeName =
1404         pTopSubform->JSObject()->TryCData(XFA_Attribute::Locale, false);
1405     if (localeName)
1406       return localeName;
1407   }
1408 
1409   LocaleIface* pLocale = GetDocument()->GetLocaleMgr()->GetDefLocale();
1410   if (!pLocale)
1411     return {};
1412 
1413   return pLocale->GetName();
1414 }
1415 
GetIntact()1416 XFA_AttributeValue CXFA_Node::GetIntact() {
1417   CXFA_Keep* pKeep = GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
1418   auto layout = JSObject()->TryEnum(XFA_Attribute::Layout, true);
1419   XFA_AttributeValue eLayoutType =
1420       layout.value_or(XFA_AttributeValue::Position);
1421   if (pKeep) {
1422     Optional<XFA_AttributeValue> intact = GetIntactFromKeep(pKeep, eLayoutType);
1423     if (intact)
1424       return *intact;
1425   }
1426 
1427   switch (GetElementType()) {
1428     case XFA_Element::Subform:
1429       switch (eLayoutType) {
1430         case XFA_AttributeValue::Position:
1431         case XFA_AttributeValue::Row:
1432           return XFA_AttributeValue::ContentArea;
1433         default:
1434           return XFA_AttributeValue::None;
1435       }
1436     case XFA_Element::Field: {
1437       CXFA_Node* parent = GetParent();
1438       if (!parent || parent->GetElementType() == XFA_Element::PageArea)
1439         return XFA_AttributeValue::ContentArea;
1440       if (parent->GetIntact() != XFA_AttributeValue::None)
1441         return XFA_AttributeValue::ContentArea;
1442 
1443       auto value = parent->JSObject()->TryEnum(XFA_Attribute::Layout, true);
1444       XFA_AttributeValue eParLayout =
1445           value.value_or(XFA_AttributeValue::Position);
1446       if (eParLayout == XFA_AttributeValue::Position ||
1447           eParLayout == XFA_AttributeValue::Row ||
1448           eParLayout == XFA_AttributeValue::Table) {
1449         return XFA_AttributeValue::None;
1450       }
1451 
1452       XFA_VERSION version = m_pDocument->GetCurVersionMode();
1453       if (eParLayout == XFA_AttributeValue::Tb && version < XFA_VERSION_208) {
1454         Optional<CXFA_Measurement> measureH =
1455             JSObject()->TryMeasure(XFA_Attribute::H, false);
1456         if (measureH)
1457           return XFA_AttributeValue::ContentArea;
1458       }
1459       return XFA_AttributeValue::None;
1460     }
1461     case XFA_Element::Draw:
1462       return XFA_AttributeValue::ContentArea;
1463     default:
1464       return XFA_AttributeValue::None;
1465   }
1466 }
1467 
GetNameExpression()1468 WideString CXFA_Node::GetNameExpression() {
1469   WideString wsName = GetNameExpressionSinglePath(this);
1470   CXFA_Node* parent = GetParent();
1471   while (parent) {
1472     WideString wsParent = GetNameExpressionSinglePath(parent);
1473     wsParent += L".";
1474     wsParent += wsName;
1475     wsName = std::move(wsParent);
1476     parent = parent->GetParent();
1477   }
1478   return wsName;
1479 }
1480 
GetDataDescriptionNode()1481 CXFA_Node* CXFA_Node::GetDataDescriptionNode() {
1482   if (m_ePacket == XFA_PacketType::Datasets)
1483     return m_pAuxNode;
1484   return nullptr;
1485 }
1486 
SetDataDescriptionNode(CXFA_Node * pDataDescriptionNode)1487 void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode) {
1488   ASSERT(m_ePacket == XFA_PacketType::Datasets);
1489   m_pAuxNode = pDataDescriptionNode;
1490 }
1491 
GetModelNode()1492 CXFA_Node* CXFA_Node::GetModelNode() {
1493   switch (GetPacketType()) {
1494     case XFA_PacketType::Xdp:
1495       return m_pDocument->GetRoot();
1496     case XFA_PacketType::Config:
1497       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
1498     case XFA_PacketType::Template:
1499       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
1500     case XFA_PacketType::Form:
1501       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
1502     case XFA_PacketType::Datasets:
1503       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
1504     case XFA_PacketType::LocaleSet:
1505       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_LocaleSet));
1506     case XFA_PacketType::ConnectionSet:
1507       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_ConnectionSet));
1508     case XFA_PacketType::SourceSet:
1509       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_SourceSet));
1510     case XFA_PacketType::Xdc:
1511       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Xdc));
1512     default:
1513       return this;
1514   }
1515 }
1516 
CountChildren(XFA_Element eType,bool bOnlyChild)1517 size_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) {
1518   size_t count = 0;
1519   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1520        pNode = pNode->GetNextSibling()) {
1521     if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
1522       continue;
1523     if (bOnlyChild && HasProperty(pNode->GetElementType()))
1524       continue;
1525     ++count;
1526   }
1527   return count;
1528 }
1529 
GetChildInternal(size_t index,XFA_Element eType,bool bOnlyChild) const1530 CXFA_Node* CXFA_Node::GetChildInternal(size_t index,
1531                                        XFA_Element eType,
1532                                        bool bOnlyChild) const {
1533   size_t count = 0;
1534   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1535        pNode = pNode->GetNextSibling()) {
1536     if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
1537       continue;
1538     if (bOnlyChild && HasProperty(pNode->GetElementType()))
1539       continue;
1540     if (count == index)
1541       return pNode;
1542 
1543     ++count;
1544   }
1545   return nullptr;
1546 }
1547 
InsertChildAndNotify(int32_t index,CXFA_Node * pNode)1548 void CXFA_Node::InsertChildAndNotify(int32_t index, CXFA_Node* pNode) {
1549   InsertChildAndNotify(pNode, GetNthChild(index));
1550 }
1551 
InsertChildAndNotify(CXFA_Node * pNode,CXFA_Node * pBeforeNode)1552 void CXFA_Node::InsertChildAndNotify(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
1553   CHECK(!pNode->GetParent());
1554   CHECK(!pBeforeNode || pBeforeNode->GetParent() == this);
1555   pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
1556   InsertBefore(pNode, pBeforeNode);
1557 
1558   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1559   if (pNotify)
1560     pNotify->OnChildAdded(this);
1561 
1562   if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
1563     return;
1564 
1565   ASSERT(!pNode->xml_node_->GetParent());
1566   xml_node_->InsertBefore(pNode->xml_node_.Get(),
1567                           pBeforeNode ? pBeforeNode->xml_node_.Get() : nullptr);
1568 }
1569 
RemoveChildAndNotify(CXFA_Node * pNode,bool bNotify)1570 void CXFA_Node::RemoveChildAndNotify(CXFA_Node* pNode, bool bNotify) {
1571   CHECK(pNode);
1572   if (pNode->GetParent() != this)
1573     return;
1574 
1575   pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren);
1576   TreeNode<CXFA_Node>::RemoveChild(pNode);
1577   OnRemoved(bNotify);
1578 
1579   if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
1580     return;
1581 
1582   if (!pNode->IsAttributeInXML()) {
1583     xml_node_->RemoveChild(pNode->xml_node_.Get());
1584     return;
1585   }
1586 
1587   ASSERT(pNode->xml_node_ == xml_node_);
1588   CFX_XMLElement* pXMLElement = ToXMLElement(pNode->xml_node_.Get());
1589   if (pXMLElement) {
1590     WideString wsAttributeName =
1591         pNode->JSObject()->GetCData(XFA_Attribute::QualifiedName);
1592     pXMLElement->RemoveAttribute(wsAttributeName);
1593   }
1594 
1595   WideString wsName = pNode->JSObject()
1596                           ->TryAttribute(XFA_Attribute::Name, false)
1597                           .value_or(WideString());
1598 
1599   auto* pNewXMLElement = GetXMLDocument()->CreateNode<CFX_XMLElement>(wsName);
1600   WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
1601   if (!wsValue.IsEmpty()) {
1602     auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(wsValue);
1603     pNewXMLElement->AppendLastChild(text);
1604   }
1605   pNode->xml_node_ = pNewXMLElement;
1606   pNode->JSObject()->SetEnum(XFA_Attribute::Contains,
1607                              XFA_AttributeValue::Unknown, false);
1608 }
1609 
GetFirstChildByName(WideStringView wsName) const1610 CXFA_Node* CXFA_Node::GetFirstChildByName(WideStringView wsName) const {
1611   return GetFirstChildByName(FX_HashCode_GetW(wsName, false));
1612 }
1613 
GetFirstChildByName(uint32_t dwNameHash) const1614 CXFA_Node* CXFA_Node::GetFirstChildByName(uint32_t dwNameHash) const {
1615   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1616        pNode = pNode->GetNextSibling()) {
1617     if (pNode->GetNameHash() == dwNameHash)
1618       return pNode;
1619   }
1620   return nullptr;
1621 }
1622 
GetFirstChildByClassInternal(XFA_Element eType) const1623 CXFA_Node* CXFA_Node::GetFirstChildByClassInternal(XFA_Element eType) const {
1624   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1625        pNode = pNode->GetNextSibling()) {
1626     if (pNode->GetElementType() == eType)
1627       return pNode;
1628   }
1629   return nullptr;
1630 }
1631 
GetNextSameNameSibling(uint32_t dwNameHash) const1632 CXFA_Node* CXFA_Node::GetNextSameNameSibling(uint32_t dwNameHash) const {
1633   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1634        pNode = pNode->GetNextSibling()) {
1635     if (pNode->GetNameHash() == dwNameHash)
1636       return pNode;
1637   }
1638   return nullptr;
1639 }
1640 
GetNextSameNameSiblingInternal(WideStringView wsNodeName) const1641 CXFA_Node* CXFA_Node::GetNextSameNameSiblingInternal(
1642     WideStringView wsNodeName) const {
1643   return GetNextSameNameSibling(FX_HashCode_GetW(wsNodeName, false));
1644 }
1645 
GetNextSameClassSiblingInternal(XFA_Element eType) const1646 CXFA_Node* CXFA_Node::GetNextSameClassSiblingInternal(XFA_Element eType) const {
1647   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1648        pNode = pNode->GetNextSibling()) {
1649     if (pNode->GetElementType() == eType)
1650       return pNode;
1651   }
1652   return nullptr;
1653 }
1654 
GetOneChildNamed(WideStringView wsName)1655 CXFA_Node* CXFA_Node::GetOneChildNamed(WideStringView wsName) {
1656   return FindFirstSiblingNamed(this, FX_HashCode_GetW(wsName, false));
1657 }
1658 
GetOneChildOfClass(WideStringView wsClass)1659 CXFA_Node* CXFA_Node::GetOneChildOfClass(WideStringView wsClass) {
1660   XFA_Element element = XFA_GetElementByName(wsClass);
1661   if (element == XFA_Element::Unknown)
1662     return nullptr;
1663 
1664   return FindFirstSiblingOfClass(this, element);
1665 }
1666 
GetSiblings(bool bIsClassName)1667 std::vector<CXFA_Node*> CXFA_Node::GetSiblings(bool bIsClassName) {
1668   std::vector<CXFA_Node*> siblings;
1669   CXFA_Node* parent = GetParent();
1670   if (!parent)
1671     return siblings;
1672   if (!parent->HasProperty(GetElementType())) {
1673     parent = GetTransparentParent();
1674     if (!parent)
1675       return siblings;
1676   }
1677 
1678   uint32_t dwNameHash = bIsClassName ? GetClassHashCode() : GetNameHash();
1679   TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true);
1680   return siblings;
1681 }
1682 
GetIndex(bool bIsProperty,bool bIsClassIndex)1683 size_t CXFA_Node::GetIndex(bool bIsProperty, bool bIsClassIndex) {
1684   CXFA_Node* parent = GetParent();
1685   if (!parent)
1686     return 0;
1687 
1688   if (!bIsProperty) {
1689     parent = GetTransparentParent();
1690     if (!parent)
1691       return 0;
1692   }
1693   uint32_t dwHashName = bIsClassIndex ? GetClassHashCode() : GetNameHash();
1694   std::vector<CXFA_Node*> siblings;
1695   TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true);
1696   for (size_t i = 0; i < siblings.size(); ++i) {
1697     if (siblings[i] == this)
1698       return i;
1699   }
1700   return 0;
1701 }
1702 
GetIndexByName()1703 size_t CXFA_Node::GetIndexByName() {
1704   return GetIndex(IsProperty(), /*bIsClassIndex=*/false);
1705 }
1706 
GetIndexByClassName()1707 size_t CXFA_Node::GetIndexByClassName() {
1708   return GetIndex(IsProperty(), /*bIsClassIndex=*/true);
1709 }
1710 
GetInstanceMgrOfSubform()1711 CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
1712   CXFA_Node* pInstanceMgr = nullptr;
1713   if (m_ePacket == XFA_PacketType::Form) {
1714     CXFA_Node* pParentNode = GetParent();
1715     if (!pParentNode || pParentNode->GetElementType() == XFA_Element::Area)
1716       return pInstanceMgr;
1717 
1718     for (CXFA_Node* pNode = GetPrevSibling(); pNode;
1719          pNode = pNode->GetPrevSibling()) {
1720       XFA_Element eType = pNode->GetElementType();
1721       if ((eType == XFA_Element::Subform || eType == XFA_Element::SubformSet) &&
1722           pNode->m_dwNameHash != m_dwNameHash) {
1723         break;
1724       }
1725       if (eType == XFA_Element::InstanceManager) {
1726         WideString wsName = JSObject()->GetCData(XFA_Attribute::Name);
1727         WideString wsInstName =
1728             pNode->JSObject()->GetCData(XFA_Attribute::Name);
1729         if (wsInstName.GetLength() > 0 && wsInstName[0] == '_' &&
1730             wsInstName.Last(wsInstName.GetLength() - 1) == wsName) {
1731           pInstanceMgr = pNode;
1732         }
1733         break;
1734       }
1735     }
1736   }
1737   return pInstanceMgr;
1738 }
1739 
GetOccurIfExists()1740 CXFA_Occur* CXFA_Node::GetOccurIfExists() {
1741   return GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
1742 }
1743 
HasFlag(XFA_NodeFlag dwFlag) const1744 bool CXFA_Node::HasFlag(XFA_NodeFlag dwFlag) const {
1745   if (m_uNodeFlags & dwFlag)
1746     return true;
1747   if (dwFlag == XFA_NodeFlag_HasRemovedChildren)
1748     return GetParent() && GetParent()->HasFlag(dwFlag);
1749   return false;
1750 }
1751 
SetFlagAndNotify(uint32_t dwFlag)1752 void CXFA_Node::SetFlagAndNotify(uint32_t dwFlag) {
1753   ASSERT(dwFlag == XFA_NodeFlag_Initialized);
1754 
1755   if (!IsInitialized()) {
1756     CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1757     if (pNotify) {
1758       pNotify->OnNodeReady(this);
1759     }
1760   }
1761   m_uNodeFlags |= dwFlag;
1762 }
1763 
SetFlag(uint32_t dwFlag)1764 void CXFA_Node::SetFlag(uint32_t dwFlag) {
1765   m_uNodeFlags |= dwFlag;
1766 }
1767 
ClearFlag(uint32_t dwFlag)1768 void CXFA_Node::ClearFlag(uint32_t dwFlag) {
1769   m_uNodeFlags &= ~dwFlag;
1770 }
1771 
IsAttributeInXML()1772 bool CXFA_Node::IsAttributeInXML() {
1773   return JSObject()->GetEnum(XFA_Attribute::Contains) ==
1774          XFA_AttributeValue::MetaData;
1775 }
1776 
OnRemoved(bool bNotify) const1777 void CXFA_Node::OnRemoved(bool bNotify) const {
1778   if (!bNotify)
1779     return;
1780 
1781   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1782   if (pNotify)
1783     pNotify->OnChildRemoved();
1784 }
1785 
UpdateNameHash()1786 void CXFA_Node::UpdateNameHash() {
1787   WideString wsName = JSObject()->GetCData(XFA_Attribute::Name);
1788   m_dwNameHash = FX_HashCode_GetW(wsName.AsStringView(), false);
1789 }
1790 
CreateXMLMappingNode()1791 CFX_XMLNode* CXFA_Node::CreateXMLMappingNode() {
1792   if (!xml_node_) {
1793     xml_node_ = GetXMLDocument()->CreateNode<CFX_XMLElement>(
1794         JSObject()->GetCData(XFA_Attribute::Name));
1795   }
1796   return xml_node_.Get();
1797 }
1798 
IsNeedSavingXMLNode() const1799 bool CXFA_Node::IsNeedSavingXMLNode() const {
1800   return xml_node_ && (GetPacketType() == XFA_PacketType::Datasets ||
1801                        GetElementType() == XFA_Element::Xfa);
1802 }
1803 
GetItemIfExists(int32_t iIndex)1804 CXFA_Node* CXFA_Node::GetItemIfExists(int32_t iIndex) {
1805   int32_t iCount = 0;
1806   uint32_t dwNameHash = 0;
1807   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1808        pNode = pNode->GetNextSibling()) {
1809     XFA_Element eCurType = pNode->GetElementType();
1810     if (eCurType == XFA_Element::InstanceManager)
1811       break;
1812     if ((eCurType != XFA_Element::Subform) &&
1813         (eCurType != XFA_Element::SubformSet)) {
1814       continue;
1815     }
1816     if (iCount == 0) {
1817       WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
1818       WideString wsInstName = JSObject()->GetCData(XFA_Attribute::Name);
1819       if (wsInstName.GetLength() < 1 || wsInstName[0] != '_' ||
1820           wsInstName.Last(wsInstName.GetLength() - 1) != wsName) {
1821         return nullptr;
1822       }
1823       dwNameHash = pNode->GetNameHash();
1824     }
1825     if (dwNameHash != pNode->GetNameHash())
1826       break;
1827 
1828     iCount++;
1829     if (iCount > iIndex)
1830       return pNode;
1831   }
1832   return nullptr;
1833 }
1834 
GetCount()1835 int32_t CXFA_Node::GetCount() {
1836   int32_t iCount = 0;
1837   uint32_t dwNameHash = 0;
1838   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1839        pNode = pNode->GetNextSibling()) {
1840     XFA_Element eCurType = pNode->GetElementType();
1841     if (eCurType == XFA_Element::InstanceManager)
1842       break;
1843     if ((eCurType != XFA_Element::Subform) &&
1844         (eCurType != XFA_Element::SubformSet)) {
1845       continue;
1846     }
1847     if (iCount == 0) {
1848       WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
1849       WideString wsInstName = JSObject()->GetCData(XFA_Attribute::Name);
1850       if (wsInstName.GetLength() < 1 || wsInstName[0] != '_' ||
1851           wsInstName.Last(wsInstName.GetLength() - 1) != wsName) {
1852         return iCount;
1853       }
1854       dwNameHash = pNode->GetNameHash();
1855     }
1856     if (dwNameHash != pNode->GetNameHash())
1857       break;
1858 
1859     iCount++;
1860   }
1861   return iCount;
1862 }
1863 
InsertItem(CXFA_Node * pNewInstance,int32_t iPos,int32_t iCount,bool bMoveDataBindingNodes)1864 void CXFA_Node::InsertItem(CXFA_Node* pNewInstance,
1865                            int32_t iPos,
1866                            int32_t iCount,
1867                            bool bMoveDataBindingNodes) {
1868   if (iCount < 0)
1869     iCount = GetCount();
1870   if (iPos < 0)
1871     iPos = iCount;
1872   if (iPos == iCount) {
1873     CXFA_Node* item = GetItemIfExists(iCount - 1);
1874     if (!item)
1875       return;
1876 
1877     CXFA_Node* pNextSibling =
1878         iCount > 0 ? item->GetNextSibling() : GetNextSibling();
1879     GetParent()->InsertChildAndNotify(pNewInstance, pNextSibling);
1880     if (bMoveDataBindingNodes) {
1881       std::set<CXFA_Node*> sNew;
1882       std::set<CXFA_Node*> sAfter;
1883       CXFA_NodeIteratorTemplate<CXFA_Node,
1884                                 CXFA_TraverseStrategy_XFAContainerNode>
1885           sIteratorNew(pNewInstance);
1886       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
1887            pNode = sIteratorNew.MoveToNext()) {
1888         CXFA_Node* pDataNode = pNode->GetBindData();
1889         if (!pDataNode)
1890           continue;
1891 
1892         sNew.insert(pDataNode);
1893       }
1894       CXFA_NodeIteratorTemplate<CXFA_Node,
1895                                 CXFA_TraverseStrategy_XFAContainerNode>
1896           sIteratorAfter(pNextSibling);
1897       for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
1898            pNode = sIteratorAfter.MoveToNext()) {
1899         CXFA_Node* pDataNode = pNode->GetBindData();
1900         if (!pDataNode)
1901           continue;
1902 
1903         sAfter.insert(pDataNode);
1904       }
1905       ReorderDataNodes(sNew, sAfter, false);
1906     }
1907   } else {
1908     CXFA_Node* pBeforeInstance = GetItemIfExists(iPos);
1909     if (!pBeforeInstance) {
1910       // TODO(dsinclair): What should happen here?
1911       return;
1912     }
1913 
1914     GetParent()->InsertChildAndNotify(pNewInstance, pBeforeInstance);
1915     if (bMoveDataBindingNodes) {
1916       std::set<CXFA_Node*> sNew;
1917       std::set<CXFA_Node*> sBefore;
1918       CXFA_NodeIteratorTemplate<CXFA_Node,
1919                                 CXFA_TraverseStrategy_XFAContainerNode>
1920           sIteratorNew(pNewInstance);
1921       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
1922            pNode = sIteratorNew.MoveToNext()) {
1923         CXFA_Node* pDataNode = pNode->GetBindData();
1924         if (!pDataNode)
1925           continue;
1926 
1927         sNew.insert(pDataNode);
1928       }
1929       CXFA_NodeIteratorTemplate<CXFA_Node,
1930                                 CXFA_TraverseStrategy_XFAContainerNode>
1931           sIteratorBefore(pBeforeInstance);
1932       for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
1933            pNode = sIteratorBefore.MoveToNext()) {
1934         CXFA_Node* pDataNode = pNode->GetBindData();
1935         if (!pDataNode)
1936           continue;
1937 
1938         sBefore.insert(pDataNode);
1939       }
1940       ReorderDataNodes(sNew, sBefore, true);
1941     }
1942   }
1943 }
1944 
RemoveItem(CXFA_Node * pRemoveInstance,bool bRemoveDataBinding)1945 void CXFA_Node::RemoveItem(CXFA_Node* pRemoveInstance,
1946                            bool bRemoveDataBinding) {
1947   GetParent()->RemoveChildAndNotify(pRemoveInstance, true);
1948   if (!bRemoveDataBinding)
1949     return;
1950 
1951   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
1952       sIterator(pRemoveInstance);
1953   for (CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode;
1954        pFormNode = sIterator.MoveToNext()) {
1955     CXFA_Node* pDataNode = pFormNode->GetBindData();
1956     if (!pDataNode)
1957       continue;
1958 
1959     if (pDataNode->RemoveBindItem(pFormNode) == 0) {
1960       if (CXFA_Node* pDataParent = pDataNode->GetParent()) {
1961         pDataParent->RemoveChildAndNotify(pDataNode, true);
1962       }
1963     }
1964     pFormNode->SetBindingNode(nullptr);
1965   }
1966 }
1967 
CreateInstanceIfPossible(bool bDataMerge)1968 CXFA_Node* CXFA_Node::CreateInstanceIfPossible(bool bDataMerge) {
1969   CXFA_Document* pDocument = GetDocument();
1970   CXFA_Node* pTemplateNode = GetTemplateNodeIfExists();
1971   if (!pTemplateNode)
1972     return nullptr;
1973 
1974   CXFA_Node* pFormParent = GetParent();
1975   CXFA_Node* pDataScope = nullptr;
1976   for (CXFA_Node* pRootBoundNode = pFormParent;
1977        pRootBoundNode && pRootBoundNode->IsContainerNode();
1978        pRootBoundNode = pRootBoundNode->GetParent()) {
1979     pDataScope = pRootBoundNode->GetBindData();
1980     if (pDataScope)
1981       break;
1982   }
1983   if (!pDataScope) {
1984     pDataScope = ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
1985     ASSERT(pDataScope);
1986   }
1987 
1988   CXFA_Node* pInstance = pDocument->DataMerge_CopyContainer(
1989       pTemplateNode, pFormParent, pDataScope, true, bDataMerge, true);
1990   if (pInstance) {
1991     pDocument->DataMerge_UpdateBindingRelations(pInstance);
1992     pFormParent->RemoveChildAndNotify(pInstance, true);
1993   }
1994   return pInstance;
1995 }
1996 
GetDefaultBoolean(XFA_Attribute attr) const1997 Optional<bool> CXFA_Node::GetDefaultBoolean(XFA_Attribute attr) const {
1998   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Boolean);
1999   if (!value)
2000     return {};
2001   return {!!*value};
2002 }
2003 
GetDefaultInteger(XFA_Attribute attr) const2004 Optional<int32_t> CXFA_Node::GetDefaultInteger(XFA_Attribute attr) const {
2005   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Integer);
2006   if (!value)
2007     return {};
2008   return {static_cast<int32_t>(reinterpret_cast<uintptr_t>(*value))};
2009 }
2010 
GetDefaultMeasurement(XFA_Attribute attr) const2011 Optional<CXFA_Measurement> CXFA_Node::GetDefaultMeasurement(
2012     XFA_Attribute attr) const {
2013   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Measure);
2014   if (!value)
2015     return {};
2016 
2017   WideString str = WideString(static_cast<const wchar_t*>(*value));
2018   return {CXFA_Measurement(str.AsStringView())};
2019 }
2020 
GetDefaultCData(XFA_Attribute attr) const2021 Optional<WideString> CXFA_Node::GetDefaultCData(XFA_Attribute attr) const {
2022   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::CData);
2023   if (!value)
2024     return {};
2025 
2026   return {WideString(static_cast<const wchar_t*>(*value))};
2027 }
2028 
GetDefaultEnum(XFA_Attribute attr) const2029 Optional<XFA_AttributeValue> CXFA_Node::GetDefaultEnum(
2030     XFA_Attribute attr) const {
2031   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Enum);
2032   if (!value)
2033     return {};
2034   return {static_cast<XFA_AttributeValue>(reinterpret_cast<uintptr_t>(*value))};
2035 }
2036 
GetDefaultValue(XFA_Attribute attr,XFA_AttributeType eType) const2037 Optional<void*> CXFA_Node::GetDefaultValue(XFA_Attribute attr,
2038                                            XFA_AttributeType eType) const {
2039   const AttributeData* data = GetAttributeData(attr);
2040   if (!data)
2041     return {};
2042   if (data->type == eType)
2043     return {data->default_value};
2044   return {};
2045 }
2046 
SendAttributeChangeMessage(XFA_Attribute eAttribute,bool bScriptModify)2047 void CXFA_Node::SendAttributeChangeMessage(XFA_Attribute eAttribute,
2048                                            bool bScriptModify) {
2049   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
2050   if (!pNotify)
2051     return;
2052 
2053   if (GetPacketType() != XFA_PacketType::Form) {
2054     pNotify->OnValueChanged(this, eAttribute, this, this);
2055     return;
2056   }
2057 
2058   bool bNeedFindContainer = false;
2059   switch (GetElementType()) {
2060     case XFA_Element::Caption:
2061       bNeedFindContainer = true;
2062       pNotify->OnValueChanged(this, eAttribute, this, GetParent());
2063       break;
2064     case XFA_Element::Font:
2065     case XFA_Element::Para: {
2066       bNeedFindContainer = true;
2067       CXFA_Node* pParentNode = GetParent();
2068       if (pParentNode->GetElementType() == XFA_Element::Caption) {
2069         pNotify->OnValueChanged(this, eAttribute, pParentNode,
2070                                 pParentNode->GetParent());
2071       } else {
2072         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
2073       }
2074       break;
2075     }
2076     case XFA_Element::Margin: {
2077       bNeedFindContainer = true;
2078       CXFA_Node* pParentNode = GetParent();
2079       XFA_Element eParentType = pParentNode->GetElementType();
2080       if (pParentNode->IsContainerNode()) {
2081         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
2082       } else if (eParentType == XFA_Element::Caption) {
2083         pNotify->OnValueChanged(this, eAttribute, pParentNode,
2084                                 pParentNode->GetParent());
2085       } else {
2086         CXFA_Node* pNode = pParentNode->GetParent();
2087         if (pNode && pNode->GetElementType() == XFA_Element::Ui)
2088           pNotify->OnValueChanged(this, eAttribute, pNode, pNode->GetParent());
2089       }
2090       break;
2091     }
2092     case XFA_Element::Comb: {
2093       CXFA_Node* pEditNode = GetParent();
2094       XFA_Element eUIType = pEditNode->GetElementType();
2095       if (pEditNode && (eUIType == XFA_Element::DateTimeEdit ||
2096                         eUIType == XFA_Element::NumericEdit ||
2097                         eUIType == XFA_Element::TextEdit)) {
2098         CXFA_Node* pUINode = pEditNode->GetParent();
2099         if (pUINode) {
2100           pNotify->OnValueChanged(this, eAttribute, pUINode,
2101                                   pUINode->GetParent());
2102         }
2103       }
2104       break;
2105     }
2106     case XFA_Element::Button:
2107     case XFA_Element::Barcode:
2108     case XFA_Element::ChoiceList:
2109     case XFA_Element::DateTimeEdit:
2110     case XFA_Element::NumericEdit:
2111     case XFA_Element::PasswordEdit:
2112     case XFA_Element::TextEdit: {
2113       CXFA_Node* pUINode = GetParent();
2114       if (pUINode) {
2115         pNotify->OnValueChanged(this, eAttribute, pUINode,
2116                                 pUINode->GetParent());
2117       }
2118       break;
2119     }
2120     case XFA_Element::CheckButton: {
2121       bNeedFindContainer = true;
2122       CXFA_Node* pUINode = GetParent();
2123       if (pUINode) {
2124         pNotify->OnValueChanged(this, eAttribute, pUINode,
2125                                 pUINode->GetParent());
2126       }
2127       break;
2128     }
2129     case XFA_Element::Keep:
2130     case XFA_Element::Bookend:
2131     case XFA_Element::Break:
2132     case XFA_Element::BreakAfter:
2133     case XFA_Element::BreakBefore:
2134     case XFA_Element::Overflow:
2135       bNeedFindContainer = true;
2136       break;
2137     case XFA_Element::Area:
2138     case XFA_Element::Draw:
2139     case XFA_Element::ExclGroup:
2140     case XFA_Element::Field:
2141     case XFA_Element::Subform:
2142     case XFA_Element::SubformSet:
2143       pNotify->OnContainerChanged(this);
2144       pNotify->OnValueChanged(this, eAttribute, this, this);
2145       break;
2146     case XFA_Element::Sharptext:
2147     case XFA_Element::Sharpxml:
2148     case XFA_Element::SharpxHTML: {
2149       CXFA_Node* pTextNode = GetParent();
2150       if (!pTextNode)
2151         return;
2152 
2153       CXFA_Node* pValueNode = pTextNode->GetParent();
2154       if (!pValueNode)
2155         return;
2156 
2157       XFA_Element eType = pValueNode->GetElementType();
2158       if (eType == XFA_Element::Value) {
2159         bNeedFindContainer = true;
2160         CXFA_Node* pNode = pValueNode->GetParent();
2161         if (pNode && pNode->IsContainerNode()) {
2162           if (bScriptModify)
2163             pValueNode = pNode;
2164 
2165           pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
2166         } else {
2167           pNotify->OnValueChanged(this, eAttribute, pNode, pNode->GetParent());
2168         }
2169       } else {
2170         if (eType == XFA_Element::Items) {
2171           CXFA_Node* pNode = pValueNode->GetParent();
2172           if (pNode && pNode->IsContainerNode()) {
2173             pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
2174           }
2175         }
2176       }
2177       break;
2178     }
2179     default:
2180       break;
2181   }
2182 
2183   if (!bNeedFindContainer)
2184     return;
2185 
2186   CXFA_Node* pParent = this;
2187   while (pParent && !pParent->IsContainerNode())
2188     pParent = pParent->GetParent();
2189 
2190   if (pParent)
2191     pNotify->OnContainerChanged(pParent);
2192 }
2193 
SyncValue(const WideString & wsValue,bool bNotify)2194 void CXFA_Node::SyncValue(const WideString& wsValue, bool bNotify) {
2195   WideString wsFormatValue = wsValue;
2196   CXFA_Node* pContainerNode = GetContainerNode();
2197   if (pContainerNode)
2198     wsFormatValue = pContainerNode->GetFormatDataValue(wsValue);
2199 
2200   JSObject()->SetContent(wsValue, wsFormatValue, bNotify, false, true);
2201 }
2202 
GetRawValue()2203 WideString CXFA_Node::GetRawValue() {
2204   return JSObject()->GetContent(false);
2205 }
2206 
GetRotate() const2207 int32_t CXFA_Node::GetRotate() const {
2208   Optional<int32_t> degrees =
2209       JSObject()->TryInteger(XFA_Attribute::Rotate, false);
2210   return degrees ? XFA_MapRotation(*degrees) / 90 * 90 : 0;
2211 }
2212 
GetBorderIfExists() const2213 CXFA_Border* CXFA_Node::GetBorderIfExists() const {
2214   return JSObject()->GetProperty<CXFA_Border>(0, XFA_Element::Border);
2215 }
2216 
GetOrCreateBorderIfPossible()2217 CXFA_Border* CXFA_Node::GetOrCreateBorderIfPossible() {
2218   return JSObject()->GetOrCreateProperty<CXFA_Border>(0, XFA_Element::Border);
2219 }
2220 
GetCaptionIfExists() const2221 CXFA_Caption* CXFA_Node::GetCaptionIfExists() const {
2222   return JSObject()->GetProperty<CXFA_Caption>(0, XFA_Element::Caption);
2223 }
2224 
GetOrCreateFontIfPossible()2225 CXFA_Font* CXFA_Node::GetOrCreateFontIfPossible() {
2226   return JSObject()->GetOrCreateProperty<CXFA_Font>(0, XFA_Element::Font);
2227 }
2228 
GetFontIfExists() const2229 CXFA_Font* CXFA_Node::GetFontIfExists() const {
2230   return JSObject()->GetProperty<CXFA_Font>(0, XFA_Element::Font);
2231 }
2232 
GetFontSize() const2233 float CXFA_Node::GetFontSize() const {
2234   CXFA_Font* font = GetFontIfExists();
2235   float fFontSize = font ? font->GetFontSize() : 10.0f;
2236   return fFontSize < 0.1f ? 10.0f : fFontSize;
2237 }
2238 
GetLineHeight() const2239 float CXFA_Node::GetLineHeight() const {
2240   float fLineHeight = 0;
2241   CXFA_Para* para = GetParaIfExists();
2242   if (para)
2243     fLineHeight = para->GetLineHeight();
2244 
2245   if (fLineHeight < 1)
2246     fLineHeight = GetFontSize() * 1.2f;
2247   return fLineHeight;
2248 }
2249 
GetTextColor() const2250 FX_ARGB CXFA_Node::GetTextColor() const {
2251   CXFA_Font* font = GetFontIfExists();
2252   return font ? font->GetColor() : 0xFF000000;
2253 }
2254 
GetMarginIfExists() const2255 CXFA_Margin* CXFA_Node::GetMarginIfExists() const {
2256   return JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin);
2257 }
2258 
GetParaIfExists() const2259 CXFA_Para* CXFA_Node::GetParaIfExists() const {
2260   return JSObject()->GetProperty<CXFA_Para>(0, XFA_Element::Para);
2261 }
2262 
IsOpenAccess() const2263 bool CXFA_Node::IsOpenAccess() const {
2264   for (auto* pNode = this; pNode; pNode = pNode->GetContainerParent()) {
2265     XFA_AttributeValue iAcc = pNode->JSObject()->GetEnum(XFA_Attribute::Access);
2266     if (iAcc != XFA_AttributeValue::Open)
2267       return false;
2268   }
2269   return true;
2270 }
2271 
GetDefaultValueIfExists()2272 CXFA_Value* CXFA_Node::GetDefaultValueIfExists() {
2273   CXFA_Node* pTemNode = GetTemplateNodeIfExists();
2274   return pTemNode ? pTemNode->JSObject()->GetProperty<CXFA_Value>(
2275                         0, XFA_Element::Value)
2276                   : nullptr;
2277 }
2278 
GetFormValueIfExists() const2279 CXFA_Value* CXFA_Node::GetFormValueIfExists() const {
2280   return JSObject()->GetProperty<CXFA_Value>(0, XFA_Element::Value);
2281 }
2282 
GetCalculateIfExists() const2283 CXFA_Calculate* CXFA_Node::GetCalculateIfExists() const {
2284   return JSObject()->GetProperty<CXFA_Calculate>(0, XFA_Element::Calculate);
2285 }
2286 
GetValidateIfExists() const2287 CXFA_Validate* CXFA_Node::GetValidateIfExists() const {
2288   return JSObject()->GetProperty<CXFA_Validate>(0, XFA_Element::Validate);
2289 }
2290 
GetOrCreateValidateIfPossible()2291 CXFA_Validate* CXFA_Node::GetOrCreateValidateIfPossible() {
2292   return JSObject()->GetOrCreateProperty<CXFA_Validate>(0,
2293                                                         XFA_Element::Validate);
2294 }
2295 
GetBindIfExists() const2296 CXFA_Bind* CXFA_Node::GetBindIfExists() const {
2297   return JSObject()->GetProperty<CXFA_Bind>(0, XFA_Element::Bind);
2298 }
2299 
GetIntactFromKeep(const CXFA_Keep * pKeep,XFA_AttributeValue eLayoutType) const2300 Optional<XFA_AttributeValue> CXFA_Node::GetIntactFromKeep(
2301     const CXFA_Keep* pKeep,
2302     XFA_AttributeValue eLayoutType) const {
2303   Optional<XFA_AttributeValue> intact =
2304       pKeep->JSObject()->TryEnum(XFA_Attribute::Intact, false);
2305   if (!intact.has_value())
2306     return {};
2307 
2308   if (intact.value() != XFA_AttributeValue::None ||
2309       eLayoutType != XFA_AttributeValue::Row ||
2310       m_pDocument->GetCurVersionMode() >= XFA_VERSION_208) {
2311     return intact;
2312   }
2313 
2314   CXFA_Node* pPreviewRow = GetPrevContainerSibling();
2315   if (!pPreviewRow || pPreviewRow->JSObject()->GetEnum(XFA_Attribute::Layout) !=
2316                           XFA_AttributeValue::Row) {
2317     return intact;
2318   }
2319 
2320   Optional<XFA_AttributeValue> value =
2321       pKeep->JSObject()->TryEnum(XFA_Attribute::Previous, false);
2322   if (value && (*value == XFA_AttributeValue::ContentArea ||
2323                 *value == XFA_AttributeValue::PageArea)) {
2324     return XFA_AttributeValue::ContentArea;
2325   }
2326 
2327   CXFA_Keep* pNode =
2328       pPreviewRow->GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
2329   if (!pNode)
2330     return intact;
2331 
2332   Optional<XFA_AttributeValue> ret =
2333       pNode->JSObject()->TryEnum(XFA_Attribute::Next, false);
2334   if (!ret)
2335     return intact;
2336 
2337   return (*ret == XFA_AttributeValue::ContentArea ||
2338           *ret == XFA_AttributeValue::PageArea)
2339              ? XFA_AttributeValue::ContentArea
2340              : intact;
2341 }
2342 
TryWidth()2343 Optional<float> CXFA_Node::TryWidth() {
2344   return JSObject()->TryMeasureAsFloat(XFA_Attribute::W);
2345 }
2346 
TryHeight()2347 Optional<float> CXFA_Node::TryHeight() {
2348   return JSObject()->TryMeasureAsFloat(XFA_Attribute::H);
2349 }
2350 
TryMinWidth()2351 Optional<float> CXFA_Node::TryMinWidth() {
2352   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinW);
2353 }
2354 
TryMinHeight()2355 Optional<float> CXFA_Node::TryMinHeight() {
2356   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinH);
2357 }
2358 
TryMaxWidth()2359 Optional<float> CXFA_Node::TryMaxWidth() {
2360   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxW);
2361 }
2362 
TryMaxHeight()2363 Optional<float> CXFA_Node::TryMaxHeight() {
2364   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxH);
2365 }
2366 
GetExclGroupIfExists()2367 CXFA_Node* CXFA_Node::GetExclGroupIfExists() {
2368   CXFA_Node* pExcl = GetParent();
2369   if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
2370     return nullptr;
2371   return pExcl;
2372 }
2373 
ProcessEvent(CXFA_FFDocView * pDocView,XFA_AttributeValue iActivity,CXFA_EventParam * pEventParam)2374 XFA_EventError CXFA_Node::ProcessEvent(CXFA_FFDocView* pDocView,
2375                                        XFA_AttributeValue iActivity,
2376                                        CXFA_EventParam* pEventParam) {
2377   if (GetElementType() == XFA_Element::Draw)
2378     return XFA_EventError::kNotExist;
2379 
2380   std::vector<CXFA_Event*> eventArray =
2381       GetEventByActivity(iActivity, pEventParam->m_bIsFormReady);
2382   bool first = true;
2383   XFA_EventError iRet = XFA_EventError::kNotExist;
2384   for (CXFA_Event* event : eventArray) {
2385     XFA_EventError result =
2386         ProcessEventInternal(pDocView, iActivity, event, pEventParam);
2387     if (first || result == XFA_EventError::kSuccess)
2388       iRet = result;
2389     first = false;
2390   }
2391   return iRet;
2392 }
2393 
ProcessEventInternal(CXFA_FFDocView * pDocView,XFA_AttributeValue iActivity,CXFA_Event * event,CXFA_EventParam * pEventParam)2394 XFA_EventError CXFA_Node::ProcessEventInternal(CXFA_FFDocView* pDocView,
2395                                                XFA_AttributeValue iActivity,
2396                                                CXFA_Event* event,
2397                                                CXFA_EventParam* pEventParam) {
2398   if (!event)
2399     return XFA_EventError::kNotExist;
2400 
2401   switch (event->GetEventType()) {
2402     case XFA_Element::Execute:
2403       break;
2404     case XFA_Element::Script:
2405       if (iActivity == XFA_AttributeValue::DocClose) {
2406         // Too late, scripting engine already gone.
2407         return XFA_EventError::kNotExist;
2408       }
2409       return ExecuteScript(pDocView, event->GetScriptIfExists(), pEventParam);
2410     case XFA_Element::SignData:
2411       break;
2412     case XFA_Element::Submit: {
2413 // TODO(crbug.com/867485): Submit is disabled for now. Fix it and reenable this
2414 // code.
2415 #ifdef PDF_XFA_ELEMENT_SUBMIT_ENABLED
2416       CXFA_Submit* submit = event->GetSubmitIfExists();
2417       if (!submit)
2418         return XFA_EventError::kNotExist;
2419       return pDocView->GetDoc()->GetDocEnvironment()->Submit(pDocView->GetDoc(),
2420                                                              submit);
2421 #else
2422       return XFA_EventError::kDisabled;
2423 #endif  // PDF_XFA_ELEMENT_SUBMIT_ENABLED
2424     }
2425     default:
2426       break;
2427   }
2428   return XFA_EventError::kNotExist;
2429 }
2430 
ProcessCalculate(CXFA_FFDocView * pDocView)2431 XFA_EventError CXFA_Node::ProcessCalculate(CXFA_FFDocView* pDocView) {
2432   if (GetElementType() == XFA_Element::Draw)
2433     return XFA_EventError::kNotExist;
2434 
2435   CXFA_Calculate* calc = GetCalculateIfExists();
2436   if (!calc)
2437     return XFA_EventError::kNotExist;
2438   if (IsUserInteractive())
2439     return XFA_EventError::kDisabled;
2440 
2441   CXFA_EventParam EventParam;
2442   EventParam.m_eType = XFA_EVENT_Calculate;
2443   XFA_EventError iRet =
2444       ExecuteScript(pDocView, calc->GetScriptIfExists(), &EventParam);
2445   if (iRet != XFA_EventError::kSuccess)
2446     return iRet;
2447 
2448   if (GetRawValue() != EventParam.m_wsResult) {
2449     SetValue(XFA_VALUEPICTURE_Raw, EventParam.m_wsResult);
2450     pDocView->UpdateUIDisplay(this, nullptr);
2451   }
2452   return XFA_EventError::kSuccess;
2453 }
2454 
ProcessScriptTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,XFA_EventError iRet,bool bRetValue,bool bVersionFlag)2455 void CXFA_Node::ProcessScriptTestValidate(CXFA_FFDocView* pDocView,
2456                                           CXFA_Validate* validate,
2457                                           XFA_EventError iRet,
2458                                           bool bRetValue,
2459                                           bool bVersionFlag) {
2460   if (iRet != XFA_EventError::kSuccess)
2461     return;
2462   if (bRetValue)
2463     return;
2464 
2465   IXFA_AppProvider* pAppProvider =
2466       pDocView->GetDoc()->GetApp()->GetAppProvider();
2467   if (!pAppProvider)
2468     return;
2469 
2470   WideString wsTitle = pAppProvider->GetAppTitle();
2471   WideString wsScriptMsg = validate->GetScriptMessageText();
2472   if (validate->GetScriptTest() == XFA_AttributeValue::Warning) {
2473     if (IsUserInteractive())
2474       return;
2475     if (wsScriptMsg.IsEmpty())
2476       wsScriptMsg = GetValidateMessage(false, bVersionFlag);
2477 
2478     if (bVersionFlag) {
2479       pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2480                            static_cast<uint32_t>(AlertIcon::kWarning),
2481                            static_cast<uint32_t>(AlertButton::kOK));
2482       return;
2483     }
2484     if (pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2485                              static_cast<uint32_t>(AlertIcon::kWarning),
2486                              static_cast<uint32_t>(AlertButton::kYesNo)) ==
2487         static_cast<uint32_t>(AlertReturn::kYes)) {
2488       SetFlag(XFA_NodeFlag_UserInteractive);
2489     }
2490     return;
2491   }
2492 
2493   if (wsScriptMsg.IsEmpty())
2494     wsScriptMsg = GetValidateMessage(true, bVersionFlag);
2495   pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2496                        static_cast<uint32_t>(AlertIcon::kError),
2497                        static_cast<uint32_t>(AlertButton::kOK));
2498 }
2499 
ProcessFormatTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,bool bVersionFlag)2500 XFA_EventError CXFA_Node::ProcessFormatTestValidate(CXFA_FFDocView* pDocView,
2501                                                     CXFA_Validate* validate,
2502                                                     bool bVersionFlag) {
2503   WideString wsPicture = validate->GetPicture();
2504   if (wsPicture.IsEmpty())
2505     return XFA_EventError::kNotExist;
2506 
2507   WideString wsRawValue = GetRawValue();
2508   if (wsRawValue.IsEmpty())
2509     return XFA_EventError::kError;
2510 
2511   LocaleIface* pLocale = GetLocale();
2512   if (!pLocale)
2513     return XFA_EventError::kNotExist;
2514 
2515   CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
2516   if (lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale, nullptr))
2517     return XFA_EventError::kSuccess;
2518 
2519   IXFA_AppProvider* pAppProvider =
2520       pDocView->GetDoc()->GetApp()->GetAppProvider();
2521   if (!pAppProvider)
2522     return XFA_EventError::kNotExist;
2523 
2524   WideString wsFormatMsg = validate->GetFormatMessageText();
2525   WideString wsTitle = pAppProvider->GetAppTitle();
2526   if (validate->GetFormatTest() == XFA_AttributeValue::Error) {
2527     if (wsFormatMsg.IsEmpty())
2528       wsFormatMsg = GetValidateMessage(true, bVersionFlag);
2529     pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2530                          static_cast<uint32_t>(AlertIcon::kError),
2531                          static_cast<uint32_t>(AlertButton::kOK));
2532     return XFA_EventError::kError;
2533   }
2534 
2535   if (wsFormatMsg.IsEmpty())
2536     wsFormatMsg = GetValidateMessage(false, bVersionFlag);
2537 
2538   if (bVersionFlag) {
2539     pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2540                          static_cast<uint32_t>(AlertIcon::kWarning),
2541                          static_cast<uint32_t>(AlertButton::kOK));
2542     return XFA_EventError::kError;
2543   }
2544 
2545   if (pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2546                            static_cast<uint32_t>(AlertIcon::kWarning),
2547                            static_cast<uint32_t>(AlertButton::kYesNo)) ==
2548       static_cast<uint32_t>(AlertReturn::kYes)) {
2549     SetFlag(XFA_NodeFlag_UserInteractive);
2550   }
2551 
2552   return XFA_EventError::kError;
2553 }
2554 
ProcessNullTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,int32_t iFlags,bool bVersionFlag)2555 XFA_EventError CXFA_Node::ProcessNullTestValidate(CXFA_FFDocView* pDocView,
2556                                                   CXFA_Validate* validate,
2557                                                   int32_t iFlags,
2558                                                   bool bVersionFlag) {
2559   if (!GetValue(XFA_VALUEPICTURE_Raw).IsEmpty())
2560     return XFA_EventError::kSuccess;
2561   if (m_bIsNull && m_bPreNull)
2562     return XFA_EventError::kSuccess;
2563 
2564   XFA_AttributeValue eNullTest = validate->GetNullTest();
2565   WideString wsNullMsg = validate->GetNullMessageText();
2566   if (iFlags & 0x01) {
2567     XFA_EventError iRet = XFA_EventError::kSuccess;
2568     if (eNullTest != XFA_AttributeValue::Disabled)
2569       iRet = XFA_EventError::kError;
2570 
2571     if (wsNullMsg.IsEmpty())
2572       return iRet;
2573 
2574     if (eNullTest != XFA_AttributeValue::Disabled) {
2575       pDocView->m_arrNullTestMsg.push_back(wsNullMsg);
2576       return XFA_EventError::kError;
2577     }
2578     return XFA_EventError::kSuccess;
2579   }
2580   if (wsNullMsg.IsEmpty() && bVersionFlag &&
2581       eNullTest != XFA_AttributeValue::Disabled) {
2582     return XFA_EventError::kError;
2583   }
2584   IXFA_AppProvider* pAppProvider =
2585       pDocView->GetDoc()->GetApp()->GetAppProvider();
2586   if (!pAppProvider)
2587     return XFA_EventError::kNotExist;
2588 
2589   WideString wsCaptionName;
2590   WideString wsTitle = pAppProvider->GetAppTitle();
2591   switch (eNullTest) {
2592     case XFA_AttributeValue::Error: {
2593       if (wsNullMsg.IsEmpty()) {
2594         wsCaptionName = GetValidateCaptionName(bVersionFlag);
2595         wsNullMsg = wsCaptionName + L" cannot be blank.";
2596       }
2597       pAppProvider->MsgBox(wsNullMsg, wsTitle,
2598                            static_cast<uint32_t>(AlertIcon::kStatus),
2599                            static_cast<uint32_t>(AlertButton::kOK));
2600       return XFA_EventError::kError;
2601     }
2602     case XFA_AttributeValue::Warning: {
2603       if (IsUserInteractive())
2604         return XFA_EventError::kSuccess;
2605 
2606       if (wsNullMsg.IsEmpty()) {
2607         wsCaptionName = GetValidateCaptionName(bVersionFlag);
2608         wsNullMsg = wsCaptionName +
2609                     L" cannot be blank. To ignore validations for " +
2610                     wsCaptionName + L", click Ignore.";
2611       }
2612       if (pAppProvider->MsgBox(wsNullMsg, wsTitle,
2613                                static_cast<uint32_t>(AlertIcon::kWarning),
2614                                static_cast<uint32_t>(AlertButton::kYesNo)) ==
2615           static_cast<uint32_t>(AlertReturn::kYes)) {
2616         SetFlag(XFA_NodeFlag_UserInteractive);
2617       }
2618       return XFA_EventError::kError;
2619     }
2620     case XFA_AttributeValue::Disabled:
2621     default:
2622       break;
2623   }
2624   return XFA_EventError::kSuccess;
2625 }
2626 
ProcessValidate(CXFA_FFDocView * pDocView,int32_t iFlags)2627 XFA_EventError CXFA_Node::ProcessValidate(CXFA_FFDocView* pDocView,
2628                                           int32_t iFlags) {
2629   if (GetElementType() == XFA_Element::Draw)
2630     return XFA_EventError::kNotExist;
2631 
2632   CXFA_Validate* validate = GetValidateIfExists();
2633   if (!validate)
2634     return XFA_EventError::kNotExist;
2635 
2636   bool bInitDoc = validate->NeedsInitApp();
2637   bool bStatus = pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
2638   XFA_EventError iFormat = XFA_EventError::kNotExist;
2639   XFA_EventError iRet = XFA_EventError::kNotExist;
2640   CXFA_Script* script = validate->GetScriptIfExists();
2641   bool bRet = false;
2642   bool hasBoolResult = (bInitDoc || bStatus) && GetRawValue().IsEmpty();
2643   if (script) {
2644     CXFA_EventParam eParam;
2645     eParam.m_eType = XFA_EVENT_Validate;
2646     eParam.m_pTarget = this;
2647     std::tie(iRet, bRet) = ExecuteBoolScript(pDocView, script, &eParam);
2648   }
2649 
2650   XFA_VERSION version = pDocView->GetDoc()->GetXFADoc()->GetCurVersionMode();
2651   bool bVersionFlag = version < XFA_VERSION_208;
2652 
2653   if (bInitDoc) {
2654     validate->ClearFlag(XFA_NodeFlag_NeedsInitApp);
2655   } else {
2656     iFormat = ProcessFormatTestValidate(pDocView, validate, bVersionFlag);
2657     if (!bVersionFlag)
2658       bVersionFlag = pDocView->GetDoc()->GetXFADoc()->is_scripting();
2659     XFA_EventErrorAccumulate(
2660         &iRet,
2661         ProcessNullTestValidate(pDocView, validate, iFlags, bVersionFlag));
2662   }
2663   if (iFormat != XFA_EventError::kSuccess && hasBoolResult)
2664     ProcessScriptTestValidate(pDocView, validate, iRet, bRet, bVersionFlag);
2665 
2666   XFA_EventErrorAccumulate(&iRet, iFormat);
2667   return iRet;
2668 }
2669 
GetValidateCaptionName(bool bVersionFlag)2670 WideString CXFA_Node::GetValidateCaptionName(bool bVersionFlag) {
2671   WideString wsCaptionName;
2672 
2673   if (!bVersionFlag) {
2674     CXFA_Caption* caption = GetCaptionIfExists();
2675     if (caption) {
2676       CXFA_Value* capValue = caption->GetValueIfExists();
2677       if (capValue) {
2678         CXFA_Text* captionText = capValue->GetTextIfExists();
2679         if (captionText)
2680           wsCaptionName = captionText->GetContent();
2681       }
2682     }
2683   }
2684   if (!wsCaptionName.IsEmpty())
2685     return wsCaptionName;
2686   return JSObject()->GetCData(XFA_Attribute::Name);
2687 }
2688 
GetValidateMessage(bool bError,bool bVersionFlag)2689 WideString CXFA_Node::GetValidateMessage(bool bError, bool bVersionFlag) {
2690   WideString wsCaptionName = GetValidateCaptionName(bVersionFlag);
2691   if (bVersionFlag)
2692     return wsCaptionName + L" validation failed";
2693   WideString result =
2694       L"The value you entered for " + wsCaptionName + L" is invalid.";
2695   if (!bError) {
2696     result +=
2697         L" To ignore validations for " + wsCaptionName + L", click Ignore.";
2698   }
2699   return result;
2700 }
2701 
ExecuteScript(CXFA_FFDocView * pDocView,CXFA_Script * script,CXFA_EventParam * pEventParam)2702 XFA_EventError CXFA_Node::ExecuteScript(CXFA_FFDocView* pDocView,
2703                                         CXFA_Script* script,
2704                                         CXFA_EventParam* pEventParam) {
2705   return ExecuteBoolScript(pDocView, script, pEventParam).first;
2706 }
2707 
ExecuteBoolScript(CXFA_FFDocView * pDocView,CXFA_Script * script,CXFA_EventParam * pEventParam)2708 std::pair<XFA_EventError, bool> CXFA_Node::ExecuteBoolScript(
2709     CXFA_FFDocView* pDocView,
2710     CXFA_Script* script,
2711     CXFA_EventParam* pEventParam) {
2712   if (m_ExecuteRecursionDepth > kMaxExecuteRecursion)
2713     return {XFA_EventError::kSuccess, false};
2714 
2715   ASSERT(pEventParam);
2716   if (!script)
2717     return {XFA_EventError::kNotExist, false};
2718   if (script->GetRunAt() == XFA_AttributeValue::Server)
2719     return {XFA_EventError::kDisabled, false};
2720 
2721   WideString wsExpression = script->GetExpression();
2722   if (wsExpression.IsEmpty())
2723     return {XFA_EventError::kNotExist, false};
2724 
2725   CXFA_Script::Type eScriptType = script->GetContentType();
2726   if (eScriptType == CXFA_Script::Type::Unknown)
2727     return {XFA_EventError::kSuccess, false};
2728 
2729   CXFA_FFDoc* pDoc = pDocView->GetDoc();
2730   CFXJSE_Engine* pContext = pDoc->GetXFADoc()->GetScriptContext();
2731   pContext->SetEventParam(pEventParam);
2732   pContext->SetRunAtType(script->GetRunAt());
2733 
2734   std::vector<CXFA_Node*> refNodes;
2735   if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
2736       pEventParam->m_eType == XFA_EVENT_Calculate) {
2737     pContext->SetNodesOfRunScript(&refNodes);
2738   }
2739 
2740   auto pTmpRetValue = pdfium::MakeUnique<CFXJSE_Value>(pContext->GetIsolate());
2741   bool bRet = false;
2742   {
2743     AutoRestorer<uint8_t> restorer(&m_ExecuteRecursionDepth);
2744     ++m_ExecuteRecursionDepth;
2745     bRet = pContext->RunScript(eScriptType, wsExpression.AsStringView(),
2746                                pTmpRetValue.get(), this);
2747   }
2748 
2749   XFA_EventError iRet = XFA_EventError::kError;
2750   if (bRet) {
2751     iRet = XFA_EventError::kSuccess;
2752     if (pEventParam->m_eType == XFA_EVENT_Calculate ||
2753         pEventParam->m_eType == XFA_EVENT_InitCalculate) {
2754       if (!pTmpRetValue->IsUndefined()) {
2755         if (!pTmpRetValue->IsNull())
2756           pEventParam->m_wsResult = pTmpRetValue->ToWideString();
2757 
2758         iRet = XFA_EventError::kSuccess;
2759       } else {
2760         iRet = XFA_EventError::kError;
2761       }
2762       if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
2763         if ((iRet == XFA_EventError::kSuccess) &&
2764             (GetRawValue() != pEventParam->m_wsResult)) {
2765           SetValue(XFA_VALUEPICTURE_Raw, pEventParam->m_wsResult);
2766           pDocView->AddValidateNode(this);
2767         }
2768       }
2769       for (CXFA_Node* pRefNode : refNodes) {
2770         if (pRefNode == this)
2771           continue;
2772 
2773         CXFA_CalcData* pGlobalData = pRefNode->JSObject()->GetCalcData();
2774         if (!pGlobalData) {
2775           pRefNode->JSObject()->SetCalcData(
2776               pdfium::MakeUnique<CXFA_CalcData>());
2777           pGlobalData = pRefNode->JSObject()->GetCalcData();
2778         }
2779         if (!pdfium::ContainsValue(pGlobalData->m_Globals, this))
2780           pGlobalData->m_Globals.push_back(this);
2781       }
2782     }
2783   }
2784   pContext->SetNodesOfRunScript(nullptr);
2785   pContext->SetEventParam(nullptr);
2786 
2787   return {iRet, pTmpRetValue->IsBoolean() && pTmpRetValue->ToBoolean()};
2788 }
2789 
2790 std::pair<XFA_FFWidgetType, CXFA_Ui*>
CreateChildUIAndValueNodesIfNeeded()2791 CXFA_Node::CreateChildUIAndValueNodesIfNeeded() {
2792   XFA_Element eType = GetElementType();
2793   ASSERT(eType == XFA_Element::Field || eType == XFA_Element::Draw);
2794 
2795   // Both Field and Draw have a UI property. We should always be able to
2796   // retrieve or create the UI element. If we can't something is wrong.
2797   CXFA_Ui* pUI = JSObject()->GetOrCreateProperty<CXFA_Ui>(0, XFA_Element::Ui);
2798   ASSERT(pUI);
2799 
2800   CXFA_Node* pUIChild = nullptr;
2801   // Search through the children of the UI node to see if we have any of our
2802   // One-Of entries. If so, that is the node associated with our UI.
2803   for (CXFA_Node* pChild = pUI->GetFirstChild(); pChild;
2804        pChild = pChild->GetNextSibling()) {
2805     if (pUI->IsAOneOfChild(pChild)) {
2806       pUIChild = pChild;
2807       break;
2808     }
2809   }
2810 
2811   XFA_FFWidgetType widget_type = XFA_FFWidgetType::kNone;
2812   XFA_Element expected_ui_child_type = XFA_Element::Unknown;
2813 
2814   // Both Field and Draw nodes have a Value child. So, we should either always
2815   // have it, or always create it. If we don't get the Value child for some
2816   // reason something has gone really wrong.
2817   CXFA_Value* value =
2818       JSObject()->GetOrCreateProperty<CXFA_Value>(0, XFA_Element::Value);
2819   ASSERT(value);
2820 
2821   // The Value nodes only have One-Of children. So, if we have a first child
2822   // that child must be the type we want to use.
2823   CXFA_Node* child = value->GetFirstChild();
2824   if (child) {
2825     switch (child->GetElementType()) {
2826       case XFA_Element::Boolean:
2827         expected_ui_child_type = XFA_Element::CheckButton;
2828         break;
2829       case XFA_Element::Integer:
2830       case XFA_Element::Decimal:
2831       case XFA_Element::Float:
2832         expected_ui_child_type = XFA_Element::NumericEdit;
2833         break;
2834       case XFA_Element::ExData:
2835       case XFA_Element::Text:
2836         expected_ui_child_type = XFA_Element::TextEdit;
2837         widget_type = XFA_FFWidgetType::kText;
2838         break;
2839       case XFA_Element::Date:
2840       case XFA_Element::Time:
2841       case XFA_Element::DateTime:
2842         expected_ui_child_type = XFA_Element::DateTimeEdit;
2843         break;
2844       case XFA_Element::Image:
2845         expected_ui_child_type = XFA_Element::ImageEdit;
2846         widget_type = XFA_FFWidgetType::kImage;
2847         break;
2848       case XFA_Element::Arc:
2849         expected_ui_child_type = XFA_Element::DefaultUi;
2850         widget_type = XFA_FFWidgetType::kArc;
2851         break;
2852       case XFA_Element::Line:
2853         expected_ui_child_type = XFA_Element::DefaultUi;
2854         widget_type = XFA_FFWidgetType::kLine;
2855         break;
2856       case XFA_Element::Rectangle:
2857         expected_ui_child_type = XFA_Element::DefaultUi;
2858         widget_type = XFA_FFWidgetType::kRectangle;
2859         break;
2860       default:
2861         NOTREACHED();
2862         break;
2863     }
2864   }
2865 
2866   if (eType == XFA_Element::Draw) {
2867     if (pUIChild && pUIChild->GetElementType() == XFA_Element::TextEdit) {
2868       widget_type = XFA_FFWidgetType::kText;
2869     } else if (pUIChild &&
2870                pUIChild->GetElementType() == XFA_Element::ImageEdit) {
2871       widget_type = XFA_FFWidgetType::kImage;
2872     } else if (widget_type == XFA_FFWidgetType::kNone) {
2873       widget_type = XFA_FFWidgetType::kText;
2874     }
2875   } else if (eType == XFA_Element::Field) {
2876     if (pUIChild && pUIChild->GetElementType() == XFA_Element::DefaultUi) {
2877       widget_type = XFA_FFWidgetType::kTextEdit;
2878     } else if (pUIChild) {
2879       widget_type = pUIChild->GetDefaultFFWidgetType();
2880     } else if (expected_ui_child_type == XFA_Element::Unknown) {
2881       widget_type = XFA_FFWidgetType::kTextEdit;
2882     }
2883   } else {
2884     NOTREACHED();
2885   }
2886 
2887   if (!pUIChild) {
2888     if (expected_ui_child_type == XFA_Element::Unknown)
2889       expected_ui_child_type = XFA_Element::TextEdit;
2890     pUIChild = pUI->JSObject()->GetOrCreateProperty<CXFA_Node>(
2891         0, expected_ui_child_type);
2892   }
2893 
2894   CreateValueNodeIfNeeded(value, pUIChild);
2895   return {widget_type, pUI};
2896 }
2897 
GetDefaultFFWidgetType() const2898 XFA_FFWidgetType CXFA_Node::GetDefaultFFWidgetType() const {
2899   NOTREACHED();
2900   return XFA_FFWidgetType::kNone;
2901 }
2902 
CreateUINodeIfNeeded(CXFA_Ui * ui,XFA_Element type)2903 CXFA_Node* CXFA_Node::CreateUINodeIfNeeded(CXFA_Ui* ui, XFA_Element type) {
2904   return ui->JSObject()->GetOrCreateProperty<CXFA_Node>(0, type);
2905 }
2906 
CreateValueNodeIfNeeded(CXFA_Value * value,CXFA_Node * pUIChild)2907 void CXFA_Node::CreateValueNodeIfNeeded(CXFA_Value* value,
2908                                         CXFA_Node* pUIChild) {
2909   // Value nodes only have one child. If we have one already we're done.
2910   if (value->GetFirstChild())
2911     return;
2912 
2913   // Create the Value node for our UI if needed.
2914   XFA_Element valueType = pUIChild->GetValueNodeType();
2915   if (pUIChild->GetElementType() == XFA_Element::CheckButton) {
2916     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
2917     if (pItems) {
2918       CXFA_Node* pItem =
2919           pItems->GetChild<CXFA_Node>(0, XFA_Element::Unknown, false);
2920       if (pItem)
2921         valueType = pItem->GetElementType();
2922     }
2923   }
2924   value->JSObject()->GetOrCreateProperty<CXFA_Node>(0, valueType);
2925 }
2926 
GetValueNodeType() const2927 XFA_Element CXFA_Node::GetValueNodeType() const {
2928   return XFA_Element::Text;
2929 }
2930 
GetUIChildNode()2931 CXFA_Node* CXFA_Node::GetUIChildNode() {
2932   ASSERT(HasCreatedUIWidget());
2933 
2934   if (ff_widget_type_ != XFA_FFWidgetType::kNone)
2935     return ui_ ? ui_->GetFirstChild() : nullptr;
2936 
2937   XFA_Element type = GetElementType();
2938   if (type == XFA_Element::Field || type == XFA_Element::Draw) {
2939     std::tie(ff_widget_type_, ui_) = CreateChildUIAndValueNodesIfNeeded();
2940   } else if (type == XFA_Element::Subform) {
2941     ff_widget_type_ = XFA_FFWidgetType::kSubform;
2942   } else if (type == XFA_Element::ExclGroup) {
2943     ff_widget_type_ = XFA_FFWidgetType::kExclGroup;
2944   } else {
2945     NOTREACHED();
2946   }
2947   return ui_ ? ui_->GetFirstChild() : nullptr;
2948 }
2949 
GetFFWidgetType()2950 XFA_FFWidgetType CXFA_Node::GetFFWidgetType() {
2951   GetUIChildNode();
2952   return ff_widget_type_;
2953 }
2954 
GetUIBorder()2955 CXFA_Border* CXFA_Node::GetUIBorder() {
2956   CXFA_Node* pUIChild = GetUIChildNode();
2957   return pUIChild ? pUIChild->JSObject()->GetProperty<CXFA_Border>(
2958                         0, XFA_Element::Border)
2959                   : nullptr;
2960 }
2961 
GetUIMargin()2962 CFX_RectF CXFA_Node::GetUIMargin() {
2963   CXFA_Node* pUIChild = GetUIChildNode();
2964   if (!pUIChild)
2965     return CFX_RectF();
2966 
2967   CXFA_Margin* mgUI =
2968       pUIChild->JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin);
2969   if (!mgUI)
2970     return CFX_RectF();
2971 
2972   CXFA_Border* border = GetUIBorder();
2973   if (border && border->GetPresence() != XFA_AttributeValue::Visible)
2974     return CFX_RectF();
2975 
2976   Optional<float> left = mgUI->TryLeftInset();
2977   Optional<float> top = mgUI->TryTopInset();
2978   Optional<float> right = mgUI->TryRightInset();
2979   Optional<float> bottom = mgUI->TryBottomInset();
2980   if (border) {
2981     bool bVisible = false;
2982     float fThickness = 0;
2983     XFA_AttributeValue iType = XFA_AttributeValue::Unknown;
2984     std::tie(iType, bVisible, fThickness) = border->Get3DStyle();
2985     if (!left || !top || !right || !bottom) {
2986       std::vector<CXFA_Stroke*> strokes = border->GetStrokes();
2987       if (!top)
2988         top = GetEdgeThickness(strokes, bVisible, 0);
2989       if (!right)
2990         right = GetEdgeThickness(strokes, bVisible, 1);
2991       if (!bottom)
2992         bottom = GetEdgeThickness(strokes, bVisible, 2);
2993       if (!left)
2994         left = GetEdgeThickness(strokes, bVisible, 3);
2995     }
2996   }
2997   return CFX_RectF(left.value_or(0.0), top.value_or(0.0), right.value_or(0.0),
2998                    bottom.value_or(0.0));
2999 }
3000 
GetEventByActivity(XFA_AttributeValue iActivity,bool bIsFormReady)3001 std::vector<CXFA_Event*> CXFA_Node::GetEventByActivity(
3002     XFA_AttributeValue iActivity,
3003     bool bIsFormReady) {
3004   std::vector<CXFA_Event*> events;
3005   for (CXFA_Node* node : GetNodeListForType(XFA_Element::Event)) {
3006     auto* event = static_cast<CXFA_Event*>(node);
3007     if (event->GetActivity() != iActivity)
3008       continue;
3009 
3010     if (iActivity != XFA_AttributeValue::Ready) {
3011       events.push_back(event);
3012       continue;
3013     }
3014 
3015     WideString wsRef = event->GetRef();
3016     if (bIsFormReady) {
3017       if (wsRef == WideStringView(L"$form"))
3018         events.push_back(event);
3019       continue;
3020     }
3021 
3022     if (wsRef == WideStringView(L"$layout"))
3023       events.push_back(event);
3024   }
3025   return events;
3026 }
3027 
ResetData()3028 void CXFA_Node::ResetData() {
3029   WideString wsValue;
3030   switch (GetFFWidgetType()) {
3031     case XFA_FFWidgetType::kImageEdit: {
3032       CXFA_Value* imageValue = GetDefaultValueIfExists();
3033       CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
3034       WideString wsContentType, wsHref;
3035       if (image) {
3036         wsValue = image->GetContent();
3037         wsContentType = image->GetContentType();
3038         wsHref = image->GetHref();
3039       }
3040       SetImageEdit(wsContentType, wsHref, wsValue);
3041       break;
3042     }
3043     case XFA_FFWidgetType::kExclGroup: {
3044       CXFA_Node* pNextChild = GetFirstContainerChild();
3045       while (pNextChild) {
3046         CXFA_Node* pChild = pNextChild;
3047         if (!pChild->IsWidgetReady())
3048           continue;
3049 
3050         bool done = false;
3051         if (wsValue.IsEmpty()) {
3052           CXFA_Value* defValue = pChild->GetDefaultValueIfExists();
3053           if (defValue) {
3054             wsValue = defValue->GetChildValueContent();
3055             SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3056             pChild->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3057             done = true;
3058           }
3059         }
3060         if (!done) {
3061           CXFA_Items* pItems =
3062               pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3063           if (!pItems)
3064             continue;
3065 
3066           WideString itemText;
3067           if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
3068             itemText =
3069                 pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
3070                     ->JSObject()
3071                     ->GetContent(false);
3072           }
3073           pChild->SetValue(XFA_VALUEPICTURE_Raw, itemText);
3074         }
3075         pNextChild = pChild->GetNextContainerSibling();
3076       }
3077       break;
3078     }
3079     case XFA_FFWidgetType::kChoiceList:
3080       ClearAllSelections();
3081       FALLTHROUGH;
3082     default: {
3083       CXFA_Value* defValue = GetDefaultValueIfExists();
3084       if (defValue)
3085         wsValue = defValue->GetChildValueContent();
3086 
3087       SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3088       break;
3089     }
3090   }
3091 }
3092 
SetImageEdit(const WideString & wsContentType,const WideString & wsHref,const WideString & wsData)3093 void CXFA_Node::SetImageEdit(const WideString& wsContentType,
3094                              const WideString& wsHref,
3095                              const WideString& wsData) {
3096   CXFA_Value* formValue = GetFormValueIfExists();
3097   CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
3098   if (image) {
3099     image->SetContentType(WideString(wsContentType));
3100     image->SetHref(wsHref);
3101   }
3102 
3103   JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true, false, true);
3104 
3105   CXFA_Node* pBind = GetBindData();
3106   if (!pBind) {
3107     if (image)
3108       image->SetTransferEncoding(XFA_AttributeValue::Base64);
3109     return;
3110   }
3111   pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
3112                               false);
3113   CXFA_Node* pHrefNode = pBind->GetFirstChild();
3114   if (pHrefNode) {
3115     pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref, false, false);
3116     return;
3117   }
3118   CFX_XMLElement* pElement = ToXMLElement(pBind->GetXMLMappingNode());
3119   pElement->SetAttribute(L"href", wsHref);
3120 }
3121 
CalcCaptionSize(CXFA_FFDoc * doc,CFX_SizeF * pszCap)3122 void CXFA_Node::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF* pszCap) {
3123   CXFA_Caption* caption = GetCaptionIfExists();
3124   if (!caption || !caption->IsVisible())
3125     return;
3126 
3127   LoadCaption(doc);
3128 
3129   const float fCapReserve = caption->GetReserve();
3130   const XFA_AttributeValue iCapPlacement = caption->GetPlacementType();
3131   const bool bReserveExit = fCapReserve > 0.01;
3132   const bool bVert = iCapPlacement == XFA_AttributeValue::Top ||
3133                      iCapPlacement == XFA_AttributeValue::Bottom;
3134   CXFA_TextLayout* pCapTextLayout =
3135       m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout.get();
3136   if (pCapTextLayout) {
3137     if (!bVert && GetFFWidgetType() != XFA_FFWidgetType::kButton)
3138       pszCap->width = fCapReserve;
3139 
3140     CFX_SizeF minSize;
3141     *pszCap = pCapTextLayout->CalcSize(minSize, *pszCap);
3142     if (bReserveExit)
3143       bVert ? pszCap->height = fCapReserve : pszCap->width = fCapReserve;
3144   } else {
3145     float fFontSize = 10.0f;
3146     CXFA_Font* font = caption->GetFontIfExists();
3147     if (font) {
3148       fFontSize = font->GetFontSize();
3149     } else {
3150       CXFA_Font* widgetfont = GetFontIfExists();
3151       if (widgetfont)
3152         fFontSize = widgetfont->GetFontSize();
3153     }
3154 
3155     if (bVert) {
3156       pszCap->height = fCapReserve > 0 ? fCapReserve : fFontSize;
3157     } else {
3158       pszCap->width = fCapReserve > 0 ? fCapReserve : 0;
3159       pszCap->height = fFontSize;
3160     }
3161   }
3162 
3163   CXFA_Margin* captionMargin = caption->GetMarginIfExists();
3164   if (!captionMargin)
3165     return;
3166 
3167   float fLeftInset = captionMargin->GetLeftInset();
3168   float fTopInset = captionMargin->GetTopInset();
3169   float fRightInset = captionMargin->GetRightInset();
3170   float fBottomInset = captionMargin->GetBottomInset();
3171   if (bReserveExit) {
3172     bVert ? (pszCap->width += fLeftInset + fRightInset)
3173           : (pszCap->height += fTopInset + fBottomInset);
3174   } else {
3175     pszCap->width += fLeftInset + fRightInset;
3176     pszCap->height += fTopInset + fBottomInset;
3177   }
3178 }
3179 
CalculateFieldAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3180 bool CXFA_Node::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3181   CFX_SizeF szCap;
3182   CalcCaptionSize(doc, &szCap);
3183 
3184   CFX_RectF rtUIMargin = GetUIMargin();
3185   pSize->width += rtUIMargin.left + rtUIMargin.width;
3186   pSize->height += rtUIMargin.top + rtUIMargin.height;
3187   if (szCap.width > 0 && szCap.height > 0) {
3188     CXFA_Caption* caption = GetCaptionIfExists();
3189     XFA_AttributeValue placement = caption
3190                                        ? caption->GetPlacementType()
3191                                        : CXFA_Caption::kDefaultPlacementType;
3192     switch (placement) {
3193       case XFA_AttributeValue::Left:
3194       case XFA_AttributeValue::Right:
3195       case XFA_AttributeValue::Inline: {
3196         pSize->width += szCap.width;
3197         pSize->height = std::max(pSize->height, szCap.height);
3198       } break;
3199       case XFA_AttributeValue::Top:
3200       case XFA_AttributeValue::Bottom: {
3201         pSize->height += szCap.height;
3202         pSize->width = std::max(pSize->width, szCap.width);
3203         break;
3204       }
3205       default:
3206         break;
3207     }
3208   }
3209   return CalculateWidgetAutoSize(pSize);
3210 }
3211 
CalculateWidgetAutoSize(CFX_SizeF * pSize)3212 bool CXFA_Node::CalculateWidgetAutoSize(CFX_SizeF* pSize) {
3213   CXFA_Margin* margin = GetMarginIfExists();
3214   if (margin) {
3215     pSize->width += margin->GetLeftInset() + margin->GetRightInset();
3216     pSize->height += margin->GetTopInset() + margin->GetBottomInset();
3217   }
3218 
3219   CXFA_Para* para = GetParaIfExists();
3220   if (para)
3221     pSize->width += para->GetMarginLeft() + para->GetTextIndent();
3222 
3223   Optional<float> width = TryWidth();
3224   if (width) {
3225     pSize->width = *width;
3226   } else {
3227     Optional<float> min = TryMinWidth();
3228     if (min)
3229       pSize->width = std::max(pSize->width, *min);
3230 
3231     Optional<float> max = TryMaxWidth();
3232     if (max && *max > 0)
3233       pSize->width = std::min(pSize->width, *max);
3234   }
3235 
3236   Optional<float> height = TryHeight();
3237   if (height) {
3238     pSize->height = *height;
3239   } else {
3240     Optional<float> min = TryMinHeight();
3241     if (min)
3242       pSize->height = std::max(pSize->height, *min);
3243 
3244     Optional<float> max = TryMaxHeight();
3245     if (max && *max > 0)
3246       pSize->height = std::min(pSize->height, *max);
3247   }
3248   return true;
3249 }
3250 
CalculateTextContentSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3251 void CXFA_Node::CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3252   float fFontSize = GetFontSize();
3253   WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
3254   if (wsText.IsEmpty()) {
3255     pSize->height += fFontSize;
3256     return;
3257   }
3258 
3259   if (wsText.Back() == L'\n')
3260     wsText += L'\n';
3261 
3262   CXFA_FieldLayoutData* layoutData = m_pLayoutData->AsFieldLayoutData();
3263   if (!layoutData->m_pTextOut) {
3264     layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
3265     CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
3266     pTextOut->SetFont(GetFDEFont(doc));
3267     pTextOut->SetFontSize(fFontSize);
3268     pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
3269     pTextOut->SetLineSpace(GetLineHeight());
3270 
3271     FDE_TextStyle dwStyles;
3272     dwStyles.last_line_height_ = true;
3273     if (GetFFWidgetType() == XFA_FFWidgetType::kTextEdit && IsMultiLine())
3274       dwStyles.line_wrap_ = true;
3275 
3276     pTextOut->SetStyles(dwStyles);
3277   }
3278   layoutData->m_pTextOut->CalcLogicSize(wsText.AsStringView(), pSize);
3279 }
3280 
CalculateTextEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3281 bool CXFA_Node::CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3282   if (pSize->width > 0) {
3283     CFX_SizeF szOrz = *pSize;
3284     CFX_SizeF szCap;
3285     CalcCaptionSize(doc, &szCap);
3286     bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
3287     XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3288     if (bCapExit) {
3289       CXFA_Caption* caption = GetCaptionIfExists();
3290       iCapPlacement = caption ? caption->GetPlacementType()
3291                               : CXFA_Caption::kDefaultPlacementType;
3292       switch (iCapPlacement) {
3293         case XFA_AttributeValue::Left:
3294         case XFA_AttributeValue::Right:
3295         case XFA_AttributeValue::Inline: {
3296           pSize->width -= szCap.width;
3297           break;
3298         }
3299         default:
3300           break;
3301       }
3302     }
3303     CFX_RectF rtUIMargin = GetUIMargin();
3304     pSize->width -= rtUIMargin.left + rtUIMargin.width;
3305     CXFA_Margin* margin = GetMarginIfExists();
3306     if (margin)
3307       pSize->width -= margin->GetLeftInset() + margin->GetRightInset();
3308 
3309     CalculateTextContentSize(doc, pSize);
3310     pSize->height += rtUIMargin.top + rtUIMargin.height;
3311     if (bCapExit) {
3312       switch (iCapPlacement) {
3313         case XFA_AttributeValue::Left:
3314         case XFA_AttributeValue::Right:
3315         case XFA_AttributeValue::Inline: {
3316           pSize->height = std::max(pSize->height, szCap.height);
3317         } break;
3318         case XFA_AttributeValue::Top:
3319         case XFA_AttributeValue::Bottom: {
3320           pSize->height += szCap.height;
3321           break;
3322         }
3323         default:
3324           break;
3325       }
3326     }
3327     pSize->width = szOrz.width;
3328     return CalculateWidgetAutoSize(pSize);
3329   }
3330   CalculateTextContentSize(doc, pSize);
3331   return CalculateFieldAutoSize(doc, pSize);
3332 }
3333 
CalculateCheckButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3334 bool CXFA_Node::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc,
3335                                              CFX_SizeF* pSize) {
3336   float fCheckSize = GetCheckButtonSize();
3337   *pSize = CFX_SizeF(fCheckSize, fCheckSize);
3338   return CalculateFieldAutoSize(doc, pSize);
3339 }
3340 
CalculatePushButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3341 bool CXFA_Node::CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3342   CalcCaptionSize(doc, pSize);
3343   return CalculateWidgetAutoSize(pSize);
3344 }
3345 
CalculateImageSize(float img_width,float img_height,const CFX_Size & dpi)3346 CFX_SizeF CXFA_Node::CalculateImageSize(float img_width,
3347                                         float img_height,
3348                                         const CFX_Size& dpi) {
3349   CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi.width),
3350                     XFA_UnitPx2Pt(img_height, dpi.height));
3351 
3352   CFX_RectF rtFit;
3353   Optional<float> width = TryWidth();
3354   if (width) {
3355     rtFit.width = *width;
3356     GetWidthWithoutMargin(rtFit.width);
3357   } else {
3358     rtFit.width = rtImage.width;
3359   }
3360 
3361   Optional<float> height = TryHeight();
3362   if (height) {
3363     rtFit.height = *height;
3364     GetHeightWithoutMargin(rtFit.height);
3365   } else {
3366     rtFit.height = rtImage.height;
3367   }
3368 
3369   return rtFit.Size();
3370 }
3371 
CalculateImageAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3372 bool CXFA_Node::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3373   if (!GetImageImage())
3374     LoadImageImage(doc);
3375 
3376   pSize->clear();
3377   RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
3378   if (!pBitmap)
3379     return CalculateWidgetAutoSize(pSize);
3380 
3381   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3382                               GetImageDpi());
3383   return CalculateWidgetAutoSize(pSize);
3384 }
3385 
CalculateImageEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3386 bool CXFA_Node::CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3387   if (!GetImageEditImage())
3388     LoadImageEditImage(doc);
3389 
3390   pSize->clear();
3391   RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
3392   if (!pBitmap)
3393     return CalculateFieldAutoSize(doc, pSize);
3394 
3395   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3396                               GetImageEditDpi());
3397   return CalculateFieldAutoSize(doc, pSize);
3398 }
3399 
LoadImageImage(CXFA_FFDoc * doc)3400 bool CXFA_Node::LoadImageImage(CXFA_FFDoc* doc) {
3401   InitLayoutData();
3402   return m_pLayoutData->AsImageLayoutData()->LoadImageData(doc, this);
3403 }
3404 
LoadImageEditImage(CXFA_FFDoc * doc)3405 bool CXFA_Node::LoadImageEditImage(CXFA_FFDoc* doc) {
3406   InitLayoutData();
3407   return m_pLayoutData->AsFieldLayoutData()->AsImageEditData()->LoadImageData(
3408       doc, this);
3409 }
3410 
GetImageDpi() const3411 CFX_Size CXFA_Node::GetImageDpi() const {
3412   CXFA_ImageLayoutData* pData = m_pLayoutData->AsImageLayoutData();
3413   return CFX_Size(pData->m_iImageXDpi, pData->m_iImageYDpi);
3414 }
3415 
GetImageEditDpi() const3416 CFX_Size CXFA_Node::GetImageEditDpi() const {
3417   CXFA_ImageEditData* pData =
3418       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3419   return CFX_Size(pData->m_iImageXDpi, pData->m_iImageYDpi);
3420 }
3421 
CalculateWidgetAutoWidth(float fWidthCalc)3422 float CXFA_Node::CalculateWidgetAutoWidth(float fWidthCalc) {
3423   CXFA_Margin* margin = GetMarginIfExists();
3424   if (margin)
3425     fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
3426 
3427   Optional<float> min = TryMinWidth();
3428   if (min)
3429     fWidthCalc = std::max(fWidthCalc, *min);
3430 
3431   Optional<float> max = TryMaxWidth();
3432   if (max && *max > 0)
3433     fWidthCalc = std::min(fWidthCalc, *max);
3434 
3435   return fWidthCalc;
3436 }
3437 
GetWidthWithoutMargin(float fWidthCalc) const3438 float CXFA_Node::GetWidthWithoutMargin(float fWidthCalc) const {
3439   CXFA_Margin* margin = GetMarginIfExists();
3440   if (margin)
3441     fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
3442   return fWidthCalc;
3443 }
3444 
CalculateWidgetAutoHeight(float fHeightCalc)3445 float CXFA_Node::CalculateWidgetAutoHeight(float fHeightCalc) {
3446   CXFA_Margin* margin = GetMarginIfExists();
3447   if (margin)
3448     fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
3449 
3450   Optional<float> min = TryMinHeight();
3451   if (min)
3452     fHeightCalc = std::max(fHeightCalc, *min);
3453 
3454   Optional<float> max = TryMaxHeight();
3455   if (max && *max > 0)
3456     fHeightCalc = std::min(fHeightCalc, *max);
3457 
3458   return fHeightCalc;
3459 }
3460 
GetHeightWithoutMargin(float fHeightCalc) const3461 float CXFA_Node::GetHeightWithoutMargin(float fHeightCalc) const {
3462   CXFA_Margin* margin = GetMarginIfExists();
3463   if (margin)
3464     fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
3465   return fHeightCalc;
3466 }
3467 
StartWidgetLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3468 void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
3469                                   float* pCalcWidth,
3470                                   float* pCalcHeight) {
3471   InitLayoutData();
3472 
3473   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3474     m_pLayoutData->m_fWidgetHeight = TryHeight().value_or(-1);
3475     StartTextLayout(doc, pCalcWidth, pCalcHeight);
3476     return;
3477   }
3478   if (*pCalcWidth > 0 && *pCalcHeight > 0)
3479     return;
3480 
3481   m_pLayoutData->m_fWidgetHeight = -1;
3482   float fWidth = 0;
3483   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3484     Optional<float> height = TryHeight();
3485     if (height) {
3486       *pCalcHeight = *height;
3487     } else {
3488       CFX_SizeF size = CalculateAccWidthAndHeight(doc, *pCalcWidth);
3489       *pCalcWidth = size.width;
3490       *pCalcHeight = size.height;
3491     }
3492 
3493     m_pLayoutData->m_fWidgetHeight = *pCalcHeight;
3494     return;
3495   }
3496   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3497     Optional<float> height;
3498     Optional<float> width = TryWidth();
3499     if (width) {
3500       fWidth = *width;
3501 
3502       height = TryHeight();
3503       if (height)
3504         *pCalcHeight = *height;
3505     }
3506     if (!width || !height) {
3507       CFX_SizeF size = CalculateAccWidthAndHeight(doc, fWidth);
3508       *pCalcWidth = size.width;
3509       *pCalcHeight = size.height;
3510     } else {
3511       *pCalcWidth = fWidth;
3512     }
3513   }
3514   m_pLayoutData->m_fWidgetHeight = *pCalcHeight;
3515 }
3516 
CalculateAccWidthAndHeight(CXFA_FFDoc * doc,float fWidth)3517 CFX_SizeF CXFA_Node::CalculateAccWidthAndHeight(CXFA_FFDoc* doc, float fWidth) {
3518   CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
3519   switch (GetFFWidgetType()) {
3520     case XFA_FFWidgetType::kBarcode:
3521     case XFA_FFWidgetType::kChoiceList:
3522     case XFA_FFWidgetType::kSignature:
3523       CalculateFieldAutoSize(doc, &sz);
3524       break;
3525     case XFA_FFWidgetType::kImageEdit:
3526       CalculateImageEditAutoSize(doc, &sz);
3527       break;
3528     case XFA_FFWidgetType::kButton:
3529       CalculatePushButtonAutoSize(doc, &sz);
3530       break;
3531     case XFA_FFWidgetType::kCheckButton:
3532       CalculateCheckButtonAutoSize(doc, &sz);
3533       break;
3534     case XFA_FFWidgetType::kDateTimeEdit:
3535     case XFA_FFWidgetType::kNumericEdit:
3536     case XFA_FFWidgetType::kPasswordEdit:
3537     case XFA_FFWidgetType::kTextEdit:
3538       CalculateTextEditAutoSize(doc, &sz);
3539       break;
3540     case XFA_FFWidgetType::kImage:
3541       CalculateImageAutoSize(doc, &sz);
3542       break;
3543     case XFA_FFWidgetType::kArc:
3544     case XFA_FFWidgetType::kLine:
3545     case XFA_FFWidgetType::kRectangle:
3546     case XFA_FFWidgetType::kSubform:
3547     case XFA_FFWidgetType::kExclGroup:
3548       CalculateWidgetAutoSize(&sz);
3549       break;
3550     case XFA_FFWidgetType::kText:
3551     case XFA_FFWidgetType::kNone:
3552       break;
3553   }
3554 
3555   m_pLayoutData->m_fWidgetHeight = sz.height;
3556   return sz;
3557 }
3558 
FindSplitPos(CXFA_FFDocView * pDocView,size_t szBlockIndex,float fCalcHeight)3559 Optional<float> CXFA_Node::FindSplitPos(CXFA_FFDocView* pDocView,
3560                                         size_t szBlockIndex,
3561                                         float fCalcHeight) {
3562   if (GetFFWidgetType() == XFA_FFWidgetType::kSubform)
3563     return pdfium::nullopt;
3564 
3565   switch (GetFFWidgetType()) {
3566     case XFA_FFWidgetType::kText:
3567     case XFA_FFWidgetType::kTextEdit:
3568     case XFA_FFWidgetType::kNumericEdit:
3569     case XFA_FFWidgetType::kPasswordEdit:
3570       break;
3571     default:
3572       return 0.0f;
3573   }
3574 
3575   float fTopInset = 0;
3576   float fBottomInset = 0;
3577   if (szBlockIndex == 0) {
3578     CXFA_Margin* margin = GetMarginIfExists();
3579     if (margin) {
3580       fTopInset = margin->GetTopInset();
3581       fBottomInset = margin->GetBottomInset();
3582     }
3583 
3584     CFX_RectF rtUIMargin = GetUIMargin();
3585     fTopInset += rtUIMargin.top;
3586     fBottomInset += rtUIMargin.width;
3587   }
3588   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3589     float fHeight = fCalcHeight;
3590     if (szBlockIndex == 0) {
3591       fCalcHeight -= fTopInset;
3592       fCalcHeight = std::max(fCalcHeight, 0.0f);
3593     }
3594     CXFA_TextLayout* pTextLayout =
3595         m_pLayoutData->AsTextLayoutData()->GetTextLayout();
3596     fCalcHeight = pTextLayout->DoSplitLayout(
3597         szBlockIndex, fCalcHeight, m_pLayoutData->m_fWidgetHeight - fTopInset);
3598     if (fCalcHeight != 0) {
3599       if (szBlockIndex == 0)
3600         fCalcHeight += fTopInset;
3601       if (fabs(fHeight - fCalcHeight) < kXFAWidgetPrecision)
3602         return pdfium::nullopt;
3603     }
3604     return fCalcHeight;
3605   }
3606 
3607   XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3608   float fCapReserve = 0;
3609   if (szBlockIndex == 0) {
3610     CXFA_Caption* caption = GetCaptionIfExists();
3611     if (caption && !caption->IsHidden()) {
3612       iCapPlacement = caption->GetPlacementType();
3613       fCapReserve = caption->GetReserve();
3614     }
3615     if (iCapPlacement == XFA_AttributeValue::Top &&
3616         fCalcHeight < fCapReserve + fTopInset) {
3617       return 0.0f;
3618     }
3619     if (iCapPlacement == XFA_AttributeValue::Bottom &&
3620         m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
3621       return 0.0f;
3622     }
3623     if (iCapPlacement != XFA_AttributeValue::Top)
3624       fCapReserve = 0;
3625   }
3626   CXFA_FieldLayoutData* pFieldData = m_pLayoutData->AsFieldLayoutData();
3627   int32_t iLinesCount = 0;
3628   float fHeight = m_pLayoutData->m_fWidgetHeight;
3629   if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
3630     iLinesCount = 1;
3631   } else {
3632     if (!pFieldData->m_pTextOut) {
3633       CFX_SizeF size = CalculateAccWidthAndHeight(pDocView->GetDoc(),
3634                                                   TryWidth().value_or(0));
3635       fHeight = size.height;
3636     }
3637 
3638     iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
3639   }
3640   std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
3641   size_t szFieldSplitCount = pFieldArray->size();
3642   if (szFieldSplitCount < szBlockIndex * 3)
3643     return pdfium::nullopt;
3644 
3645   for (size_t i = 0; i < szBlockIndex * 3; i += 3) {
3646     iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
3647     fHeight -= (*pFieldArray)[i + 2];
3648   }
3649   if (iLinesCount == 0)
3650     return pdfium::nullopt;
3651 
3652   float fLineHeight = GetLineHeight();
3653   float fFontSize = GetFontSize();
3654   float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
3655   float fSpaceAbove = 0;
3656   float fStartOffset = 0;
3657   if (fHeight > 0.1f && szBlockIndex == 0) {
3658     fStartOffset = fTopInset;
3659     fHeight -= (fTopInset + fBottomInset);
3660     CXFA_Para* para = GetParaIfExists();
3661     if (para) {
3662       fSpaceAbove = para->GetSpaceAbove();
3663       float fSpaceBelow = para->GetSpaceBelow();
3664       fHeight -= (fSpaceAbove + fSpaceBelow);
3665       switch (para->GetVerticalAlign()) {
3666         case XFA_AttributeValue::Top:
3667           fStartOffset += fSpaceAbove;
3668           break;
3669         case XFA_AttributeValue::Middle:
3670           fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
3671           break;
3672         case XFA_AttributeValue::Bottom:
3673           fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
3674           break;
3675         default:
3676           NOTREACHED();
3677           break;
3678       }
3679     }
3680     if (fStartOffset < 0.1f)
3681       fStartOffset = 0;
3682   }
3683   if (szBlockIndex > 0) {
3684     size_t i = szBlockIndex - 1;
3685     fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
3686     if (fStartOffset < 0.1f)
3687       fStartOffset = 0;
3688   }
3689   if (szFieldSplitCount / 3 == (szBlockIndex + 1))
3690     (*pFieldArray)[0] = fStartOffset;
3691   else
3692     pFieldArray->push_back(fStartOffset);
3693 
3694   XFA_VERSION version = pDocView->GetDoc()->GetXFADoc()->GetCurVersionMode();
3695   bool bCanSplitNoContent = false;
3696   auto value = GetParent()->JSObject()->TryEnum(XFA_Attribute::Layout, true);
3697   XFA_AttributeValue eLayoutMode = value.value_or(XFA_AttributeValue::Position);
3698   if ((eLayoutMode == XFA_AttributeValue::Position ||
3699        eLayoutMode == XFA_AttributeValue::Tb ||
3700        eLayoutMode == XFA_AttributeValue::Row ||
3701        eLayoutMode == XFA_AttributeValue::Table) &&
3702       version > XFA_VERSION_208) {
3703     bCanSplitNoContent = true;
3704   }
3705   if ((eLayoutMode == XFA_AttributeValue::Tb ||
3706        eLayoutMode == XFA_AttributeValue::Row ||
3707        eLayoutMode == XFA_AttributeValue::Table) &&
3708       version <= XFA_VERSION_208) {
3709     if (fStartOffset >= fCalcHeight)
3710       return 0.0f;
3711 
3712     bCanSplitNoContent = true;
3713   }
3714   if (!bCanSplitNoContent ||
3715       fCalcHeight - fTopInset - fSpaceAbove < fLineHeight) {
3716     return 0.0f;
3717   }
3718 
3719   if (fStartOffset + kXFAWidgetPrecision >= fCalcHeight) {
3720     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3721       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3722       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3723     } else {
3724       pFieldArray->push_back(0);
3725       pFieldArray->push_back(fCalcHeight);
3726     }
3727     return pdfium::nullopt;
3728   }
3729 
3730   if (fCalcHeight - fStartOffset < fLineHeight) {
3731     fCalcHeight = fStartOffset;
3732     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3733       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3734       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3735     } else {
3736       pFieldArray->push_back(0);
3737       pFieldArray->push_back(fCalcHeight);
3738     }
3739     return fCalcHeight;
3740   }
3741 
3742   float fTextNum =
3743       fCalcHeight + kXFAWidgetPrecision - fCapReserve - fStartOffset;
3744   int32_t iLineNum =
3745       (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
3746   if (iLineNum >= iLinesCount) {
3747     if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
3748       if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3749         (*pFieldArray)[szBlockIndex * 3 + 1] = iLinesCount;
3750         (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3751       } else {
3752         pFieldArray->push_back(iLinesCount);
3753         pFieldArray->push_back(fCalcHeight);
3754       }
3755       return pdfium::nullopt;
3756     }
3757     if (fHeight - fStartOffset - fTextHeight < fFontSize) {
3758       iLineNum -= 1;
3759       if (iLineNum == 0)
3760         return 0.0f;
3761     } else {
3762       iLineNum = (int32_t)(fTextNum / fLineHeight);
3763     }
3764   }
3765   if (iLineNum <= 0)
3766     return 0.0f;
3767 
3768   float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
3769   if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3770     (*pFieldArray)[szBlockIndex * 3 + 1] = iLineNum;
3771     (*pFieldArray)[szBlockIndex * 3 + 2] = fSplitHeight;
3772   } else {
3773     pFieldArray->push_back(iLineNum);
3774     pFieldArray->push_back(fSplitHeight);
3775   }
3776   if (fabs(fSplitHeight - fCalcHeight) < kXFAWidgetPrecision)
3777     return pdfium::nullopt;
3778   return fSplitHeight;
3779 }
3780 
InitLayoutData()3781 void CXFA_Node::InitLayoutData() {
3782   if (m_pLayoutData)
3783     return;
3784 
3785   switch (GetFFWidgetType()) {
3786     case XFA_FFWidgetType::kText:
3787       m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
3788       return;
3789     case XFA_FFWidgetType::kTextEdit:
3790       m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
3791       return;
3792     case XFA_FFWidgetType::kImage:
3793       m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
3794       return;
3795     case XFA_FFWidgetType::kImageEdit:
3796       m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
3797       return;
3798     default:
3799       break;
3800   }
3801   if (GetElementType() == XFA_Element::Field) {
3802     m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
3803     return;
3804   }
3805   m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
3806 }
3807 
StartTextLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3808 void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
3809                                 float* pCalcWidth,
3810                                 float* pCalcHeight) {
3811   InitLayoutData();
3812 
3813   CXFA_TextLayoutData* pTextLayoutData = m_pLayoutData->AsTextLayoutData();
3814   pTextLayoutData->LoadText(doc, this);
3815 
3816   CXFA_TextLayout* pTextLayout = pTextLayoutData->GetTextLayout();
3817   float fTextHeight = 0;
3818   if (*pCalcWidth > 0 && *pCalcHeight > 0) {
3819     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3820     pTextLayout->StartLayout(fWidth);
3821     fTextHeight = *pCalcHeight;
3822     fTextHeight = GetHeightWithoutMargin(fTextHeight);
3823     pTextLayout->DoLayout(fTextHeight);
3824     return;
3825   }
3826   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3827     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3828     pTextLayout->StartLayout(fWidth);
3829   }
3830   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3831     Optional<float> width = TryWidth();
3832     if (width) {
3833       pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
3834       *pCalcWidth = *width;
3835     } else {
3836       float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
3837       pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
3838       *pCalcWidth = fMaxWidth;
3839     }
3840   }
3841   if (m_pLayoutData->m_fWidgetHeight < 0) {
3842     m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
3843     m_pLayoutData->m_fWidgetHeight =
3844         CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
3845   }
3846   fTextHeight = m_pLayoutData->m_fWidgetHeight;
3847   fTextHeight = GetHeightWithoutMargin(fTextHeight);
3848   pTextLayout->DoLayout(fTextHeight);
3849   *pCalcHeight = m_pLayoutData->m_fWidgetHeight;
3850 }
3851 
LoadCaption(CXFA_FFDoc * doc)3852 bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
3853   InitLayoutData();
3854   return m_pLayoutData->AsFieldLayoutData()->LoadCaption(doc, this);
3855 }
3856 
GetCaptionTextLayout()3857 CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
3858   return m_pLayoutData
3859              ? m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout.get()
3860              : nullptr;
3861 }
3862 
GetTextLayout()3863 CXFA_TextLayout* CXFA_Node::GetTextLayout() {
3864   return m_pLayoutData ? m_pLayoutData->AsTextLayoutData()->GetTextLayout()
3865                        : nullptr;
3866 }
3867 
GetImageImage()3868 RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageImage() {
3869   return m_pLayoutData ? m_pLayoutData->AsImageLayoutData()->m_pDIBitmap
3870                        : nullptr;
3871 }
3872 
GetImageEditImage()3873 RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageEditImage() {
3874   return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()
3875                              ->AsImageEditData()
3876                              ->m_pDIBitmap
3877                        : nullptr;
3878 }
3879 
SetImageImage(const RetainPtr<CFX_DIBitmap> & newImage)3880 void CXFA_Node::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
3881   CXFA_ImageLayoutData* pData = m_pLayoutData->AsImageLayoutData();
3882   if (pData->m_pDIBitmap != newImage)
3883     pData->m_pDIBitmap = newImage;
3884 }
3885 
SetImageEditImage(const RetainPtr<CFX_DIBitmap> & newImage)3886 void CXFA_Node::SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage) {
3887   CXFA_ImageEditData* pData =
3888       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3889   if (pData->m_pDIBitmap != newImage)
3890     pData->m_pDIBitmap = newImage;
3891 }
3892 
GetFDEFont(CXFA_FFDoc * doc)3893 RetainPtr<CFGAS_GEFont> CXFA_Node::GetFDEFont(CXFA_FFDoc* doc) {
3894   WideString wsFontName = L"Courier";
3895   uint32_t dwFontStyle = 0;
3896   CXFA_Font* font = GetFontIfExists();
3897   if (font) {
3898     if (font->IsBold())
3899       dwFontStyle |= FXFONT_FORCE_BOLD;
3900     if (font->IsItalic())
3901       dwFontStyle |= FXFONT_ITALIC;
3902 
3903     wsFontName = font->GetTypeface();
3904   }
3905   return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
3906                                                  dwFontStyle);
3907 }
3908 
HasButtonRollover()3909 bool CXFA_Node::HasButtonRollover() {
3910   CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3911   if (!pItems)
3912     return false;
3913 
3914   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3915        pText = pText->GetNextSibling()) {
3916     if (pText->JSObject()
3917             ->GetCData(XFA_Attribute::Name)
3918             .EqualsASCII("rollover")) {
3919       return !pText->JSObject()->GetContent(false).IsEmpty();
3920     }
3921   }
3922   return false;
3923 }
3924 
HasButtonDown()3925 bool CXFA_Node::HasButtonDown() {
3926   CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3927   if (!pItems)
3928     return false;
3929 
3930   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3931        pText = pText->GetNextSibling()) {
3932     if (pText->JSObject()->GetCData(XFA_Attribute::Name).EqualsASCII("down")) {
3933       return !pText->JSObject()->GetContent(false).IsEmpty();
3934     }
3935   }
3936   return false;
3937 }
3938 
IsRadioButton()3939 bool CXFA_Node::IsRadioButton() {
3940   CXFA_Node* pParent = GetParent();
3941   return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
3942 }
3943 
GetCheckButtonSize()3944 float CXFA_Node::GetCheckButtonSize() {
3945   CXFA_Node* pUIChild = GetUIChildNode();
3946   if (pUIChild) {
3947     return pUIChild->JSObject()->GetMeasureInUnit(XFA_Attribute::Size,
3948                                                   XFA_Unit::Pt);
3949   }
3950   return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
3951 }
3952 
GetCheckState()3953 XFA_CHECKSTATE CXFA_Node::GetCheckState() {
3954   WideString wsValue = GetRawValue();
3955   if (wsValue.IsEmpty())
3956     return XFA_CHECKSTATE_Off;
3957 
3958   auto* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3959   if (!pItems)
3960     return XFA_CHECKSTATE_Off;
3961 
3962   CXFA_Node* pText = pItems->GetFirstChild();
3963   int32_t i = 0;
3964   while (pText) {
3965     Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
3966     if (wsContent && *wsContent == wsValue)
3967       return static_cast<XFA_CHECKSTATE>(i);
3968 
3969     i++;
3970     pText = pText->GetNextSibling();
3971   }
3972   return XFA_CHECKSTATE_Off;
3973 }
3974 
SetCheckState(XFA_CHECKSTATE eCheckState,bool bNotify)3975 void CXFA_Node::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
3976   CXFA_Node* node = GetExclGroupIfExists();
3977   if (!node) {
3978     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3979     if (!pItems)
3980       return;
3981 
3982     int32_t i = -1;
3983     CXFA_Node* pText = pItems->GetFirstChild();
3984     WideString wsContent;
3985     while (pText) {
3986       i++;
3987       if (i == eCheckState) {
3988         wsContent = pText->JSObject()->GetContent(false);
3989         break;
3990       }
3991       pText = pText->GetNextSibling();
3992     }
3993     SyncValue(wsContent, bNotify);
3994 
3995     return;
3996   }
3997 
3998   WideString wsValue;
3999   if (eCheckState != XFA_CHECKSTATE_Off) {
4000     if (CXFA_Items* pItems =
4001             GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
4002       CXFA_Node* pText = pItems->GetFirstChild();
4003       if (pText)
4004         wsValue = pText->JSObject()->GetContent(false);
4005     }
4006   }
4007   CXFA_Node* pChild = node->GetFirstChild();
4008   for (; pChild; pChild = pChild->GetNextSibling()) {
4009     if (pChild->GetElementType() != XFA_Element::Field)
4010       continue;
4011 
4012     CXFA_Items* pItem =
4013         pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4014     if (!pItem)
4015       continue;
4016 
4017     CXFA_Node* pItemchild = pItem->GetFirstChild();
4018     if (!pItemchild)
4019       continue;
4020 
4021     WideString text = pItemchild->JSObject()->GetContent(false);
4022     WideString wsChildValue = text;
4023     if (wsValue != text) {
4024       pItemchild = pItemchild->GetNextSibling();
4025       if (pItemchild)
4026         wsChildValue = pItemchild->JSObject()->GetContent(false);
4027       else
4028         wsChildValue.clear();
4029     }
4030     pChild->SyncValue(wsChildValue, bNotify);
4031   }
4032   node->SyncValue(wsValue, bNotify);
4033 }
4034 
GetSelectedMember()4035 CXFA_Node* CXFA_Node::GetSelectedMember() {
4036   CXFA_Node* pSelectedMember = nullptr;
4037   WideString wsState = GetRawValue();
4038   if (wsState.IsEmpty())
4039     return pSelectedMember;
4040 
4041   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4042        pNode = pNode->GetNextSibling()) {
4043     if (pNode->GetCheckState() == XFA_CHECKSTATE_On) {
4044       pSelectedMember = pNode;
4045       break;
4046     }
4047   }
4048   return pSelectedMember;
4049 }
4050 
SetSelectedMember(WideStringView wsName,bool bNotify)4051 CXFA_Node* CXFA_Node::SetSelectedMember(WideStringView wsName, bool bNotify) {
4052   uint32_t nameHash = FX_HashCode_GetW(wsName, false);
4053   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4054        pNode = pNode->GetNextSibling()) {
4055     if (pNode->GetNameHash() == nameHash) {
4056       pNode->SetCheckState(XFA_CHECKSTATE_On, bNotify);
4057       return pNode;
4058     }
4059   }
4060   return nullptr;
4061 }
4062 
SetSelectedMemberByValue(WideStringView wsValue,bool bNotify,bool bScriptModify,bool bSyncData)4063 void CXFA_Node::SetSelectedMemberByValue(WideStringView wsValue,
4064                                          bool bNotify,
4065                                          bool bScriptModify,
4066                                          bool bSyncData) {
4067   WideString wsExclGroup;
4068   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4069        pNode = pNode->GetNextSibling()) {
4070     if (pNode->GetElementType() != XFA_Element::Field)
4071       continue;
4072 
4073     CXFA_Items* pItem =
4074         pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4075     if (!pItem)
4076       continue;
4077 
4078     CXFA_Node* pItemchild = pItem->GetFirstChild();
4079     if (!pItemchild)
4080       continue;
4081 
4082     WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
4083     if (wsValue != wsChildValue) {
4084       pItemchild = pItemchild->GetNextSibling();
4085       if (pItemchild)
4086         wsChildValue = pItemchild->JSObject()->GetContent(false);
4087       else
4088         wsChildValue.clear();
4089     } else {
4090       wsExclGroup = wsValue;
4091     }
4092     pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
4093                                   bScriptModify, false);
4094   }
4095   JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
4096                          bSyncData);
4097 }
4098 
GetExclGroupFirstMember()4099 CXFA_Node* CXFA_Node::GetExclGroupFirstMember() {
4100   CXFA_Node* pNode = GetFirstChild();
4101   while (pNode) {
4102     if (pNode->GetElementType() == XFA_Element::Field)
4103       return pNode;
4104 
4105     pNode = pNode->GetNextSibling();
4106   }
4107   return nullptr;
4108 }
4109 
GetExclGroupNextMember(CXFA_Node * pNode)4110 CXFA_Node* CXFA_Node::GetExclGroupNextMember(CXFA_Node* pNode) {
4111   if (!pNode)
4112     return nullptr;
4113 
4114   CXFA_Node* pNodeField = pNode->GetNextSibling();
4115   while (pNodeField) {
4116     if (pNodeField->GetElementType() == XFA_Element::Field)
4117       return pNodeField;
4118 
4119     pNodeField = pNodeField->GetNextSibling();
4120   }
4121   return nullptr;
4122 }
4123 
IsChoiceListCommitOnSelect()4124 bool CXFA_Node::IsChoiceListCommitOnSelect() {
4125   CXFA_Node* pUIChild = GetUIChildNode();
4126   if (pUIChild) {
4127     return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
4128            XFA_AttributeValue::Select;
4129   }
4130   return true;
4131 }
4132 
IsChoiceListAllowTextEntry()4133 bool CXFA_Node::IsChoiceListAllowTextEntry() {
4134   CXFA_Node* pUIChild = GetUIChildNode();
4135   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
4136 }
4137 
IsChoiceListMultiSelect()4138 bool CXFA_Node::IsChoiceListMultiSelect() {
4139   CXFA_Node* pUIChild = GetUIChildNode();
4140   if (pUIChild) {
4141     return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
4142            XFA_AttributeValue::MultiSelect;
4143   }
4144   return false;
4145 }
4146 
IsListBox()4147 bool CXFA_Node::IsListBox() {
4148   CXFA_Node* pUIChild = GetUIChildNode();
4149   if (!pUIChild)
4150     return false;
4151 
4152   XFA_AttributeValue attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
4153   return attr == XFA_AttributeValue::Always ||
4154          attr == XFA_AttributeValue::MultiSelect;
4155 }
4156 
CountChoiceListItems(bool bSaveValue)4157 int32_t CXFA_Node::CountChoiceListItems(bool bSaveValue) {
4158   std::vector<CXFA_Node*> pItems;
4159   int32_t iCount = 0;
4160   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4161        pNode = pNode->GetNextSibling()) {
4162     if (pNode->GetElementType() != XFA_Element::Items)
4163       continue;
4164     iCount++;
4165     pItems.push_back(pNode);
4166     if (iCount == 2)
4167       break;
4168   }
4169   if (iCount == 0)
4170     return 0;
4171 
4172   CXFA_Node* pItem = pItems[0];
4173   if (iCount > 1) {
4174     bool bItemOneHasSave =
4175         pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4176     bool bItemTwoHasSave =
4177         pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4178     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4179       pItem = pItems[1];
4180   }
4181   return pItem->CountChildren(XFA_Element::Unknown, false);
4182 }
4183 
GetChoiceListItem(int32_t nIndex,bool bSaveValue)4184 Optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
4185                                                   bool bSaveValue) {
4186   std::vector<CXFA_Node*> pItemsArray;
4187   int32_t iCount = 0;
4188   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4189        pNode = pNode->GetNextSibling()) {
4190     if (pNode->GetElementType() != XFA_Element::Items)
4191       continue;
4192 
4193     ++iCount;
4194     pItemsArray.push_back(pNode);
4195     if (iCount == 2)
4196       break;
4197   }
4198   if (iCount == 0)
4199     return {};
4200 
4201   CXFA_Node* pItems = pItemsArray[0];
4202   if (iCount > 1) {
4203     bool bItemOneHasSave =
4204         pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4205     bool bItemTwoHasSave =
4206         pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4207     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4208       pItems = pItemsArray[1];
4209   }
4210   if (!pItems)
4211     return {};
4212 
4213   CXFA_Node* pItem =
4214       pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
4215   if (pItem)
4216     return {pItem->JSObject()->GetContent(false)};
4217   return {};
4218 }
4219 
GetChoiceListItems(bool bSaveValue)4220 std::vector<WideString> CXFA_Node::GetChoiceListItems(bool bSaveValue) {
4221   std::vector<CXFA_Node*> items;
4222   for (CXFA_Node* pNode = GetFirstChild(); pNode && items.size() < 2;
4223        pNode = pNode->GetNextSibling()) {
4224     if (pNode->GetElementType() == XFA_Element::Items)
4225       items.push_back(pNode);
4226   }
4227   if (items.empty())
4228     return std::vector<WideString>();
4229 
4230   CXFA_Node* pItem = items.front();
4231   if (items.size() > 1) {
4232     bool bItemOneHasSave =
4233         items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4234     bool bItemTwoHasSave =
4235         items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4236     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4237       pItem = items[1];
4238   }
4239 
4240   std::vector<WideString> wsTextArray;
4241   for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
4242        pNode = pNode->GetNextSibling()) {
4243     wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
4244   }
4245   return wsTextArray;
4246 }
4247 
CountSelectedItems()4248 int32_t CXFA_Node::CountSelectedItems() {
4249   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4250   if (IsListBox() || !IsChoiceListAllowTextEntry())
4251     return pdfium::CollectionSize<int32_t>(wsValueArray);
4252 
4253   int32_t iSelected = 0;
4254   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4255   for (const auto& value : wsValueArray) {
4256     if (pdfium::ContainsValue(wsSaveTextArray, value))
4257       iSelected++;
4258   }
4259   return iSelected;
4260 }
4261 
GetSelectedItem(int32_t nIndex)4262 int32_t CXFA_Node::GetSelectedItem(int32_t nIndex) {
4263   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4264   if (!pdfium::IndexInBounds(wsValueArray, nIndex))
4265     return -1;
4266 
4267   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4268   auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
4269                       wsValueArray[nIndex]);
4270   return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
4271 }
4272 
GetSelectedItems()4273 std::vector<int32_t> CXFA_Node::GetSelectedItems() {
4274   std::vector<int32_t> iSelArray;
4275   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4276   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4277   for (const auto& value : wsValueArray) {
4278     auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
4279     if (it != wsSaveTextArray.end())
4280       iSelArray.push_back(it - wsSaveTextArray.begin());
4281   }
4282   return iSelArray;
4283 }
4284 
GetSelectedItemsValue()4285 std::vector<WideString> CXFA_Node::GetSelectedItemsValue() {
4286   WideString wsValue = GetRawValue();
4287   if (IsChoiceListMultiSelect())
4288     return fxcrt::Split(wsValue, L'\n');
4289 
4290   std::vector<WideString> wsSelTextArray;
4291   wsSelTextArray.push_back(wsValue);
4292   return wsSelTextArray;
4293 }
4294 
GetItemState(int32_t nIndex)4295 bool CXFA_Node::GetItemState(int32_t nIndex) {
4296   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4297   return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
4298          pdfium::ContainsValue(GetSelectedItemsValue(),
4299                                wsSaveTextArray[nIndex]);
4300 }
4301 
SetItemState(int32_t nIndex,bool bSelected,bool bNotify,bool bScriptModify,bool bSyncData)4302 void CXFA_Node::SetItemState(int32_t nIndex,
4303                              bool bSelected,
4304                              bool bNotify,
4305                              bool bScriptModify,
4306                              bool bSyncData) {
4307   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4308   if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
4309     return;
4310 
4311   int32_t iSel = -1;
4312   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4313   auto value_iter = std::find(wsValueArray.begin(), wsValueArray.end(),
4314                               wsSaveTextArray[nIndex]);
4315   if (value_iter != wsValueArray.end())
4316     iSel = value_iter - wsValueArray.begin();
4317 
4318   if (IsChoiceListMultiSelect()) {
4319     if (bSelected) {
4320       if (iSel < 0) {
4321         WideString wsValue = GetRawValue();
4322         if (!wsValue.IsEmpty()) {
4323           wsValue += L"\n";
4324         }
4325         wsValue += wsSaveTextArray[nIndex];
4326         JSObject()->SetContent(wsValue, wsValue, bNotify, bScriptModify,
4327                                bSyncData);
4328       }
4329     } else if (iSel >= 0) {
4330       std::vector<int32_t> iSelArray = GetSelectedItems();
4331       auto selected_iter =
4332           std::find(iSelArray.begin(), iSelArray.end(), nIndex);
4333       if (selected_iter != iSelArray.end())
4334         iSelArray.erase(selected_iter);
4335       SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
4336     }
4337   } else {
4338     if (bSelected) {
4339       if (iSel < 0) {
4340         WideString wsSaveText = wsSaveTextArray[nIndex];
4341         JSObject()->SetContent(wsSaveText, GetFormatDataValue(wsSaveText),
4342                                bNotify, bScriptModify, bSyncData);
4343       }
4344     } else if (iSel >= 0) {
4345       JSObject()->SetContent(WideString(), WideString(), bNotify, bScriptModify,
4346                              bSyncData);
4347     }
4348   }
4349 }
4350 
SetSelectedItems(const std::vector<int32_t> & iSelArray,bool bNotify,bool bScriptModify,bool bSyncData)4351 void CXFA_Node::SetSelectedItems(const std::vector<int32_t>& iSelArray,
4352                                  bool bNotify,
4353                                  bool bScriptModify,
4354                                  bool bSyncData) {
4355   WideString wsValue;
4356   int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
4357   if (iSize >= 1) {
4358     std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4359     WideString wsItemValue;
4360     for (int32_t i = 0; i < iSize; i++) {
4361       wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
4362                                  : wsSaveTextArray[iSelArray[i]] + L"\n";
4363       wsValue += wsItemValue;
4364     }
4365   }
4366   WideString wsFormat(wsValue);
4367   if (!IsChoiceListMultiSelect())
4368     wsFormat = GetFormatDataValue(wsValue);
4369 
4370   JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
4371 }
4372 
ClearAllSelections()4373 void CXFA_Node::ClearAllSelections() {
4374   CXFA_Node* pBind = GetBindData();
4375   if (!pBind || !IsChoiceListMultiSelect()) {
4376     SyncValue(WideString(), false);
4377     return;
4378   }
4379 
4380   while (CXFA_Node* pChildNode = pBind->GetFirstChild())
4381     pBind->RemoveChildAndNotify(pChildNode, true);
4382 }
4383 
InsertItem(const WideString & wsLabel,const WideString & wsValue,bool bNotify)4384 void CXFA_Node::InsertItem(const WideString& wsLabel,
4385                            const WideString& wsValue,
4386                            bool bNotify) {
4387   int32_t nIndex = -1;
4388   WideString wsNewValue(wsValue);
4389   if (wsNewValue.IsEmpty())
4390     wsNewValue = wsLabel;
4391 
4392   std::vector<CXFA_Node*> listitems;
4393   for (CXFA_Node* pItem = GetFirstChild(); pItem;
4394        pItem = pItem->GetNextSibling()) {
4395     if (pItem->GetElementType() == XFA_Element::Items)
4396       listitems.push_back(pItem);
4397   }
4398   if (listitems.empty()) {
4399     CXFA_Node* pItems = CreateSamePacketNode(XFA_Element::Items);
4400     InsertChildAndNotify(-1, pItems);
4401     InsertListTextItem(pItems, wsLabel, nIndex);
4402     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4403     InsertChildAndNotify(-1, pSaveItems);
4404     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4405     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4406   } else if (listitems.size() > 1) {
4407     for (int32_t i = 0; i < 2; i++) {
4408       CXFA_Node* pNode = listitems[i];
4409       bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
4410       if (bHasSave)
4411         InsertListTextItem(pNode, wsNewValue, nIndex);
4412       else
4413         InsertListTextItem(pNode, wsLabel, nIndex);
4414     }
4415   } else {
4416     CXFA_Node* pNode = listitems[0];
4417     pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
4418     pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
4419                                XFA_AttributeValue::Visible, false);
4420     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4421     InsertChildAndNotify(-1, pSaveItems);
4422     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4423     pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
4424                                     XFA_AttributeValue::Hidden, false);
4425     CXFA_Node* pListNode = pNode->GetFirstChild();
4426     int32_t i = 0;
4427     while (pListNode) {
4428       InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
4429                          i);
4430       ++i;
4431 
4432       pListNode = pListNode->GetNextSibling();
4433     }
4434     InsertListTextItem(pNode, wsLabel, nIndex);
4435     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4436   }
4437   if (bNotify)
4438     GetDocument()->GetNotify()->OnWidgetListItemAdded(this, wsLabel, nIndex);
4439 }
4440 
GetItemLabel(WideStringView wsValue) const4441 WideString CXFA_Node::GetItemLabel(WideStringView wsValue) const {
4442   std::vector<CXFA_Node*> listitems;
4443   CXFA_Node* pItems = GetFirstChild();
4444   for (; pItems; pItems = pItems->GetNextSibling()) {
4445     if (pItems->GetElementType() != XFA_Element::Items)
4446       continue;
4447     listitems.push_back(pItems);
4448   }
4449 
4450   if (listitems.size() <= 1)
4451     return WideString(wsValue);
4452 
4453   CXFA_Node* pLabelItems = listitems[0];
4454   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4455   CXFA_Node* pSaveItems = nullptr;
4456   if (bSave) {
4457     pSaveItems = pLabelItems;
4458     pLabelItems = listitems[1];
4459   } else {
4460     pSaveItems = listitems[1];
4461   }
4462 
4463   int32_t iCount = 0;
4464   int32_t iSearch = -1;
4465   for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
4466        pChildItem = pChildItem->GetNextSibling()) {
4467     if (pChildItem->JSObject()->GetContent(false) == wsValue) {
4468       iSearch = iCount;
4469       break;
4470     }
4471     iCount++;
4472   }
4473   if (iSearch < 0)
4474     return WideString();
4475 
4476   CXFA_Node* pText =
4477       pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4478   return pText ? pText->JSObject()->GetContent(false) : WideString();
4479 }
4480 
GetItemValue(WideStringView wsLabel)4481 WideString CXFA_Node::GetItemValue(WideStringView wsLabel) {
4482   int32_t iCount = 0;
4483   std::vector<CXFA_Node*> listitems;
4484   for (CXFA_Node* pItems = GetFirstChild(); pItems;
4485        pItems = pItems->GetNextSibling()) {
4486     if (pItems->GetElementType() != XFA_Element::Items)
4487       continue;
4488     iCount++;
4489     listitems.push_back(pItems);
4490   }
4491   if (iCount <= 1)
4492     return WideString(wsLabel);
4493 
4494   CXFA_Node* pLabelItems = listitems[0];
4495   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4496   CXFA_Node* pSaveItems = nullptr;
4497   if (bSave) {
4498     pSaveItems = pLabelItems;
4499     pLabelItems = listitems[1];
4500   } else {
4501     pSaveItems = listitems[1];
4502   }
4503   iCount = 0;
4504 
4505   int32_t iSearch = -1;
4506   WideString wsContent;
4507   CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
4508   for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
4509     if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
4510       iSearch = iCount;
4511       break;
4512     }
4513     iCount++;
4514   }
4515   if (iSearch < 0)
4516     return WideString();
4517 
4518   CXFA_Node* pText =
4519       pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4520   return pText ? pText->JSObject()->GetContent(false) : WideString();
4521 }
4522 
DeleteItem(int32_t nIndex,bool bNotify,bool bScriptModify)4523 bool CXFA_Node::DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify) {
4524   bool bSetValue = false;
4525   CXFA_Node* pItems = GetFirstChild();
4526   for (; pItems; pItems = pItems->GetNextSibling()) {
4527     if (pItems->GetElementType() != XFA_Element::Items)
4528       continue;
4529 
4530     if (nIndex < 0) {
4531       while (CXFA_Node* pNode = pItems->GetFirstChild()) {
4532         pItems->RemoveChildAndNotify(pNode, true);
4533       }
4534     } else {
4535       if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
4536         SetItemState(nIndex, false, true, bScriptModify, true);
4537         bSetValue = true;
4538       }
4539       int32_t i = 0;
4540       CXFA_Node* pNode = pItems->GetFirstChild();
4541       while (pNode) {
4542         if (i == nIndex) {
4543           pItems->RemoveChildAndNotify(pNode, true);
4544           break;
4545         }
4546         i++;
4547         pNode = pNode->GetNextSibling();
4548       }
4549     }
4550   }
4551   if (bNotify)
4552     GetDocument()->GetNotify()->OnWidgetListItemRemoved(this, nIndex);
4553   return true;
4554 }
4555 
IsHorizontalScrollPolicyOff()4556 bool CXFA_Node::IsHorizontalScrollPolicyOff() {
4557   CXFA_Node* pUIChild = GetUIChildNode();
4558   if (pUIChild) {
4559     return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
4560            XFA_AttributeValue::Off;
4561   }
4562   return false;
4563 }
4564 
IsVerticalScrollPolicyOff()4565 bool CXFA_Node::IsVerticalScrollPolicyOff() {
4566   CXFA_Node* pUIChild = GetUIChildNode();
4567   if (pUIChild) {
4568     return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
4569            XFA_AttributeValue::Off;
4570   }
4571   return false;
4572 }
4573 
GetNumberOfCells()4574 Optional<int32_t> CXFA_Node::GetNumberOfCells() {
4575   CXFA_Node* pUIChild = GetUIChildNode();
4576   if (!pUIChild)
4577     return {};
4578   if (CXFA_Comb* pNode =
4579           pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
4580     return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
4581   return {};
4582 }
4583 
IsMultiLine()4584 bool CXFA_Node::IsMultiLine() {
4585   CXFA_Node* pUIChild = GetUIChildNode();
4586   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
4587 }
4588 
GetMaxChars()4589 std::pair<XFA_Element, int32_t> CXFA_Node::GetMaxChars() {
4590   if (CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
4591     if (CXFA_Node* pChild = pNode->GetFirstChild()) {
4592       switch (pChild->GetElementType()) {
4593         case XFA_Element::Text:
4594           return {XFA_Element::Text,
4595                   pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
4596         case XFA_Element::ExData: {
4597           int32_t iMax =
4598               pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
4599           return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
4600         }
4601         default:
4602           break;
4603       }
4604     }
4605   }
4606   return {XFA_Element::Unknown, 0};
4607 }
4608 
GetFracDigits()4609 int32_t CXFA_Node::GetFracDigits() {
4610   CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4611   if (!pNode)
4612     return -1;
4613 
4614   CXFA_Decimal* pChild =
4615       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4616   if (!pChild)
4617     return -1;
4618 
4619   return pChild->JSObject()
4620       ->TryInteger(XFA_Attribute::FracDigits, true)
4621       .value_or(-1);
4622 }
4623 
GetLeadDigits()4624 int32_t CXFA_Node::GetLeadDigits() {
4625   CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4626   if (!pNode)
4627     return -1;
4628 
4629   CXFA_Decimal* pChild =
4630       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4631   if (!pChild)
4632     return -1;
4633 
4634   return pChild->JSObject()
4635       ->TryInteger(XFA_Attribute::LeadDigits, true)
4636       .value_or(-1);
4637 }
4638 
SetValue(XFA_VALUEPICTURE eValueType,const WideString & wsValue)4639 bool CXFA_Node::SetValue(XFA_VALUEPICTURE eValueType,
4640                          const WideString& wsValue) {
4641   if (wsValue.IsEmpty()) {
4642     SyncValue(wsValue, true);
4643     return true;
4644   }
4645 
4646   SetPreNull(IsNull());
4647   SetIsNull(false);
4648 
4649   WideString wsNewText(wsValue);
4650   WideString wsPicture = GetPictureContent(eValueType);
4651   bool bValidate = true;
4652   bool bSyncData = false;
4653   CXFA_Node* pNode = GetUIChildNode();
4654   if (!pNode)
4655     return true;
4656 
4657   XFA_Element eType = pNode->GetElementType();
4658   if (!wsPicture.IsEmpty()) {
4659     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4660     LocaleIface* pLocale = GetLocale();
4661     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4662     bValidate =
4663         widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
4664     if (bValidate) {
4665       widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
4666                                      wsPicture, pLocale, pLocaleMgr);
4667       wsNewText = widgetValue.GetValue();
4668       if (eType == XFA_Element::NumericEdit)
4669         wsNewText = NumericLimit(wsNewText);
4670 
4671       bSyncData = true;
4672     }
4673   } else if (eType == XFA_Element::NumericEdit) {
4674     if (!wsNewText.EqualsASCII("0"))
4675       wsNewText = NumericLimit(wsNewText);
4676 
4677     bSyncData = true;
4678   }
4679   if (eType != XFA_Element::NumericEdit || bSyncData)
4680     SyncValue(wsNewText, true);
4681 
4682   return bValidate;
4683 }
4684 
GetPictureContent(XFA_VALUEPICTURE ePicture)4685 WideString CXFA_Node::GetPictureContent(XFA_VALUEPICTURE ePicture) {
4686   if (ePicture == XFA_VALUEPICTURE_Raw)
4687     return WideString();
4688 
4689   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4690   switch (ePicture) {
4691     case XFA_VALUEPICTURE_Display: {
4692       if (CXFA_Format* pFormat =
4693               GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
4694         if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
4695                 0, XFA_Element::Picture, false)) {
4696           Optional<WideString> picture =
4697               pPicture->JSObject()->TryContent(false, true);
4698           if (picture)
4699             return *picture;
4700         }
4701       }
4702 
4703       LocaleIface* pLocale = GetLocale();
4704       if (!pLocale)
4705         return WideString();
4706 
4707       uint32_t dwType = widgetValue.GetType();
4708       switch (dwType) {
4709         case XFA_VT_DATE:
4710           return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
4711         case XFA_VT_TIME:
4712           return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
4713         case XFA_VT_DATETIME:
4714           return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
4715                  L"T" +
4716                  pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
4717         case XFA_VT_DECIMAL:
4718         case XFA_VT_FLOAT:
4719         default:
4720           return WideString();
4721       }
4722     }
4723     case XFA_VALUEPICTURE_Edit: {
4724       CXFA_Ui* pUI = GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
4725       if (pUI) {
4726         if (CXFA_Picture* pPicture =
4727                 pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
4728           Optional<WideString> picture =
4729               pPicture->JSObject()->TryContent(false, true);
4730           if (picture)
4731             return *picture;
4732         }
4733       }
4734 
4735       LocaleIface* pLocale = GetLocale();
4736       if (!pLocale)
4737         return WideString();
4738 
4739       uint32_t dwType = widgetValue.GetType();
4740       switch (dwType) {
4741         case XFA_VT_DATE:
4742           return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
4743         case XFA_VT_TIME:
4744           return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
4745         case XFA_VT_DATETIME:
4746           return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
4747                  L"T" +
4748                  pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
4749         default:
4750           return WideString();
4751       }
4752     }
4753     case XFA_VALUEPICTURE_DataBind: {
4754       CXFA_Bind* bind = GetBindIfExists();
4755       if (bind)
4756         return bind->GetPicture();
4757       break;
4758     }
4759     default:
4760       break;
4761   }
4762   return WideString();
4763 }
4764 
GetValue(XFA_VALUEPICTURE eValueType)4765 WideString CXFA_Node::GetValue(XFA_VALUEPICTURE eValueType) {
4766   WideString wsValue = JSObject()->GetContent(false);
4767 
4768   if (eValueType == XFA_VALUEPICTURE_Display)
4769     wsValue = GetItemLabel(wsValue.AsStringView());
4770 
4771   WideString wsPicture = GetPictureContent(eValueType);
4772   CXFA_Node* pNode = GetUIChildNode();
4773   if (!pNode)
4774     return wsValue;
4775 
4776   switch (pNode->GetElementType()) {
4777     case XFA_Element::ChoiceList: {
4778       if (eValueType == XFA_VALUEPICTURE_Display) {
4779         int32_t iSelItemIndex = GetSelectedItem(0);
4780         if (iSelItemIndex >= 0) {
4781           wsValue =
4782               GetChoiceListItem(iSelItemIndex, false).value_or(WideString());
4783           wsPicture.clear();
4784         }
4785       }
4786       break;
4787     }
4788     case XFA_Element::NumericEdit:
4789       if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
4790         LocaleIface* pLocale = GetLocale();
4791         if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
4792           wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
4793       }
4794       break;
4795     default:
4796       break;
4797   }
4798   if (wsPicture.IsEmpty())
4799     return wsValue;
4800 
4801   if (LocaleIface* pLocale = GetLocale()) {
4802     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4803     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4804     switch (widgetValue.GetType()) {
4805       case XFA_VT_DATE: {
4806         WideString wsDate, wsTime;
4807         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4808           CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocaleMgr);
4809           if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4810             return wsValue;
4811         }
4812         break;
4813       }
4814       case XFA_VT_TIME: {
4815         WideString wsDate, wsTime;
4816         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4817           CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocaleMgr);
4818           if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4819             return wsValue;
4820         }
4821         break;
4822       }
4823       default:
4824         break;
4825     }
4826     widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
4827   }
4828   return wsValue;
4829 }
4830 
GetNormalizeDataValue(const WideString & wsValue)4831 WideString CXFA_Node::GetNormalizeDataValue(const WideString& wsValue) {
4832   if (wsValue.IsEmpty())
4833     return WideString();
4834 
4835   WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
4836   if (wsPicture.IsEmpty())
4837     return wsValue;
4838 
4839   CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4840   LocaleIface* pLocale = GetLocale();
4841   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4842   if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
4843     widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
4844                                    pLocale, pLocaleMgr);
4845     return widgetValue.GetValue();
4846   }
4847   return wsValue;
4848 }
4849 
GetFormatDataValue(const WideString & wsValue)4850 WideString CXFA_Node::GetFormatDataValue(const WideString& wsValue) {
4851   if (wsValue.IsEmpty())
4852     return WideString();
4853 
4854   WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
4855   if (wsPicture.IsEmpty())
4856     return wsValue;
4857 
4858   WideString wsFormattedValue = wsValue;
4859   if (LocaleIface* pLocale = GetLocale()) {
4860     CXFA_Value* pNodeValue = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4861     if (!pNodeValue)
4862       return wsValue;
4863 
4864     CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
4865     if (!pValueChild)
4866       return wsValue;
4867 
4868     int32_t iVTType = XFA_VT_NULL;
4869     switch (pValueChild->GetElementType()) {
4870       case XFA_Element::Decimal:
4871         iVTType = XFA_VT_DECIMAL;
4872         break;
4873       case XFA_Element::Float:
4874         iVTType = XFA_VT_FLOAT;
4875         break;
4876       case XFA_Element::Date:
4877         iVTType = XFA_VT_DATE;
4878         break;
4879       case XFA_Element::Time:
4880         iVTType = XFA_VT_TIME;
4881         break;
4882       case XFA_Element::DateTime:
4883         iVTType = XFA_VT_DATETIME;
4884         break;
4885       case XFA_Element::Boolean:
4886         iVTType = XFA_VT_BOOLEAN;
4887         break;
4888       case XFA_Element::Integer:
4889         iVTType = XFA_VT_INTEGER;
4890         break;
4891       case XFA_Element::Text:
4892         iVTType = XFA_VT_TEXT;
4893         break;
4894       default:
4895         iVTType = XFA_VT_NULL;
4896         break;
4897     }
4898     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4899     CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocaleMgr);
4900     switch (widgetValue.GetType()) {
4901       case XFA_VT_DATE: {
4902         WideString wsDate, wsTime;
4903         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4904           CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocaleMgr);
4905           if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4906                                   XFA_VALUEPICTURE_DataBind)) {
4907             return wsFormattedValue;
4908           }
4909         }
4910         break;
4911       }
4912       case XFA_VT_TIME: {
4913         WideString wsDate, wsTime;
4914         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4915           CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocaleMgr);
4916           if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4917                                   XFA_VALUEPICTURE_DataBind)) {
4918             return wsFormattedValue;
4919           }
4920         }
4921         break;
4922       }
4923       default:
4924         break;
4925     }
4926     widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4927                                XFA_VALUEPICTURE_DataBind);
4928   }
4929   return wsFormattedValue;
4930 }
4931 
NormalizeNumStr(const WideString & wsValue)4932 WideString CXFA_Node::NormalizeNumStr(const WideString& wsValue) {
4933   if (wsValue.IsEmpty())
4934     return WideString();
4935 
4936   WideString wsOutput = wsValue;
4937   wsOutput.TrimLeft('0');
4938 
4939   if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
4940     wsOutput.TrimRight(L"0");
4941     wsOutput.TrimRight(L".");
4942   }
4943   if (wsOutput.IsEmpty() || wsOutput[0] == '.')
4944     wsOutput.InsertAtFront('0');
4945 
4946   return wsOutput;
4947 }
4948 
InsertListTextItem(CXFA_Node * pItems,const WideString & wsText,int32_t nIndex)4949 void CXFA_Node::InsertListTextItem(CXFA_Node* pItems,
4950                                    const WideString& wsText,
4951                                    int32_t nIndex) {
4952   CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
4953   pItems->InsertChildAndNotify(nIndex, pText);
4954   pText->JSObject()->SetContent(wsText, wsText, false, false, false);
4955 }
4956 
NumericLimit(const WideString & wsValue)4957 WideString CXFA_Node::NumericLimit(const WideString& wsValue) {
4958   int32_t iLead = GetLeadDigits();
4959   int32_t iTread = GetFracDigits();
4960 
4961   if ((iLead == -1) && (iTread == -1))
4962     return wsValue;
4963 
4964   WideString wsRet;
4965   int32_t iLead_ = 0, iTread_ = -1;
4966   int32_t iCount = wsValue.GetLength();
4967   if (iCount == 0)
4968     return wsValue;
4969 
4970   int32_t i = 0;
4971   if (wsValue[i] == L'-') {
4972     wsRet += L'-';
4973     i++;
4974   }
4975   for (; i < iCount; i++) {
4976     wchar_t wc = wsValue[i];
4977     if (FXSYS_IsDecimalDigit(wc)) {
4978       if (iLead >= 0) {
4979         iLead_++;
4980         if (iLead_ > iLead)
4981           return L"0";
4982       } else if (iTread_ >= 0) {
4983         iTread_++;
4984         if (iTread_ > iTread) {
4985           if (iTread != -1) {
4986             CFGAS_Decimal wsDeci = CFGAS_Decimal(wsValue.AsStringView());
4987             wsDeci.SetScale(iTread);
4988             wsRet = wsDeci.ToWideString();
4989           }
4990           return wsRet;
4991         }
4992       }
4993     } else if (wc == L'.') {
4994       iTread_ = 0;
4995       iLead = -1;
4996     }
4997     wsRet += wc;
4998   }
4999   return wsRet;
5000 }
5001 
IsTransparent() const5002 bool CXFA_Node::IsTransparent() const {
5003   XFA_Element type = GetElementType();
5004   return type == XFA_Element::SubformSet || type == XFA_Element::Area ||
5005          type == XFA_Element::Proto || (IsUnnamed() && IsContainerNode());
5006 }
5007 
IsProperty() const5008 bool CXFA_Node::IsProperty() const {
5009   CXFA_Node* parent = GetParent();
5010   return parent && parent->HasProperty(GetElementType());
5011 }
5012 
PresenceRequiresSpace() const5013 bool CXFA_Node::PresenceRequiresSpace() const {
5014   auto value = JSObject()->TryEnum(XFA_Attribute::Presence, true);
5015   XFA_AttributeValue ePresence = value.value_or(XFA_AttributeValue::Visible);
5016   return ePresence == XFA_AttributeValue::Visible ||
5017          ePresence == XFA_AttributeValue::Invisible;
5018 }
5019 
SetBindingNode(CXFA_Node * node)5020 void CXFA_Node::SetBindingNode(CXFA_Node* node) {
5021   binding_nodes_.clear();
5022   if (node)
5023     binding_nodes_.emplace_back(node);
5024 }
5025 
SetNodeAndDescendantsUnused()5026 void CXFA_Node::SetNodeAndDescendantsUnused() {
5027   CXFA_NodeIterator sIterator(this);
5028   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
5029        pNode = sIterator.MoveToNext()) {
5030     pNode->SetFlag(XFA_NodeFlag_UnusedNode);
5031   }
5032 }
5033 
SetToXML(const WideString & value)5034 void CXFA_Node::SetToXML(const WideString& value) {
5035   auto* pNode = GetXMLMappingNode();
5036   switch (pNode->GetType()) {
5037     case CFX_XMLNode::Type::kElement: {
5038       auto* elem = static_cast<CFX_XMLElement*>(pNode);
5039       if (IsAttributeInXML()) {
5040         elem->SetAttribute(JSObject()->GetCData(XFA_Attribute::QualifiedName),
5041                            value);
5042         return;
5043       }
5044 
5045       bool bDeleteChildren = true;
5046       if (GetPacketType() == XFA_PacketType::Datasets) {
5047         for (CXFA_Node* pChildDataNode = GetFirstChild(); pChildDataNode;
5048              pChildDataNode = pChildDataNode->GetNextSibling()) {
5049           if (pChildDataNode->HasBindItems()) {
5050             bDeleteChildren = false;
5051             break;
5052           }
5053         }
5054       }
5055       if (bDeleteChildren)
5056         elem->RemoveAllChildren();
5057 
5058       auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(value);
5059       elem->AppendLastChild(text);
5060       break;
5061     }
5062     case CFX_XMLNode::Type::kText:
5063       ToXMLText(GetXMLMappingNode())->SetText(value);
5064       break;
5065     default:
5066       NOTREACHED();
5067   }
5068 }
5069 
GetTransparentParent()5070 CXFA_Node* CXFA_Node::GetTransparentParent() {
5071   CXFA_Node* parent = GetParent();
5072   while (parent) {
5073     XFA_Element type = parent->GetElementType();
5074     if (type == XFA_Element::Variables ||
5075         (type != XFA_Element::SubformSet && !parent->IsUnnamed())) {
5076       return parent;
5077     }
5078     parent = parent->GetParent();
5079   }
5080   return nullptr;
5081 }
5082 
GetXMLDocument() const5083 CFX_XMLDocument* CXFA_Node::GetXMLDocument() const {
5084   return GetDocument()->GetNotify()->GetHDOC()->GetXMLDocument();
5085 }
5086 
5087 // static
Create(CXFA_Document * doc,XFA_Element element,XFA_PacketType packet)5088 std::unique_ptr<CXFA_Node> CXFA_Node::Create(CXFA_Document* doc,
5089                                              XFA_Element element,
5090                                              XFA_PacketType packet) {
5091   std::unique_ptr<CXFA_Node> node;
5092   switch (element) {
5093     case XFA_Element::Ps:
5094       node = pdfium::MakeUnique<CXFA_Ps>(doc, packet);
5095       break;
5096     case XFA_Element::To:
5097       node = pdfium::MakeUnique<CXFA_To>(doc, packet);
5098       break;
5099     case XFA_Element::Ui:
5100       node = pdfium::MakeUnique<CXFA_Ui>(doc, packet);
5101       break;
5102     case XFA_Element::RecordSet:
5103       node = pdfium::MakeUnique<CXFA_RecordSet>(doc, packet);
5104       break;
5105     case XFA_Element::SubsetBelow:
5106       node = pdfium::MakeUnique<CXFA_SubsetBelow>(doc, packet);
5107       break;
5108     case XFA_Element::SubformSet:
5109       node = pdfium::MakeUnique<CXFA_SubformSet>(doc, packet);
5110       break;
5111     case XFA_Element::AdobeExtensionLevel:
5112       node = pdfium::MakeUnique<CXFA_AdobeExtensionLevel>(doc, packet);
5113       break;
5114     case XFA_Element::Typeface:
5115       node = pdfium::MakeUnique<CXFA_Typeface>(doc, packet);
5116       break;
5117     case XFA_Element::Break:
5118       node = pdfium::MakeUnique<CXFA_Break>(doc, packet);
5119       break;
5120     case XFA_Element::FontInfo:
5121       node = pdfium::MakeUnique<CXFA_FontInfo>(doc, packet);
5122       break;
5123     case XFA_Element::NumberPattern:
5124       node = pdfium::MakeUnique<CXFA_NumberPattern>(doc, packet);
5125       break;
5126     case XFA_Element::DynamicRender:
5127       node = pdfium::MakeUnique<CXFA_DynamicRender>(doc, packet);
5128       break;
5129     case XFA_Element::PrintScaling:
5130       node = pdfium::MakeUnique<CXFA_PrintScaling>(doc, packet);
5131       break;
5132     case XFA_Element::CheckButton:
5133       node = pdfium::MakeUnique<CXFA_CheckButton>(doc, packet);
5134       break;
5135     case XFA_Element::DatePatterns:
5136       node = pdfium::MakeUnique<CXFA_DatePatterns>(doc, packet);
5137       break;
5138     case XFA_Element::SourceSet:
5139       node = pdfium::MakeUnique<CXFA_SourceSet>(doc, packet);
5140       break;
5141     case XFA_Element::Amd:
5142       node = pdfium::MakeUnique<CXFA_Amd>(doc, packet);
5143       break;
5144     case XFA_Element::Arc:
5145       node = pdfium::MakeUnique<CXFA_Arc>(doc, packet);
5146       break;
5147     case XFA_Element::Day:
5148       node = pdfium::MakeUnique<CXFA_Day>(doc, packet);
5149       break;
5150     case XFA_Element::Era:
5151       node = pdfium::MakeUnique<CXFA_Era>(doc, packet);
5152       break;
5153     case XFA_Element::Jog:
5154       node = pdfium::MakeUnique<CXFA_Jog>(doc, packet);
5155       break;
5156     case XFA_Element::Log:
5157       node = pdfium::MakeUnique<CXFA_Log>(doc, packet);
5158       break;
5159     case XFA_Element::Map:
5160       node = pdfium::MakeUnique<CXFA_Map>(doc, packet);
5161       break;
5162     case XFA_Element::Mdp:
5163       node = pdfium::MakeUnique<CXFA_Mdp>(doc, packet);
5164       break;
5165     case XFA_Element::BreakBefore:
5166       node = pdfium::MakeUnique<CXFA_BreakBefore>(doc, packet);
5167       break;
5168     case XFA_Element::Oid:
5169       node = pdfium::MakeUnique<CXFA_Oid>(doc, packet);
5170       break;
5171     case XFA_Element::Pcl:
5172       node = pdfium::MakeUnique<CXFA_Pcl>(doc, packet);
5173       break;
5174     case XFA_Element::Pdf:
5175       node = pdfium::MakeUnique<CXFA_Pdf>(doc, packet);
5176       break;
5177     case XFA_Element::Ref:
5178       node = pdfium::MakeUnique<CXFA_Ref>(doc, packet);
5179       break;
5180     case XFA_Element::Uri:
5181       node = pdfium::MakeUnique<CXFA_Uri>(doc, packet);
5182       break;
5183     case XFA_Element::Xdc:
5184       node = pdfium::MakeUnique<CXFA_Xdc>(doc, packet);
5185       break;
5186     case XFA_Element::Xdp:
5187       node = pdfium::MakeUnique<CXFA_Xdp>(doc, packet);
5188       break;
5189     case XFA_Element::Xfa:
5190       node = pdfium::MakeUnique<CXFA_Xfa>(doc, packet);
5191       break;
5192     case XFA_Element::Xsl:
5193       node = pdfium::MakeUnique<CXFA_Xsl>(doc, packet);
5194       break;
5195     case XFA_Element::Zpl:
5196       node = pdfium::MakeUnique<CXFA_Zpl>(doc, packet);
5197       break;
5198     case XFA_Element::Cache:
5199       node = pdfium::MakeUnique<CXFA_Cache>(doc, packet);
5200       break;
5201     case XFA_Element::Margin:
5202       node = pdfium::MakeUnique<CXFA_Margin>(doc, packet);
5203       break;
5204     case XFA_Element::KeyUsage:
5205       node = pdfium::MakeUnique<CXFA_KeyUsage>(doc, packet);
5206       break;
5207     case XFA_Element::Exclude:
5208       node = pdfium::MakeUnique<CXFA_Exclude>(doc, packet);
5209       break;
5210     case XFA_Element::ChoiceList:
5211       node = pdfium::MakeUnique<CXFA_ChoiceList>(doc, packet);
5212       break;
5213     case XFA_Element::Level:
5214       node = pdfium::MakeUnique<CXFA_Level>(doc, packet);
5215       break;
5216     case XFA_Element::LabelPrinter:
5217       node = pdfium::MakeUnique<CXFA_LabelPrinter>(doc, packet);
5218       break;
5219     case XFA_Element::CalendarSymbols:
5220       node = pdfium::MakeUnique<CXFA_CalendarSymbols>(doc, packet);
5221       break;
5222     case XFA_Element::Para:
5223       node = pdfium::MakeUnique<CXFA_Para>(doc, packet);
5224       break;
5225     case XFA_Element::Part:
5226       node = pdfium::MakeUnique<CXFA_Part>(doc, packet);
5227       break;
5228     case XFA_Element::Pdfa:
5229       node = pdfium::MakeUnique<CXFA_Pdfa>(doc, packet);
5230       break;
5231     case XFA_Element::Filter:
5232       node = pdfium::MakeUnique<CXFA_Filter>(doc, packet);
5233       break;
5234     case XFA_Element::Present:
5235       node = pdfium::MakeUnique<CXFA_Present>(doc, packet);
5236       break;
5237     case XFA_Element::Pagination:
5238       node = pdfium::MakeUnique<CXFA_Pagination>(doc, packet);
5239       break;
5240     case XFA_Element::Encoding:
5241       node = pdfium::MakeUnique<CXFA_Encoding>(doc, packet);
5242       break;
5243     case XFA_Element::Event:
5244       node = pdfium::MakeUnique<CXFA_Event>(doc, packet);
5245       break;
5246     case XFA_Element::Whitespace:
5247       node = pdfium::MakeUnique<CXFA_Whitespace>(doc, packet);
5248       break;
5249     case XFA_Element::DefaultUi:
5250       node = pdfium::MakeUnique<CXFA_DefaultUi>(doc, packet);
5251       break;
5252     case XFA_Element::DataModel:
5253       node = pdfium::MakeUnique<CXFA_DataModel>(doc, packet);
5254       break;
5255     case XFA_Element::Barcode:
5256       node = pdfium::MakeUnique<CXFA_Barcode>(doc, packet);
5257       break;
5258     case XFA_Element::TimePattern:
5259       node = pdfium::MakeUnique<CXFA_TimePattern>(doc, packet);
5260       break;
5261     case XFA_Element::BatchOutput:
5262       node = pdfium::MakeUnique<CXFA_BatchOutput>(doc, packet);
5263       break;
5264     case XFA_Element::Enforce:
5265       node = pdfium::MakeUnique<CXFA_Enforce>(doc, packet);
5266       break;
5267     case XFA_Element::CurrencySymbols:
5268       node = pdfium::MakeUnique<CXFA_CurrencySymbols>(doc, packet);
5269       break;
5270     case XFA_Element::AddSilentPrint:
5271       node = pdfium::MakeUnique<CXFA_AddSilentPrint>(doc, packet);
5272       break;
5273     case XFA_Element::Rename:
5274       node = pdfium::MakeUnique<CXFA_Rename>(doc, packet);
5275       break;
5276     case XFA_Element::Operation:
5277       node = pdfium::MakeUnique<CXFA_Operation>(doc, packet);
5278       break;
5279     case XFA_Element::Typefaces:
5280       node = pdfium::MakeUnique<CXFA_Typefaces>(doc, packet);
5281       break;
5282     case XFA_Element::SubjectDNs:
5283       node = pdfium::MakeUnique<CXFA_SubjectDNs>(doc, packet);
5284       break;
5285     case XFA_Element::Issuers:
5286       node = pdfium::MakeUnique<CXFA_Issuers>(doc, packet);
5287       break;
5288     case XFA_Element::WsdlConnection:
5289       node = pdfium::MakeUnique<CXFA_WsdlConnection>(doc, packet);
5290       break;
5291     case XFA_Element::Debug:
5292       node = pdfium::MakeUnique<CXFA_Debug>(doc, packet);
5293       break;
5294     case XFA_Element::Delta:
5295       node = pdfium::MakeUnique<CXFA_Delta>(doc, packet);
5296       break;
5297     case XFA_Element::EraNames:
5298       node = pdfium::MakeUnique<CXFA_EraNames>(doc, packet);
5299       break;
5300     case XFA_Element::ModifyAnnots:
5301       node = pdfium::MakeUnique<CXFA_ModifyAnnots>(doc, packet);
5302       break;
5303     case XFA_Element::StartNode:
5304       node = pdfium::MakeUnique<CXFA_StartNode>(doc, packet);
5305       break;
5306     case XFA_Element::Button:
5307       node = pdfium::MakeUnique<CXFA_Button>(doc, packet);
5308       break;
5309     case XFA_Element::Format:
5310       node = pdfium::MakeUnique<CXFA_Format>(doc, packet);
5311       break;
5312     case XFA_Element::Border:
5313       node = pdfium::MakeUnique<CXFA_Border>(doc, packet);
5314       break;
5315     case XFA_Element::Area:
5316       node = pdfium::MakeUnique<CXFA_Area>(doc, packet);
5317       break;
5318     case XFA_Element::Hyphenation:
5319       node = pdfium::MakeUnique<CXFA_Hyphenation>(doc, packet);
5320       break;
5321     case XFA_Element::Text:
5322       node = pdfium::MakeUnique<CXFA_Text>(doc, packet);
5323       break;
5324     case XFA_Element::Time:
5325       node = pdfium::MakeUnique<CXFA_Time>(doc, packet);
5326       break;
5327     case XFA_Element::Type:
5328       node = pdfium::MakeUnique<CXFA_Type>(doc, packet);
5329       break;
5330     case XFA_Element::Overprint:
5331       node = pdfium::MakeUnique<CXFA_Overprint>(doc, packet);
5332       break;
5333     case XFA_Element::Certificates:
5334       node = pdfium::MakeUnique<CXFA_Certificates>(doc, packet);
5335       break;
5336     case XFA_Element::EncryptionMethods:
5337       node = pdfium::MakeUnique<CXFA_EncryptionMethods>(doc, packet);
5338       break;
5339     case XFA_Element::SetProperty:
5340       node = pdfium::MakeUnique<CXFA_SetProperty>(doc, packet);
5341       break;
5342     case XFA_Element::PrinterName:
5343       node = pdfium::MakeUnique<CXFA_PrinterName>(doc, packet);
5344       break;
5345     case XFA_Element::StartPage:
5346       node = pdfium::MakeUnique<CXFA_StartPage>(doc, packet);
5347       break;
5348     case XFA_Element::PageOffset:
5349       node = pdfium::MakeUnique<CXFA_PageOffset>(doc, packet);
5350       break;
5351     case XFA_Element::DateTime:
5352       node = pdfium::MakeUnique<CXFA_DateTime>(doc, packet);
5353       break;
5354     case XFA_Element::Comb:
5355       node = pdfium::MakeUnique<CXFA_Comb>(doc, packet);
5356       break;
5357     case XFA_Element::Pattern:
5358       node = pdfium::MakeUnique<CXFA_Pattern>(doc, packet);
5359       break;
5360     case XFA_Element::IfEmpty:
5361       node = pdfium::MakeUnique<CXFA_IfEmpty>(doc, packet);
5362       break;
5363     case XFA_Element::SuppressBanner:
5364       node = pdfium::MakeUnique<CXFA_SuppressBanner>(doc, packet);
5365       break;
5366     case XFA_Element::OutputBin:
5367       node = pdfium::MakeUnique<CXFA_OutputBin>(doc, packet);
5368       break;
5369     case XFA_Element::Field:
5370       node = pdfium::MakeUnique<CXFA_Field>(doc, packet);
5371       break;
5372     case XFA_Element::Agent:
5373       node = pdfium::MakeUnique<CXFA_Agent>(doc, packet);
5374       break;
5375     case XFA_Element::OutputXSL:
5376       node = pdfium::MakeUnique<CXFA_OutputXSL>(doc, packet);
5377       break;
5378     case XFA_Element::AdjustData:
5379       node = pdfium::MakeUnique<CXFA_AdjustData>(doc, packet);
5380       break;
5381     case XFA_Element::AutoSave:
5382       node = pdfium::MakeUnique<CXFA_AutoSave>(doc, packet);
5383       break;
5384     case XFA_Element::ContentArea:
5385       node = pdfium::MakeUnique<CXFA_ContentArea>(doc, packet);
5386       break;
5387     case XFA_Element::WsdlAddress:
5388       node = pdfium::MakeUnique<CXFA_WsdlAddress>(doc, packet);
5389       break;
5390     case XFA_Element::Solid:
5391       node = pdfium::MakeUnique<CXFA_Solid>(doc, packet);
5392       break;
5393     case XFA_Element::DateTimeSymbols:
5394       node = pdfium::MakeUnique<CXFA_DateTimeSymbols>(doc, packet);
5395       break;
5396     case XFA_Element::EncryptionLevel:
5397       node = pdfium::MakeUnique<CXFA_EncryptionLevel>(doc, packet);
5398       break;
5399     case XFA_Element::Edge:
5400       node = pdfium::MakeUnique<CXFA_Edge>(doc, packet);
5401       break;
5402     case XFA_Element::Stipple:
5403       node = pdfium::MakeUnique<CXFA_Stipple>(doc, packet);
5404       break;
5405     case XFA_Element::Attributes:
5406       node = pdfium::MakeUnique<CXFA_Attributes>(doc, packet);
5407       break;
5408     case XFA_Element::VersionControl:
5409       node = pdfium::MakeUnique<CXFA_VersionControl>(doc, packet);
5410       break;
5411     case XFA_Element::Meridiem:
5412       node = pdfium::MakeUnique<CXFA_Meridiem>(doc, packet);
5413       break;
5414     case XFA_Element::ExclGroup:
5415       node = pdfium::MakeUnique<CXFA_ExclGroup>(doc, packet);
5416       break;
5417     case XFA_Element::ToolTip:
5418       node = pdfium::MakeUnique<CXFA_ToolTip>(doc, packet);
5419       break;
5420     case XFA_Element::Compress:
5421       node = pdfium::MakeUnique<CXFA_Compress>(doc, packet);
5422       break;
5423     case XFA_Element::Reason:
5424       node = pdfium::MakeUnique<CXFA_Reason>(doc, packet);
5425       break;
5426     case XFA_Element::Execute:
5427       node = pdfium::MakeUnique<CXFA_Execute>(doc, packet);
5428       break;
5429     case XFA_Element::ContentCopy:
5430       node = pdfium::MakeUnique<CXFA_ContentCopy>(doc, packet);
5431       break;
5432     case XFA_Element::DateTimeEdit:
5433       node = pdfium::MakeUnique<CXFA_DateTimeEdit>(doc, packet);
5434       break;
5435     case XFA_Element::Config:
5436       node = pdfium::MakeUnique<CXFA_Config>(doc, packet);
5437       break;
5438     case XFA_Element::Image:
5439       node = pdfium::MakeUnique<CXFA_Image>(doc, packet);
5440       break;
5441     case XFA_Element::SharpxHTML:
5442       node = pdfium::MakeUnique<CXFA_SharpxHTML>(doc, packet);
5443       break;
5444     case XFA_Element::NumberOfCopies:
5445       node = pdfium::MakeUnique<CXFA_NumberOfCopies>(doc, packet);
5446       break;
5447     case XFA_Element::BehaviorOverride:
5448       node = pdfium::MakeUnique<CXFA_BehaviorOverride>(doc, packet);
5449       break;
5450     case XFA_Element::TimeStamp:
5451       node = pdfium::MakeUnique<CXFA_TimeStamp>(doc, packet);
5452       break;
5453     case XFA_Element::Month:
5454       node = pdfium::MakeUnique<CXFA_Month>(doc, packet);
5455       break;
5456     case XFA_Element::ViewerPreferences:
5457       node = pdfium::MakeUnique<CXFA_ViewerPreferences>(doc, packet);
5458       break;
5459     case XFA_Element::ScriptModel:
5460       node = pdfium::MakeUnique<CXFA_ScriptModel>(doc, packet);
5461       break;
5462     case XFA_Element::Decimal:
5463       node = pdfium::MakeUnique<CXFA_Decimal>(doc, packet);
5464       break;
5465     case XFA_Element::Subform:
5466       node = pdfium::MakeUnique<CXFA_Subform>(doc, packet);
5467       break;
5468     case XFA_Element::Select:
5469       node = pdfium::MakeUnique<CXFA_Select>(doc, packet);
5470       break;
5471     case XFA_Element::Window:
5472       node = pdfium::MakeUnique<CXFA_Window>(doc, packet);
5473       break;
5474     case XFA_Element::LocaleSet:
5475       node = pdfium::MakeUnique<CXFA_LocaleSet>(doc, packet);
5476       break;
5477     case XFA_Element::Handler:
5478       node = pdfium::MakeUnique<CXFA_Handler>(doc, packet);
5479       break;
5480     case XFA_Element::Presence:
5481       node = pdfium::MakeUnique<CXFA_Presence>(doc, packet);
5482       break;
5483     case XFA_Element::Record:
5484       node = pdfium::MakeUnique<CXFA_Record>(doc, packet);
5485       break;
5486     case XFA_Element::Embed:
5487       node = pdfium::MakeUnique<CXFA_Embed>(doc, packet);
5488       break;
5489     case XFA_Element::Version:
5490       node = pdfium::MakeUnique<CXFA_Version>(doc, packet);
5491       break;
5492     case XFA_Element::Command:
5493       node = pdfium::MakeUnique<CXFA_Command>(doc, packet);
5494       break;
5495     case XFA_Element::Copies:
5496       node = pdfium::MakeUnique<CXFA_Copies>(doc, packet);
5497       break;
5498     case XFA_Element::Staple:
5499       node = pdfium::MakeUnique<CXFA_Staple>(doc, packet);
5500       break;
5501     case XFA_Element::SubmitFormat:
5502       node = pdfium::MakeUnique<CXFA_SubmitFormat>(doc, packet);
5503       break;
5504     case XFA_Element::Boolean:
5505       node = pdfium::MakeUnique<CXFA_Boolean>(doc, packet);
5506       break;
5507     case XFA_Element::Message:
5508       node = pdfium::MakeUnique<CXFA_Message>(doc, packet);
5509       break;
5510     case XFA_Element::Output:
5511       node = pdfium::MakeUnique<CXFA_Output>(doc, packet);
5512       break;
5513     case XFA_Element::PsMap:
5514       node = pdfium::MakeUnique<CXFA_PsMap>(doc, packet);
5515       break;
5516     case XFA_Element::ExcludeNS:
5517       node = pdfium::MakeUnique<CXFA_ExcludeNS>(doc, packet);
5518       break;
5519     case XFA_Element::Assist:
5520       node = pdfium::MakeUnique<CXFA_Assist>(doc, packet);
5521       break;
5522     case XFA_Element::Picture:
5523       node = pdfium::MakeUnique<CXFA_Picture>(doc, packet);
5524       break;
5525     case XFA_Element::Traversal:
5526       node = pdfium::MakeUnique<CXFA_Traversal>(doc, packet);
5527       break;
5528     case XFA_Element::SilentPrint:
5529       node = pdfium::MakeUnique<CXFA_SilentPrint>(doc, packet);
5530       break;
5531     case XFA_Element::WebClient:
5532       node = pdfium::MakeUnique<CXFA_WebClient>(doc, packet);
5533       break;
5534     case XFA_Element::Producer:
5535       node = pdfium::MakeUnique<CXFA_Producer>(doc, packet);
5536       break;
5537     case XFA_Element::Corner:
5538       node = pdfium::MakeUnique<CXFA_Corner>(doc, packet);
5539       break;
5540     case XFA_Element::MsgId:
5541       node = pdfium::MakeUnique<CXFA_MsgId>(doc, packet);
5542       break;
5543     case XFA_Element::Color:
5544       node = pdfium::MakeUnique<CXFA_Color>(doc, packet);
5545       break;
5546     case XFA_Element::Keep:
5547       node = pdfium::MakeUnique<CXFA_Keep>(doc, packet);
5548       break;
5549     case XFA_Element::Query:
5550       node = pdfium::MakeUnique<CXFA_Query>(doc, packet);
5551       break;
5552     case XFA_Element::Insert:
5553       node = pdfium::MakeUnique<CXFA_Insert>(doc, packet);
5554       break;
5555     case XFA_Element::ImageEdit:
5556       node = pdfium::MakeUnique<CXFA_ImageEdit>(doc, packet);
5557       break;
5558     case XFA_Element::Validate:
5559       node = pdfium::MakeUnique<CXFA_Validate>(doc, packet);
5560       break;
5561     case XFA_Element::DigestMethods:
5562       node = pdfium::MakeUnique<CXFA_DigestMethods>(doc, packet);
5563       break;
5564     case XFA_Element::NumberPatterns:
5565       node = pdfium::MakeUnique<CXFA_NumberPatterns>(doc, packet);
5566       break;
5567     case XFA_Element::PageSet:
5568       node = pdfium::MakeUnique<CXFA_PageSet>(doc, packet);
5569       break;
5570     case XFA_Element::Integer:
5571       node = pdfium::MakeUnique<CXFA_Integer>(doc, packet);
5572       break;
5573     case XFA_Element::SoapAddress:
5574       node = pdfium::MakeUnique<CXFA_SoapAddress>(doc, packet);
5575       break;
5576     case XFA_Element::Equate:
5577       node = pdfium::MakeUnique<CXFA_Equate>(doc, packet);
5578       break;
5579     case XFA_Element::FormFieldFilling:
5580       node = pdfium::MakeUnique<CXFA_FormFieldFilling>(doc, packet);
5581       break;
5582     case XFA_Element::PageRange:
5583       node = pdfium::MakeUnique<CXFA_PageRange>(doc, packet);
5584       break;
5585     case XFA_Element::Update:
5586       node = pdfium::MakeUnique<CXFA_Update>(doc, packet);
5587       break;
5588     case XFA_Element::ConnectString:
5589       node = pdfium::MakeUnique<CXFA_ConnectString>(doc, packet);
5590       break;
5591     case XFA_Element::Mode:
5592       node = pdfium::MakeUnique<CXFA_Mode>(doc, packet);
5593       break;
5594     case XFA_Element::Layout:
5595       node = pdfium::MakeUnique<CXFA_Layout>(doc, packet);
5596       break;
5597     case XFA_Element::Sharpxml:
5598       node = pdfium::MakeUnique<CXFA_Sharpxml>(doc, packet);
5599       break;
5600     case XFA_Element::XsdConnection:
5601       node = pdfium::MakeUnique<CXFA_XsdConnection>(doc, packet);
5602       break;
5603     case XFA_Element::Traverse:
5604       node = pdfium::MakeUnique<CXFA_Traverse>(doc, packet);
5605       break;
5606     case XFA_Element::Encodings:
5607       node = pdfium::MakeUnique<CXFA_Encodings>(doc, packet);
5608       break;
5609     case XFA_Element::Template:
5610       node = pdfium::MakeUnique<CXFA_Template>(doc, packet);
5611       break;
5612     case XFA_Element::Acrobat:
5613       node = pdfium::MakeUnique<CXFA_Acrobat>(doc, packet);
5614       break;
5615     case XFA_Element::ValidationMessaging:
5616       node = pdfium::MakeUnique<CXFA_ValidationMessaging>(doc, packet);
5617       break;
5618     case XFA_Element::Signing:
5619       node = pdfium::MakeUnique<CXFA_Signing>(doc, packet);
5620       break;
5621     case XFA_Element::Script:
5622       node = pdfium::MakeUnique<CXFA_Script>(doc, packet);
5623       break;
5624     case XFA_Element::AddViewerPreferences:
5625       node = pdfium::MakeUnique<CXFA_AddViewerPreferences>(doc, packet);
5626       break;
5627     case XFA_Element::AlwaysEmbed:
5628       node = pdfium::MakeUnique<CXFA_AlwaysEmbed>(doc, packet);
5629       break;
5630     case XFA_Element::PasswordEdit:
5631       node = pdfium::MakeUnique<CXFA_PasswordEdit>(doc, packet);
5632       break;
5633     case XFA_Element::NumericEdit:
5634       node = pdfium::MakeUnique<CXFA_NumericEdit>(doc, packet);
5635       break;
5636     case XFA_Element::EncryptionMethod:
5637       node = pdfium::MakeUnique<CXFA_EncryptionMethod>(doc, packet);
5638       break;
5639     case XFA_Element::Change:
5640       node = pdfium::MakeUnique<CXFA_Change>(doc, packet);
5641       break;
5642     case XFA_Element::PageArea:
5643       node = pdfium::MakeUnique<CXFA_PageArea>(doc, packet);
5644       break;
5645     case XFA_Element::SubmitUrl:
5646       node = pdfium::MakeUnique<CXFA_SubmitUrl>(doc, packet);
5647       break;
5648     case XFA_Element::Oids:
5649       node = pdfium::MakeUnique<CXFA_Oids>(doc, packet);
5650       break;
5651     case XFA_Element::Signature:
5652       node = pdfium::MakeUnique<CXFA_Signature>(doc, packet);
5653       break;
5654     case XFA_Element::ADBE_JSConsole:
5655       node = pdfium::MakeUnique<CXFA_ADBE_JSConsole>(doc, packet);
5656       break;
5657     case XFA_Element::Caption:
5658       node = pdfium::MakeUnique<CXFA_Caption>(doc, packet);
5659       break;
5660     case XFA_Element::Relevant:
5661       node = pdfium::MakeUnique<CXFA_Relevant>(doc, packet);
5662       break;
5663     case XFA_Element::FlipLabel:
5664       node = pdfium::MakeUnique<CXFA_FlipLabel>(doc, packet);
5665       break;
5666     case XFA_Element::ExData:
5667       node = pdfium::MakeUnique<CXFA_ExData>(doc, packet);
5668       break;
5669     case XFA_Element::DayNames:
5670       node = pdfium::MakeUnique<CXFA_DayNames>(doc, packet);
5671       break;
5672     case XFA_Element::SoapAction:
5673       node = pdfium::MakeUnique<CXFA_SoapAction>(doc, packet);
5674       break;
5675     case XFA_Element::DefaultTypeface:
5676       node = pdfium::MakeUnique<CXFA_DefaultTypeface>(doc, packet);
5677       break;
5678     case XFA_Element::Manifest:
5679       node = pdfium::MakeUnique<CXFA_Manifest>(doc, packet);
5680       break;
5681     case XFA_Element::Overflow:
5682       node = pdfium::MakeUnique<CXFA_Overflow>(doc, packet);
5683       break;
5684     case XFA_Element::Linear:
5685       node = pdfium::MakeUnique<CXFA_Linear>(doc, packet);
5686       break;
5687     case XFA_Element::CurrencySymbol:
5688       node = pdfium::MakeUnique<CXFA_CurrencySymbol>(doc, packet);
5689       break;
5690     case XFA_Element::Delete:
5691       node = pdfium::MakeUnique<CXFA_Delete>(doc, packet);
5692       break;
5693     case XFA_Element::DigestMethod:
5694       node = pdfium::MakeUnique<CXFA_DigestMethod>(doc, packet);
5695       break;
5696     case XFA_Element::InstanceManager:
5697       node = pdfium::MakeUnique<CXFA_InstanceManager>(doc, packet);
5698       break;
5699     case XFA_Element::EquateRange:
5700       node = pdfium::MakeUnique<CXFA_EquateRange>(doc, packet);
5701       break;
5702     case XFA_Element::Medium:
5703       node = pdfium::MakeUnique<CXFA_Medium>(doc, packet);
5704       break;
5705     case XFA_Element::TextEdit:
5706       node = pdfium::MakeUnique<CXFA_TextEdit>(doc, packet);
5707       break;
5708     case XFA_Element::TemplateCache:
5709       node = pdfium::MakeUnique<CXFA_TemplateCache>(doc, packet);
5710       break;
5711     case XFA_Element::CompressObjectStream:
5712       node = pdfium::MakeUnique<CXFA_CompressObjectStream>(doc, packet);
5713       break;
5714     case XFA_Element::DataValue:
5715       node = pdfium::MakeUnique<CXFA_DataValue>(doc, packet);
5716       break;
5717     case XFA_Element::AccessibleContent:
5718       node = pdfium::MakeUnique<CXFA_AccessibleContent>(doc, packet);
5719       break;
5720     case XFA_Element::IncludeXDPContent:
5721       node = pdfium::MakeUnique<CXFA_IncludeXDPContent>(doc, packet);
5722       break;
5723     case XFA_Element::XmlConnection:
5724       node = pdfium::MakeUnique<CXFA_XmlConnection>(doc, packet);
5725       break;
5726     case XFA_Element::ValidateApprovalSignatures:
5727       node = pdfium::MakeUnique<CXFA_ValidateApprovalSignatures>(doc, packet);
5728       break;
5729     case XFA_Element::SignData:
5730       node = pdfium::MakeUnique<CXFA_SignData>(doc, packet);
5731       break;
5732     case XFA_Element::Packets:
5733       node = pdfium::MakeUnique<CXFA_Packets>(doc, packet);
5734       break;
5735     case XFA_Element::DatePattern:
5736       node = pdfium::MakeUnique<CXFA_DatePattern>(doc, packet);
5737       break;
5738     case XFA_Element::DuplexOption:
5739       node = pdfium::MakeUnique<CXFA_DuplexOption>(doc, packet);
5740       break;
5741     case XFA_Element::Base:
5742       node = pdfium::MakeUnique<CXFA_Base>(doc, packet);
5743       break;
5744     case XFA_Element::Bind:
5745       node = pdfium::MakeUnique<CXFA_Bind>(doc, packet);
5746       break;
5747     case XFA_Element::Compression:
5748       node = pdfium::MakeUnique<CXFA_Compression>(doc, packet);
5749       break;
5750     case XFA_Element::User:
5751       node = pdfium::MakeUnique<CXFA_User>(doc, packet);
5752       break;
5753     case XFA_Element::Rectangle:
5754       node = pdfium::MakeUnique<CXFA_Rectangle>(doc, packet);
5755       break;
5756     case XFA_Element::EffectiveOutputPolicy:
5757       node = pdfium::MakeUnique<CXFA_EffectiveOutputPolicy>(doc, packet);
5758       break;
5759     case XFA_Element::ADBE_JSDebugger:
5760       node = pdfium::MakeUnique<CXFA_ADBE_JSDebugger>(doc, packet);
5761       break;
5762     case XFA_Element::Acrobat7:
5763       node = pdfium::MakeUnique<CXFA_Acrobat7>(doc, packet);
5764       break;
5765     case XFA_Element::Interactive:
5766       node = pdfium::MakeUnique<CXFA_Interactive>(doc, packet);
5767       break;
5768     case XFA_Element::Locale:
5769       node = pdfium::MakeUnique<CXFA_Locale>(doc, packet);
5770       break;
5771     case XFA_Element::CurrentPage:
5772       node = pdfium::MakeUnique<CXFA_CurrentPage>(doc, packet);
5773       break;
5774     case XFA_Element::Data:
5775       node = pdfium::MakeUnique<CXFA_Data>(doc, packet);
5776       break;
5777     case XFA_Element::Date:
5778       node = pdfium::MakeUnique<CXFA_Date>(doc, packet);
5779       break;
5780     case XFA_Element::Desc:
5781       node = pdfium::MakeUnique<CXFA_Desc>(doc, packet);
5782       break;
5783     case XFA_Element::Encrypt:
5784       node = pdfium::MakeUnique<CXFA_Encrypt>(doc, packet);
5785       break;
5786     case XFA_Element::Draw:
5787       node = pdfium::MakeUnique<CXFA_Draw>(doc, packet);
5788       break;
5789     case XFA_Element::Encryption:
5790       node = pdfium::MakeUnique<CXFA_Encryption>(doc, packet);
5791       break;
5792     case XFA_Element::MeridiemNames:
5793       node = pdfium::MakeUnique<CXFA_MeridiemNames>(doc, packet);
5794       break;
5795     case XFA_Element::Messaging:
5796       node = pdfium::MakeUnique<CXFA_Messaging>(doc, packet);
5797       break;
5798     case XFA_Element::Speak:
5799       node = pdfium::MakeUnique<CXFA_Speak>(doc, packet);
5800       break;
5801     case XFA_Element::DataGroup:
5802       node = pdfium::MakeUnique<CXFA_DataGroup>(doc, packet);
5803       break;
5804     case XFA_Element::Common:
5805       node = pdfium::MakeUnique<CXFA_Common>(doc, packet);
5806       break;
5807     case XFA_Element::Sharptext:
5808       node = pdfium::MakeUnique<CXFA_Sharptext>(doc, packet);
5809       break;
5810     case XFA_Element::PaginationOverride:
5811       node = pdfium::MakeUnique<CXFA_PaginationOverride>(doc, packet);
5812       break;
5813     case XFA_Element::Reasons:
5814       node = pdfium::MakeUnique<CXFA_Reasons>(doc, packet);
5815       break;
5816     case XFA_Element::SignatureProperties:
5817       node = pdfium::MakeUnique<CXFA_SignatureProperties>(doc, packet);
5818       break;
5819     case XFA_Element::Threshold:
5820       node = pdfium::MakeUnique<CXFA_Threshold>(doc, packet);
5821       break;
5822     case XFA_Element::AppearanceFilter:
5823       node = pdfium::MakeUnique<CXFA_AppearanceFilter>(doc, packet);
5824       break;
5825     case XFA_Element::Fill:
5826       node = pdfium::MakeUnique<CXFA_Fill>(doc, packet);
5827       break;
5828     case XFA_Element::Font:
5829       node = pdfium::MakeUnique<CXFA_Font>(doc, packet);
5830       break;
5831     case XFA_Element::Form:
5832       node = pdfium::MakeUnique<CXFA_Form>(doc, packet);
5833       break;
5834     case XFA_Element::MediumInfo:
5835       node = pdfium::MakeUnique<CXFA_MediumInfo>(doc, packet);
5836       break;
5837     case XFA_Element::Certificate:
5838       node = pdfium::MakeUnique<CXFA_Certificate>(doc, packet);
5839       break;
5840     case XFA_Element::Password:
5841       node = pdfium::MakeUnique<CXFA_Password>(doc, packet);
5842       break;
5843     case XFA_Element::RunScripts:
5844       node = pdfium::MakeUnique<CXFA_RunScripts>(doc, packet);
5845       break;
5846     case XFA_Element::Trace:
5847       node = pdfium::MakeUnique<CXFA_Trace>(doc, packet);
5848       break;
5849     case XFA_Element::Float:
5850       node = pdfium::MakeUnique<CXFA_Float>(doc, packet);
5851       break;
5852     case XFA_Element::RenderPolicy:
5853       node = pdfium::MakeUnique<CXFA_RenderPolicy>(doc, packet);
5854       break;
5855     case XFA_Element::Destination:
5856       node = pdfium::MakeUnique<CXFA_Destination>(doc, packet);
5857       break;
5858     case XFA_Element::Value:
5859       node = pdfium::MakeUnique<CXFA_Value>(doc, packet);
5860       break;
5861     case XFA_Element::Bookend:
5862       node = pdfium::MakeUnique<CXFA_Bookend>(doc, packet);
5863       break;
5864     case XFA_Element::ExObject:
5865       node = pdfium::MakeUnique<CXFA_ExObject>(doc, packet);
5866       break;
5867     case XFA_Element::OpenAction:
5868       node = pdfium::MakeUnique<CXFA_OpenAction>(doc, packet);
5869       break;
5870     case XFA_Element::NeverEmbed:
5871       node = pdfium::MakeUnique<CXFA_NeverEmbed>(doc, packet);
5872       break;
5873     case XFA_Element::BindItems:
5874       node = pdfium::MakeUnique<CXFA_BindItems>(doc, packet);
5875       break;
5876     case XFA_Element::Calculate:
5877       node = pdfium::MakeUnique<CXFA_Calculate>(doc, packet);
5878       break;
5879     case XFA_Element::Print:
5880       node = pdfium::MakeUnique<CXFA_Print>(doc, packet);
5881       break;
5882     case XFA_Element::Extras:
5883       node = pdfium::MakeUnique<CXFA_Extras>(doc, packet);
5884       break;
5885     case XFA_Element::Proto:
5886       node = pdfium::MakeUnique<CXFA_Proto>(doc, packet);
5887       break;
5888     case XFA_Element::DSigData:
5889       node = pdfium::MakeUnique<CXFA_DSigData>(doc, packet);
5890       break;
5891     case XFA_Element::Creator:
5892       node = pdfium::MakeUnique<CXFA_Creator>(doc, packet);
5893       break;
5894     case XFA_Element::Connect:
5895       node = pdfium::MakeUnique<CXFA_Connect>(doc, packet);
5896       break;
5897     case XFA_Element::Permissions:
5898       node = pdfium::MakeUnique<CXFA_Permissions>(doc, packet);
5899       break;
5900     case XFA_Element::ConnectionSet:
5901       node = pdfium::MakeUnique<CXFA_ConnectionSet>(doc, packet);
5902       break;
5903     case XFA_Element::Submit:
5904       node = pdfium::MakeUnique<CXFA_Submit>(doc, packet);
5905       break;
5906     case XFA_Element::Range:
5907       node = pdfium::MakeUnique<CXFA_Range>(doc, packet);
5908       break;
5909     case XFA_Element::Linearized:
5910       node = pdfium::MakeUnique<CXFA_Linearized>(doc, packet);
5911       break;
5912     case XFA_Element::Packet:
5913       node = pdfium::MakeUnique<CXFA_Packet>(doc, packet);
5914       break;
5915     case XFA_Element::RootElement:
5916       node = pdfium::MakeUnique<CXFA_RootElement>(doc, packet);
5917       break;
5918     case XFA_Element::PlaintextMetadata:
5919       node = pdfium::MakeUnique<CXFA_PlaintextMetadata>(doc, packet);
5920       break;
5921     case XFA_Element::NumberSymbols:
5922       node = pdfium::MakeUnique<CXFA_NumberSymbols>(doc, packet);
5923       break;
5924     case XFA_Element::PrintHighQuality:
5925       node = pdfium::MakeUnique<CXFA_PrintHighQuality>(doc, packet);
5926       break;
5927     case XFA_Element::Driver:
5928       node = pdfium::MakeUnique<CXFA_Driver>(doc, packet);
5929       break;
5930     case XFA_Element::IncrementalLoad:
5931       node = pdfium::MakeUnique<CXFA_IncrementalLoad>(doc, packet);
5932       break;
5933     case XFA_Element::SubjectDN:
5934       node = pdfium::MakeUnique<CXFA_SubjectDN>(doc, packet);
5935       break;
5936     case XFA_Element::CompressLogicalStructure:
5937       node = pdfium::MakeUnique<CXFA_CompressLogicalStructure>(doc, packet);
5938       break;
5939     case XFA_Element::IncrementalMerge:
5940       node = pdfium::MakeUnique<CXFA_IncrementalMerge>(doc, packet);
5941       break;
5942     case XFA_Element::Radial:
5943       node = pdfium::MakeUnique<CXFA_Radial>(doc, packet);
5944       break;
5945     case XFA_Element::Variables:
5946       node = pdfium::MakeUnique<CXFA_Variables>(doc, packet);
5947       break;
5948     case XFA_Element::TimePatterns:
5949       node = pdfium::MakeUnique<CXFA_TimePatterns>(doc, packet);
5950       break;
5951     case XFA_Element::EffectiveInputPolicy:
5952       node = pdfium::MakeUnique<CXFA_EffectiveInputPolicy>(doc, packet);
5953       break;
5954     case XFA_Element::NameAttr:
5955       node = pdfium::MakeUnique<CXFA_NameAttr>(doc, packet);
5956       break;
5957     case XFA_Element::Conformance:
5958       node = pdfium::MakeUnique<CXFA_Conformance>(doc, packet);
5959       break;
5960     case XFA_Element::Transform:
5961       node = pdfium::MakeUnique<CXFA_Transform>(doc, packet);
5962       break;
5963     case XFA_Element::LockDocument:
5964       node = pdfium::MakeUnique<CXFA_LockDocument>(doc, packet);
5965       break;
5966     case XFA_Element::BreakAfter:
5967       node = pdfium::MakeUnique<CXFA_BreakAfter>(doc, packet);
5968       break;
5969     case XFA_Element::Line:
5970       node = pdfium::MakeUnique<CXFA_Line>(doc, packet);
5971       break;
5972     case XFA_Element::Source:
5973       node = pdfium::MakeUnique<CXFA_Source>(doc, packet);
5974       break;
5975     case XFA_Element::Occur:
5976       node = pdfium::MakeUnique<CXFA_Occur>(doc, packet);
5977       break;
5978     case XFA_Element::PickTrayByPDFSize:
5979       node = pdfium::MakeUnique<CXFA_PickTrayByPDFSize>(doc, packet);
5980       break;
5981     case XFA_Element::MonthNames:
5982       node = pdfium::MakeUnique<CXFA_MonthNames>(doc, packet);
5983       break;
5984     case XFA_Element::Severity:
5985       node = pdfium::MakeUnique<CXFA_Severity>(doc, packet);
5986       break;
5987     case XFA_Element::GroupParent:
5988       node = pdfium::MakeUnique<CXFA_GroupParent>(doc, packet);
5989       break;
5990     case XFA_Element::DocumentAssembly:
5991       node = pdfium::MakeUnique<CXFA_DocumentAssembly>(doc, packet);
5992       break;
5993     case XFA_Element::NumberSymbol:
5994       node = pdfium::MakeUnique<CXFA_NumberSymbol>(doc, packet);
5995       break;
5996     case XFA_Element::Tagged:
5997       node = pdfium::MakeUnique<CXFA_Tagged>(doc, packet);
5998       break;
5999     case XFA_Element::Items:
6000       node = pdfium::MakeUnique<CXFA_Items>(doc, packet);
6001       break;
6002     default:
6003       NOTREACHED();
6004       return nullptr;
6005   }
6006   if (!node || !node->IsValidInPacket(packet))
6007     return nullptr;
6008   return node;
6009 }
6010