xref: /aosp_15_r20/external/pdfium/xfa/fxfa/parser/xfa_basic_data.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/parser/xfa_basic_data.h"
8 
9 #include <iterator>
10 #include <utility>
11 
12 #include "fxjs/xfa/cjx_boolean.h"
13 #include "fxjs/xfa/cjx_container.h"
14 #include "fxjs/xfa/cjx_datawindow.h"
15 #include "fxjs/xfa/cjx_delta.h"
16 #include "fxjs/xfa/cjx_desc.h"
17 #include "fxjs/xfa/cjx_draw.h"
18 #include "fxjs/xfa/cjx_encrypt.h"
19 #include "fxjs/xfa/cjx_eventpseudomodel.h"
20 #include "fxjs/xfa/cjx_exclgroup.h"
21 #include "fxjs/xfa/cjx_extras.h"
22 #include "fxjs/xfa/cjx_field.h"
23 #include "fxjs/xfa/cjx_form.h"
24 #include "fxjs/xfa/cjx_handler.h"
25 #include "fxjs/xfa/cjx_hostpseudomodel.h"
26 #include "fxjs/xfa/cjx_instancemanager.h"
27 #include "fxjs/xfa/cjx_layoutpseudomodel.h"
28 #include "fxjs/xfa/cjx_logpseudomodel.h"
29 #include "fxjs/xfa/cjx_manifest.h"
30 #include "fxjs/xfa/cjx_model.h"
31 #include "fxjs/xfa/cjx_node.h"
32 #include "fxjs/xfa/cjx_occur.h"
33 #include "fxjs/xfa/cjx_packet.h"
34 #include "fxjs/xfa/cjx_script.h"
35 #include "fxjs/xfa/cjx_signaturepseudomodel.h"
36 #include "fxjs/xfa/cjx_source.h"
37 #include "fxjs/xfa/cjx_subform.h"
38 #include "fxjs/xfa/cjx_textnode.h"
39 #include "fxjs/xfa/cjx_tree.h"
40 #include "fxjs/xfa/cjx_treelist.h"
41 #include "fxjs/xfa/cjx_wsdlconnection.h"
42 #include "fxjs/xfa/cjx_xfa.h"
43 #include "xfa/fxfa/fxfa_basic.h"
44 
45 namespace {
46 
47 struct PacketTableRecord {
48   uint32_t hash;
49   XFA_PACKETINFO info;
50 };
51 
52 const PacketTableRecord kPacketTable[] = {
53 #undef PCKT____
54 #define PCKT____(a, b, c, d, e, f) \
55   {a, {XFA_PacketType::c, XFA_PacketMatch::e, XFA_PacketSupport::f, b, d}},
56 #include "xfa/fxfa/parser/packets.inc"
57 #undef PCKT____
58 };
59 
60 struct ElementRecord {
61   uint32_t hash;  // Hashed as wide string.
62   XFA_Element element;
63   XFA_Element parent;
64 };
65 
66 // Contains read-only data that do not require relocation.
67 // Parts that require relocation are in `kElementNames` below.
68 constexpr ElementRecord kElementRecords[] = {
69 #undef ELEM____
70 #define ELEM____(a, b, c, d) {a, XFA_Element::c, XFA_Element::d},
71 #include "xfa/fxfa/parser/elements.inc"
72 #undef ELEM____
73 };
74 
75 constexpr const char* kElementNames[] = {
76 #undef ELEM____
77 #define ELEM____(a, b, c, d) b,
78 #include "xfa/fxfa/parser/elements.inc"
79 #undef ELEM____
80 };
81 
82 static_assert(std::size(kElementRecords) == std::size(kElementNames),
83               "Size mismatch");
84 
85 struct AttributeRecord {
86   uint32_t hash;  // Hashed as wide string.
87   XFA_Attribute attribute;
88   XFA_ScriptType script_type;
89 };
90 
91 // Contains read-only data that do not require relocation.
92 // Parts that require relocation are in `kAttributeNames` below.
93 constexpr AttributeRecord kAttributeRecords[] = {
94 #undef ATTR____
95 #define ATTR____(a, b, c, d) {a, XFA_Attribute::c, XFA_ScriptType::d},
96 #include "xfa/fxfa/parser/attributes.inc"
97 #undef ATTR____
98 };
99 
100 constexpr const char* kAttributeNames[] = {
101 #undef ATTR____
102 #define ATTR____(a, b, c, d) b,
103 #include "xfa/fxfa/parser/attributes.inc"
104 #undef ATTR____
105 };
106 
107 static_assert(std::size(kAttributeRecords) == std::size(kAttributeNames),
108               "Size mismatch");
109 
110 struct AttributeValueRecord {
111   // Associated entry in `kAttributeValueNames` hashed as WideString.
112   uint32_t uHash;
113   XFA_AttributeValue eName;
114 };
115 
116 // Contains read-only data that do not require relocation.
117 // Parts that require relocation are in `kAttributeValueNames` below.
118 constexpr AttributeValueRecord kAttributeValueRecords[] = {
119 #undef VALUE____
120 #define VALUE____(a, b, c) {a, XFA_AttributeValue::c},
121 #include "xfa/fxfa/parser/attribute_values.inc"
122 #undef VALUE____
123 };
124 
125 constexpr const char* kAttributeValueNames[] = {
126 #undef VALUE____
127 #define VALUE____(a, b, c) b,
128 #include "xfa/fxfa/parser/attribute_values.inc"
129 #undef VALUE____
130 };
131 
132 static_assert(std::size(kAttributeValueRecords) ==
133                   std::size(kAttributeValueNames),
134               "Size mismatch");
135 
136 struct ElementAttributeRecord {
137   XFA_Element element;
138   XFA_Attribute attribute;
139 };
140 
141 // Contains read-only data that do not require relocation.
142 // Parts that require relocation are in `kElementAttributeCallbacks` below.
143 constexpr ElementAttributeRecord kElementAttributeRecords[] = {
144 #undef ELEM_ATTR____
145 #define ELEM_ATTR____(a, b, c) {XFA_Element::a, XFA_Attribute::b},
146 #include "xfa/fxfa/parser/element_attributes.inc"
147 #undef ELEM_ATTR____
148 };
149 
150 constexpr XFA_ATTRIBUTE_CALLBACK kElementAttributeCallbacks[] = {
151 #undef ELEM_ATTR____
152 #define ELEM_ATTR____(a, b, c) c##_static,
153 #include "xfa/fxfa/parser/element_attributes.inc"
154 #undef ELEM_ATTR____
155 };
156 
157 static_assert(std::size(kElementAttributeRecords) ==
158                   std::size(kElementAttributeCallbacks),
159               "Size mismatch");
160 
161 }  // namespace
162 
XFA_GetPacketByIndex(XFA_PacketType ePacket)163 XFA_PACKETINFO XFA_GetPacketByIndex(XFA_PacketType ePacket) {
164   return kPacketTable[static_cast<uint8_t>(ePacket)].info;
165 }
166 
XFA_GetPacketByName(WideStringView wsName)167 absl::optional<XFA_PACKETINFO> XFA_GetPacketByName(WideStringView wsName) {
168   uint32_t hash = FX_HashCode_GetW(wsName);
169   auto* elem = std::lower_bound(
170       std::begin(kPacketTable), std::end(kPacketTable), hash,
171       [](const PacketTableRecord& a, uint32_t hash) { return a.hash < hash; });
172   if (elem != std::end(kPacketTable) && wsName.EqualsASCII(elem->info.name))
173     return elem->info;
174   return absl::nullopt;
175 }
176 
XFA_ElementToName(XFA_Element elem)177 ByteStringView XFA_ElementToName(XFA_Element elem) {
178   return kElementNames[static_cast<size_t>(elem)];
179 }
180 
XFA_GetElementByName(WideStringView name)181 XFA_Element XFA_GetElementByName(WideStringView name) {
182   uint32_t hash = FX_HashCode_GetW(name);
183   auto* elem = std::lower_bound(
184       std::begin(kElementRecords), std::end(kElementRecords), hash,
185       [](const ElementRecord& a, uint32_t hash) { return a.hash < hash; });
186   if (elem == std::end(kElementRecords))
187     return XFA_Element::Unknown;
188 
189   size_t index = std::distance(std::begin(kElementRecords), elem);
190   return name.EqualsASCII(kElementNames[index]) ? elem->element
191                                                 : XFA_Element::Unknown;
192 }
193 
XFA_AttributeToName(XFA_Attribute attr)194 ByteStringView XFA_AttributeToName(XFA_Attribute attr) {
195   return kAttributeNames[static_cast<size_t>(attr)];
196 }
197 
XFA_GetAttributeByName(WideStringView name)198 absl::optional<XFA_ATTRIBUTEINFO> XFA_GetAttributeByName(WideStringView name) {
199   uint32_t hash = FX_HashCode_GetW(name);
200   auto* elem = std::lower_bound(
201       std::begin(kAttributeRecords), std::end(kAttributeRecords), hash,
202       [](const AttributeRecord& a, uint32_t hash) { return a.hash < hash; });
203   if (elem == std::end(kAttributeRecords))
204     return absl::nullopt;
205 
206   size_t index = std::distance(std::begin(kAttributeRecords), elem);
207   if (!name.EqualsASCII(kAttributeNames[index]))
208     return absl::nullopt;
209 
210   XFA_ATTRIBUTEINFO result;
211   result.attribute = elem->attribute;
212   result.eValueType = elem->script_type;
213   return result;
214 }
215 
XFA_AttributeValueToName(XFA_AttributeValue item)216 ByteStringView XFA_AttributeValueToName(XFA_AttributeValue item) {
217   return kAttributeValueNames[static_cast<int32_t>(item)];
218 }
219 
XFA_GetAttributeValueByName(WideStringView name)220 absl::optional<XFA_AttributeValue> XFA_GetAttributeValueByName(
221     WideStringView name) {
222   auto* it =
223       std::lower_bound(std::begin(kAttributeValueRecords),
224                        std::end(kAttributeValueRecords), FX_HashCode_GetW(name),
225                        [](const AttributeValueRecord& arg, uint32_t hash) {
226                          return arg.uHash < hash;
227                        });
228   if (it == std::end(kAttributeValueRecords))
229     return absl::nullopt;
230 
231   size_t index = std::distance(std::begin(kAttributeValueRecords), it);
232   if (!name.EqualsASCII(kAttributeValueNames[index]))
233     return absl::nullopt;
234 
235   return it->eName;
236 }
237 
XFA_GetScriptAttributeByName(XFA_Element element,WideStringView attribute_name)238 absl::optional<XFA_SCRIPTATTRIBUTEINFO> XFA_GetScriptAttributeByName(
239     XFA_Element element,
240     WideStringView attribute_name) {
241   absl::optional<XFA_ATTRIBUTEINFO> attr =
242       XFA_GetAttributeByName(attribute_name);
243   if (!attr.has_value())
244     return absl::nullopt;
245 
246   while (element != XFA_Element::Unknown) {
247     auto compound_key = std::make_pair(element, attr.value().attribute);
248     auto* it = std::lower_bound(
249         std::begin(kElementAttributeRecords),
250         std::end(kElementAttributeRecords), compound_key,
251         [](const ElementAttributeRecord& arg,
252            const std::pair<XFA_Element, XFA_Attribute>& key) {
253           return std::make_pair(arg.element, arg.attribute) < key;
254         });
255     if (it != std::end(kElementAttributeRecords) &&
256         compound_key == std::make_pair(it->element, it->attribute)) {
257       XFA_SCRIPTATTRIBUTEINFO result;
258       result.attribute = attr.value().attribute;
259       result.eValueType = attr.value().eValueType;
260       size_t index = std::distance(std::begin(kElementAttributeRecords), it);
261       result.callback = kElementAttributeCallbacks[index];
262       return result;
263     }
264     element = kElementRecords[static_cast<size_t>(element)].parent;
265   }
266   return absl::nullopt;
267 }
268