Home | History | Annotate | Download | only in parser
      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 
     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 
    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 }
    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 
    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 
    224 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) {
    225   CFX_WideString wsValue = CFX_WideString::FromUTF8(szStringVal);
    226   return WideStringToDouble(wsValue);
    227 }
    228 
    229 int32_t XFA_MapRotation(int32_t nRotation) {
    230   nRotation = nRotation % 360;
    231   nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
    232   return nRotation;
    233 }
    234 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    443 const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
    444   return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName)
    445                                         : nullptr;
    446 }
    447 
    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 
    469 const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket) {
    470   return g_XFAPacketData + ePacket;
    471 }
    472 
    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