• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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/xfa_utils.h"
8 
9 #include "core/fxcrt/fx_ext.h"
10 #include "xfa/fde/xml/fde_xml_imp.h"
11 #include "xfa/fxfa/parser/cxfa_document.h"
12 #include "xfa/fxfa/parser/cxfa_measurement.h"
13 #include "xfa/fxfa/parser/xfa_basic_data.h"
14 #include "xfa/fxfa/parser/xfa_localemgr.h"
15 #include "xfa/fxfa/parser/xfa_localevalue.h"
16 #include "xfa/fxfa/parser/xfa_object.h"
17 
18 namespace {
19 
20 const FX_DOUBLE fraction_scales[] = {0.1,
21                                      0.01,
22                                      0.001,
23                                      0.0001,
24                                      0.00001,
25                                      0.000001,
26                                      0.0000001,
27                                      0.00000001,
28                                      0.000000001,
29                                      0.0000000001,
30                                      0.00000000001,
31                                      0.000000000001,
32                                      0.0000000000001,
33                                      0.00000000000001,
34                                      0.000000000000001,
35                                      0.0000000000000001};
36 
WideStringToDouble(const CFX_WideString & wsStringVal)37 FX_DOUBLE WideStringToDouble(const CFX_WideString& wsStringVal) {
38   CFX_WideString wsValue = wsStringVal;
39   wsValue.TrimLeft();
40   wsValue.TrimRight();
41   int64_t nIntegral = 0;
42   uint32_t dwFractional = 0;
43   int32_t nExponent = 0;
44   int32_t cc = 0;
45   bool bNegative = false;
46   bool bExpSign = false;
47   const FX_WCHAR* str = wsValue.c_str();
48   int32_t len = wsValue.GetLength();
49   if (str[0] == '+') {
50     cc++;
51   } else if (str[0] == '-') {
52     bNegative = true;
53     cc++;
54   }
55   int32_t nIntegralLen = 0;
56   while (cc < len) {
57     if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' ||
58         nIntegralLen > 17) {
59       break;
60     }
61     if (!FXSYS_isDecimalDigit(str[cc])) {
62       return 0;
63     }
64     nIntegral = nIntegral * 10 + str[cc] - '0';
65     cc++;
66     nIntegralLen++;
67   }
68   nIntegral = bNegative ? -nIntegral : nIntegral;
69   int32_t scale = 0;
70   FX_DOUBLE fraction = 0.0;
71   if (cc < len && str[cc] == '.') {
72     cc++;
73     while (cc < len) {
74       fraction += fraction_scales[scale] * (str[cc] - '0');
75       scale++;
76       cc++;
77       if (cc == len) {
78         break;
79       }
80       if (scale == sizeof(fraction_scales) / sizeof(FX_DOUBLE) ||
81           str[cc] == 'E' || str[cc] == 'e') {
82         break;
83       }
84       if (!FXSYS_isDecimalDigit(str[cc])) {
85         return 0;
86       }
87     }
88     dwFractional = (uint32_t)(fraction * 4294967296.0);
89   }
90   if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
91     cc++;
92     if (cc < len) {
93       if (str[cc] == '+') {
94         cc++;
95       } else if (str[cc] == '-') {
96         bExpSign = true;
97         cc++;
98       }
99     }
100     while (cc < len) {
101       if (str[cc] == '.' || !FXSYS_isDecimalDigit(str[cc])) {
102         return 0;
103       }
104       nExponent = nExponent * 10 + str[cc] - '0';
105       cc++;
106     }
107     nExponent = bExpSign ? -nExponent : nExponent;
108   }
109   FX_DOUBLE dValue = (dwFractional / 4294967296.0);
110   dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
111   if (nExponent != 0) {
112     dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
113   }
114   return dValue;
115 }
116 
117 }  // namespace
118 
XFA_GetLocaleValue(CXFA_WidgetData * pWidgetData)119 CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData) {
120   CXFA_Node* pNodeValue =
121       pWidgetData->GetNode()->GetChild(0, XFA_Element::Value);
122   if (!pNodeValue) {
123     return CXFA_LocaleValue();
124   }
125   CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
126   if (!pValueChild) {
127     return CXFA_LocaleValue();
128   }
129   int32_t iVTType = XFA_VT_NULL;
130   switch (pValueChild->GetElementType()) {
131     case XFA_Element::Decimal:
132       iVTType = XFA_VT_DECIMAL;
133       break;
134     case XFA_Element::Float:
135       iVTType = XFA_VT_FLOAT;
136       break;
137     case XFA_Element::Date:
138       iVTType = XFA_VT_DATE;
139       break;
140     case XFA_Element::Time:
141       iVTType = XFA_VT_TIME;
142       break;
143     case XFA_Element::DateTime:
144       iVTType = XFA_VT_DATETIME;
145       break;
146     case XFA_Element::Boolean:
147       iVTType = XFA_VT_BOOLEAN;
148       break;
149     case XFA_Element::Integer:
150       iVTType = XFA_VT_INTEGER;
151       break;
152     case XFA_Element::Text:
153       iVTType = XFA_VT_TEXT;
154       break;
155     default:
156       iVTType = XFA_VT_NULL;
157       break;
158   }
159   return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(),
160                           pWidgetData->GetNode()->GetDocument()->GetLocalMgr());
161 }
XFA_GetPlainTextFromRichText(CFDE_XMLNode * pXMLNode,CFX_WideString & wsPlainText)162 void XFA_GetPlainTextFromRichText(CFDE_XMLNode* pXMLNode,
163                                   CFX_WideString& wsPlainText) {
164   if (!pXMLNode) {
165     return;
166   }
167   switch (pXMLNode->GetType()) {
168     case FDE_XMLNODE_Element: {
169       CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
170       CFX_WideString wsTag;
171       pXMLElement->GetLocalTagName(wsTag);
172       uint32_t uTag = FX_HashCode_GetW(wsTag.AsStringC(), true);
173       if (uTag == 0x0001f714) {
174         wsPlainText += L"\n";
175       } else if (uTag == 0x00000070) {
176         if (!wsPlainText.IsEmpty()) {
177           wsPlainText += L"\n";
178         }
179       } else if (uTag == 0xa48ac63) {
180         if (!wsPlainText.IsEmpty() &&
181             wsPlainText[wsPlainText.GetLength() - 1] != '\n') {
182           wsPlainText += L"\n";
183         }
184       }
185     } break;
186     case FDE_XMLNODE_Text: {
187       CFX_WideString wsContent;
188       static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsContent);
189       wsPlainText += wsContent;
190     } break;
191     case FDE_XMLNODE_CharData: {
192       CFX_WideString wsCharData;
193       static_cast<CFDE_XMLCharData*>(pXMLNode)->GetCharData(wsCharData);
194       wsPlainText += wsCharData;
195     } break;
196     default:
197       break;
198   }
199   for (CFDE_XMLNode* pChildXML =
200            pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
201        pChildXML;
202        pChildXML = pChildXML->GetNodeItem(CFDE_XMLNode::NextSibling)) {
203     XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
204   }
205 }
206 
XFA_FieldIsMultiListBox(CXFA_Node * pFieldNode)207 bool XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) {
208   bool bRet = false;
209   if (!pFieldNode)
210     return bRet;
211 
212   CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_Element::Ui);
213   if (pUIChild) {
214     CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
215     if (pFirstChild &&
216         pFirstChild->GetElementType() == XFA_Element::ChoiceList) {
217       bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) ==
218              XFA_ATTRIBUTEENUM_MultiSelect;
219     }
220   }
221   return bRet;
222 }
223 
XFA_ByteStringToDouble(const CFX_ByteStringC & szStringVal)224 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) {
225   CFX_WideString wsValue = CFX_WideString::FromUTF8(szStringVal);
226   return WideStringToDouble(wsValue);
227 }
228 
XFA_MapRotation(int32_t nRotation)229 int32_t XFA_MapRotation(int32_t nRotation) {
230   nRotation = nRotation % 360;
231   nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
232   return nRotation;
233 }
234 
XFA_GetScriptAttributeByName(XFA_Element eElement,const CFX_WideStringC & wsAttributeName)235 const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
236     XFA_Element eElement,
237     const CFX_WideStringC& wsAttributeName) {
238   if (wsAttributeName.IsEmpty())
239     return nullptr;
240 
241   int32_t iElementIndex = static_cast<int32_t>(eElement);
242   while (iElementIndex != -1) {
243     const XFA_SCRIPTHIERARCHY* scriptIndex = g_XFAScriptIndex + iElementIndex;
244     int32_t icount = scriptIndex->wAttributeCount;
245     if (icount == 0) {
246       iElementIndex = scriptIndex->wParentIndex;
247       continue;
248     }
249     uint32_t uHash = FX_HashCode_GetW(wsAttributeName, false);
250     int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
251     do {
252       int32_t iMid = (iStart + iEnd) / 2;
253       const XFA_SCRIPTATTRIBUTEINFO* pInfo = g_SomAttributeData + iMid;
254       if (uHash == pInfo->uHash)
255         return pInfo;
256       if (uHash < pInfo->uHash)
257         iEnd = iMid - 1;
258       else
259         iStart = iMid + 1;
260     } while (iStart <= iEnd);
261     iElementIndex = scriptIndex->wParentIndex;
262   }
263   return nullptr;
264 }
265 
XFA_GetNotsureAttribute(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,XFA_ATTRIBUTETYPE eType)266 const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(XFA_Element eElement,
267                                                     XFA_ATTRIBUTE eAttribute,
268                                                     XFA_ATTRIBUTETYPE eType) {
269   int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1;
270   do {
271     int32_t iMid = (iStart + iEnd) / 2;
272     const XFA_NOTSUREATTRIBUTE* pAttr = g_XFANotsureAttributes + iMid;
273     if (eElement == pAttr->eElement) {
274       if (pAttr->eAttribute == eAttribute) {
275         if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
276           return pAttr;
277         return nullptr;
278       }
279       int32_t iBefore = iMid - 1;
280       if (iBefore >= 0) {
281         pAttr = g_XFANotsureAttributes + iBefore;
282         while (eElement == pAttr->eElement) {
283           if (pAttr->eAttribute == eAttribute) {
284             if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
285               return pAttr;
286             return nullptr;
287           }
288           iBefore--;
289           if (iBefore < 0)
290             break;
291 
292           pAttr = g_XFANotsureAttributes + iBefore;
293         }
294       }
295 
296       int32_t iAfter = iMid + 1;
297       if (iAfter <= g_iXFANotsureCount - 1) {
298         pAttr = g_XFANotsureAttributes + iAfter;
299         while (eElement == pAttr->eElement) {
300           if (pAttr->eAttribute == eAttribute) {
301             if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
302               return pAttr;
303             return nullptr;
304           }
305           iAfter++;
306           if (iAfter > g_iXFANotsureCount - 1)
307             break;
308 
309           pAttr = g_XFANotsureAttributes + iAfter;
310         }
311       }
312       return nullptr;
313     }
314 
315     if (eElement < pAttr->eElement)
316       iEnd = iMid - 1;
317     else
318       iStart = iMid + 1;
319   } while (iStart <= iEnd);
320   return nullptr;
321 }
322 
XFA_GetPropertyOfElement(XFA_Element eElement,XFA_Element eProperty,uint32_t dwPacket)323 const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_Element eElement,
324                                              XFA_Element eProperty,
325                                              uint32_t dwPacket) {
326   int32_t iCount = 0;
327   const XFA_PROPERTY* pProperties = XFA_GetElementProperties(eElement, iCount);
328   if (!pProperties || iCount < 1)
329     return nullptr;
330 
331   auto it = std::find_if(pProperties, pProperties + iCount,
332                          [eProperty](const XFA_PROPERTY& prop) {
333                            return prop.eName == eProperty;
334                          });
335   if (it == pProperties + iCount)
336     return nullptr;
337 
338   const XFA_ELEMENTINFO* pInfo = XFA_GetElementByID(eProperty);
339   ASSERT(pInfo);
340   if (dwPacket != XFA_XDPPACKET_UNKNOWN && !(dwPacket & pInfo->dwPackets))
341     return nullptr;
342   return it;
343 }
344 
XFA_GetElementProperties(XFA_Element eElement,int32_t & iCount)345 const XFA_PROPERTY* XFA_GetElementProperties(XFA_Element eElement,
346                                              int32_t& iCount) {
347   if (eElement == XFA_Element::Unknown)
348     return nullptr;
349 
350   const XFA_ELEMENTHIERARCHY* pElement =
351       g_XFAElementPropertyIndex + static_cast<int32_t>(eElement);
352   iCount = pElement->wCount;
353   return g_XFAElementPropertyData + pElement->wStart;
354 }
355 
XFA_GetElementAttributes(XFA_Element eElement,int32_t & iCount)356 const uint8_t* XFA_GetElementAttributes(XFA_Element eElement, int32_t& iCount) {
357   if (eElement == XFA_Element::Unknown)
358     return nullptr;
359 
360   const XFA_ELEMENTHIERARCHY* pElement =
361       g_XFAElementAttributeIndex + static_cast<int32_t>(eElement);
362   iCount = pElement->wCount;
363   return g_XFAElementAttributeData + pElement->wStart;
364 }
365 
XFA_GetElementByID(XFA_Element eName)366 const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_Element eName) {
367   return eName != XFA_Element::Unknown
368              ? g_XFAElementData + static_cast<int32_t>(eName)
369              : nullptr;
370 }
371 
XFA_GetElementTypeForName(const CFX_WideStringC & wsName)372 XFA_Element XFA_GetElementTypeForName(const CFX_WideStringC& wsName) {
373   if (wsName.IsEmpty())
374     return XFA_Element::Unknown;
375 
376   uint32_t uHash = FX_HashCode_GetW(wsName, false);
377   const XFA_ELEMENTINFO* pEnd = g_XFAElementData + g_iXFAElementCount;
378   auto pInfo = std::lower_bound(g_XFAElementData, pEnd, uHash,
379                                 [](const XFA_ELEMENTINFO& info, uint32_t hash) {
380                                   return info.uHash < hash;
381                                 });
382   if (pInfo < pEnd && pInfo->uHash == uHash)
383     return pInfo->eName;
384   return XFA_Element::Unknown;
385 }
386 
XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,uint32_t dwPacket)387 CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,
388                                                       XFA_ATTRIBUTE eAttribute,
389                                                       uint32_t dwPacket) {
390   void* pValue;
391   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
392                                    XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
393     return *(CXFA_Measurement*)pValue;
394   }
395   return CXFA_Measurement();
396 }
397 
XFA_GetAttributeDefaultValue(void * & pValue,XFA_Element eElement,XFA_ATTRIBUTE eAttribute,XFA_ATTRIBUTETYPE eType,uint32_t dwPacket)398 bool XFA_GetAttributeDefaultValue(void*& pValue,
399                                   XFA_Element eElement,
400                                   XFA_ATTRIBUTE eAttribute,
401                                   XFA_ATTRIBUTETYPE eType,
402                                   uint32_t dwPacket) {
403   const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
404   if (!pInfo)
405     return false;
406   if (dwPacket && (dwPacket & pInfo->dwPackets) == 0)
407     return false;
408   if (pInfo->eType == eType) {
409     pValue = pInfo->pDefValue;
410     return true;
411   }
412   if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
413     const XFA_NOTSUREATTRIBUTE* pAttr =
414         XFA_GetNotsureAttribute(eElement, eAttribute, eType);
415     if (pAttr) {
416       pValue = pAttr->pValue;
417       return true;
418     }
419   }
420   return false;
421 }
422 
XFA_GetAttributeByName(const CFX_WideStringC & wsName)423 const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName) {
424   if (wsName.IsEmpty())
425     return nullptr;
426 
427   uint32_t uHash = FX_HashCode_GetW(wsName, false);
428   int32_t iStart = 0;
429   int32_t iEnd = g_iXFAAttributeCount - 1;
430   do {
431     int32_t iMid = (iStart + iEnd) / 2;
432     const XFA_ATTRIBUTEINFO* pInfo = g_XFAAttributeData + iMid;
433     if (uHash == pInfo->uHash)
434       return pInfo;
435     if (uHash < pInfo->uHash)
436       iEnd = iMid - 1;
437     else
438       iStart = iMid + 1;
439   } while (iStart <= iEnd);
440   return nullptr;
441 }
442 
XFA_GetAttributeByID(XFA_ATTRIBUTE eName)443 const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
444   return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName)
445                                         : nullptr;
446 }
447 
XFA_GetAttributeEnumByName(const CFX_WideStringC & wsName)448 const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
449     const CFX_WideStringC& wsName) {
450   if (wsName.IsEmpty())
451     return nullptr;
452 
453   uint32_t uHash = FX_HashCode_GetW(wsName, false);
454   int32_t iStart = 0;
455   int32_t iEnd = g_iXFAEnumCount - 1;
456   do {
457     int32_t iMid = (iStart + iEnd) / 2;
458     const XFA_ATTRIBUTEENUMINFO* pInfo = g_XFAEnumData + iMid;
459     if (uHash == pInfo->uHash)
460       return pInfo;
461     if (uHash < pInfo->uHash)
462       iEnd = iMid - 1;
463     else
464       iStart = iMid + 1;
465   } while (iStart <= iEnd);
466   return nullptr;
467 }
468 
XFA_GetPacketByIndex(XFA_PACKET ePacket)469 const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket) {
470   return g_XFAPacketData + ePacket;
471 }
472 
XFA_GetPacketByID(uint32_t dwPacket)473 const XFA_PACKETINFO* XFA_GetPacketByID(uint32_t dwPacket) {
474   int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
475   do {
476     int32_t iMid = (iStart + iEnd) / 2;
477     uint32_t dwFind = (g_XFAPacketData + iMid)->eName;
478     if (dwPacket == dwFind)
479       return g_XFAPacketData + iMid;
480     if (dwPacket < dwFind)
481       iEnd = iMid - 1;
482     else
483       iStart = iMid + 1;
484   } while (iStart <= iEnd);
485   return nullptr;
486 }
487