string conversion in libnxsnmp uses MultiByteToWideChar; minor refactoring
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Mar 2014 15:19:13 +0000 (17:19 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Mar 2014 15:19:13 +0000 (17:19 +0200)
15 files changed:
include/nxsnmp.h
src/libnetxms/unicode.cpp
src/server/core/cdp.cpp
src/server/core/components.cpp
src/server/core/download_job.cpp
src/server/core/lldp.cpp
src/server/core/nxsl_classes.cpp
src/server/core/snmptrap.cpp
src/server/drivers/at/at.cpp
src/server/drivers/lib/cisco/cisco.cpp
src/server/drivers/ntws/ntws.cpp
src/server/libnxsrv/ndd.cpp
src/server/libnxsrv/snmp.cpp
src/snmp/libnxsnmp/variable.cpp
src/snmp/nxsnmpwalk/nxsnmpwalk.cpp

index fb0b2dc..7186259 100644 (file)
@@ -408,7 +408,7 @@ public:
        size_t getRawValue(BYTE *buffer, size_t bufSize);
    UINT32 GetValueAsUInt();
    LONG GetValueAsInt();
-   TCHAR *GetValueAsString(TCHAR *pszBuffer, UINT32 dwBufferSize);
+   TCHAR *getValueAsString(TCHAR *pszBuffer, UINT32 dwBufferSize);
    TCHAR *getValueAsPrintableString(TCHAR *buffer, UINT32 bufferSize, bool *convertToHex);
    SNMP_ObjectId *GetValueAsObjectId();
    TCHAR *GetValueAsMACAddr(TCHAR *pszBuffer);
index 73b5326..48186eb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  ** NetXMS - Network Management System
- ** Copyright (C) 2003-2013 NetXMS Team
+ ** Copyright (C) 2003-2014 NetXMS Team
  **
  ** This program is free software; you can redistribute it and/or modify
  ** it under the terms of the GNU Lesser General Public License as published
@@ -185,7 +185,7 @@ inline int WideCharToMultiByteSimpleCopy(int iCodePage, DWORD dwFlags, const WCH
    if (iSize >= cchByteChar)
       iSize = cchByteChar - 1;
    for(pSrc = pWideCharStr, iPos = 0, pDest = pByteStr; iPos < iSize; iPos++, pSrc++, pDest++)
-      *pDest = (*pSrc < 256) ? (char) (*pSrc) : '?';
+      *pDest = (*pSrc < 256) ? (char)(*pSrc) : '?';
    *pDest = 0;
 
    return iSize;
@@ -212,17 +212,16 @@ inline int WideCharToMultiByteIconv(int iCodePage, DWORD dwFlags, const WCHAR *p
 #endif /* HAVE_ICONV_IGNORE */
 
    cd = iconv_open(iCodePage == CP_UTF8 ? "UTF-8" : cp, UNICODE_CODEPAGE_NAME);
-   if (cd == (iconv_t) (-1))
+   if (cd == (iconv_t)(-1))
    {
-      return WideCharToMultiByteSimpleCopy(iCodePage, dwFlags, pWideCharStr, cchWideChar, pByteStr, cchByteChar, pDefaultChar,
-         pbUsedDefChar);
+      return WideCharToMultiByteSimpleCopy(iCodePage, dwFlags, pWideCharStr, cchWideChar, pByteStr, cchByteChar, pDefaultChar, pbUsedDefChar);
    }
 
-   inbuf = (const char *) pWideCharStr;
+   inbuf = (const char *)pWideCharStr;
    inbytes = ((cchWideChar == -1) ? wcslen(pWideCharStr) + 1 : cchWideChar) * sizeof(WCHAR);
    outbuf = pByteStr;
    outbytes = cchByteChar;
-   nRet = iconv(cd, (ICONV_CONST char **) &inbuf, &inbytes, &outbuf, &outbytes);
+   nRet = iconv(cd, (ICONV_CONST char **)&inbuf, &inbytes, &outbuf, &outbytes);
    iconv_close(cd);
    if (nRet == -1)
    {
@@ -308,7 +307,7 @@ inline int MultiByteToWideCharIconv(int iCodePage, DWORD dwFlags, const char *pB
    size_t inbytes, outbytes;
 
    cd = iconv_open(UNICODE_CODEPAGE_NAME, iCodePage == CP_UTF8 ? "UTF-8" : m_cpDefault);
-   if (cd == (iconv_t) (-1))
+   if (cd == (iconv_t)(-1))
    {
       return MultiByteToWideCharSimpleCopy(iCodePage, dwFlags, pByteStr, cchByteChar, pWideCharStr, cchWideChar);
    }
@@ -377,9 +376,7 @@ int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, DWORD dwFlags, const
 UINT32 LIBNETXMS_EXPORTABLE inet_addr_w(const WCHAR *pszAddr)
 {
    char szBuffer[256];
-
-   WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
-      pszAddr, -1, szBuffer, 256, NULL, NULL);
+   WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, pszAddr, -1, szBuffer, 256, NULL, NULL);
    return inet_addr(szBuffer);
 }
 
index be44a20..b7b96d1 100644 (file)
@@ -61,7 +61,7 @@ static UINT32 CDPTopoHandler(UINT32 snmpVersion, SNMP_Variable *var, SNMP_Transp
                if (pRespPDU->getNumVariables() >= 1)
                {
                        TCHAR ifName[MAX_CONNECTOR_NAME] = _T("");
-                       pRespPDU->getVariable(0)->GetValueAsString(ifName, 64);
+                       pRespPDU->getVariable(0)->getValueAsString(ifName, 64);
                        DbgPrintf(6, _T("CDP(%s [%d]): remote port is \"%s\""), node->Name(), node->Id(), ifName);
                        Interface *ifRemote = remoteNode->findInterface(ifName);
                        if (ifRemote != NULL)
index eb3e661..8155ae6 100644 (file)
@@ -180,7 +180,7 @@ UINT32 Component::fillMessage(CSCPMessage *msg, UINT32 baseId)
 static UINT32 EntityWalker(UINT32 snmpVersion, SNMP_Variable *var, SNMP_Transport *transport, void *arg)
 {
        TCHAR buffer[256];
-       Component *element = new Component(var->GetName()->getValue()[12], var->GetValueAsString(buffer, 256));
+       Component *element = new Component(var->GetName()->getValue()[12], var->getValueAsString(buffer, 256));
        UINT32 rc = element->updateFromSnmp(transport);
        if (rc != SNMP_ERR_SUCCESS)
        {
index 909ab87..8b36617 100644 (file)
@@ -140,7 +140,7 @@ bool FileDownloadJob::run()
             //default - get parameters
             if (m_maxFileSize > 0)
             {
-               msg.SetVariable(VID_FILE_OFFSET, -m_maxFileSize);
+               msg.SetVariable(VID_FILE_OFFSET, (UINT32)(-((int)m_maxFileSize)));
             }
             else
             {
index c5b2047..e94ae74 100644 (file)
@@ -44,7 +44,7 @@ static UINT32 PortLocalInfoHandler(UINT32 snmpVersion, SNMP_Variable *var, SNMP_
        delete pRqPDU;
        if (rcc == SNMP_ERR_SUCCESS)
    {
-               pRespPDU->getVariable(0)->GetValueAsString(port->ifDescr, 192);
+               pRespPDU->getVariable(0)->getValueAsString(port->ifDescr, 192);
                delete pRespPDU;
        }
        else
index 541497b..13c64ec 100644 (file)
@@ -600,13 +600,13 @@ NXSL_Value *NXSL_SNMPVarBindClass::getAttr(NXSL_Object *object, const TCHAR *att
        }
        else if (!_tcscmp(attr, _T("value")))
        {
-               value = new NXSL_Value(t->GetValueAsString(strValue, 1024));
+               value = new NXSL_Value(t->getValueAsString(strValue, 1024));
        }
        else if (!_tcscmp(attr, _T("printableValue")))
        {
                bool convToHex = true;
                t->getValueAsPrintableString(strValue, 1024, &convToHex);
-               value = new NXSL_Value(t->GetValueAsString(strValue, 1024));
+               value = new NXSL_Value(strValue);
        }
        else if (!_tcscmp(attr, _T("valueAsIp")))
        {
index b614005..f2a5aba 100644 (file)
@@ -178,7 +178,7 @@ static void GenerateTrapEvent(UINT32 dwObjectId, UINT32 dwIndex, SNMP_PDU *pdu)
          if (pVar != NULL)
          {
                                bool convertToHex = true;
-                               pszArgList[i] = _tcsdup((s_allowVarbindConversion && !(m_pTrapCfg[dwIndex].pMaps[i].dwFlags & TRAP_VARBIND_FORCE_TEXT)) ? pVar->getValueAsPrintableString(szBuffer, 256, &convertToHex) : pVar->GetValueAsString(szBuffer, 256));
+                               pszArgList[i] = _tcsdup((s_allowVarbindConversion && !(m_pTrapCfg[dwIndex].pMaps[i].dwFlags & TRAP_VARBIND_FORCE_TEXT)) ? pVar->getValueAsPrintableString(szBuffer, 256, &convertToHex) : pVar->getValueAsString(szBuffer, 256));
          }
          else
          {
@@ -196,7 +196,7 @@ static void GenerateTrapEvent(UINT32 dwObjectId, UINT32 dwIndex, SNMP_PDU *pdu)
             if ((iResult == OID_EQUAL) || (iResult == OID_SHORTER))
             {
                                        bool convertToHex = true;
-                                       pszArgList[i] = _tcsdup((s_allowVarbindConversion && !(m_pTrapCfg[dwIndex].pMaps[i].dwFlags & TRAP_VARBIND_FORCE_TEXT)) ? pdu->getVariable(j)->getValueAsPrintableString(szBuffer, 256, &convertToHex) : pdu->getVariable(j)->GetValueAsString(szBuffer, 256));
+                                       pszArgList[i] = _tcsdup((s_allowVarbindConversion && !(m_pTrapCfg[dwIndex].pMaps[i].dwFlags & TRAP_VARBIND_FORCE_TEXT)) ? pdu->getVariable(j)->getValueAsPrintableString(szBuffer, 256, &convertToHex) : pdu->getVariable(j)->getValueAsString(szBuffer, 256));
                break;
             }
          }
@@ -278,7 +278,7 @@ static void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transpo
          dwBufPos += _sntprintf(&pszTrapArgs[dwBufPos], dwBufSize - dwBufPos, _T("%s%s == '%s'"),
                                 (dwBufPos == 0) ? _T("") : _T("; "),
                                 pVar->GetName()->getValueAsText(), 
-                                                                                 s_allowVarbindConversion ? pVar->getValueAsPrintableString(szBuffer, 3000, &convertToHex) : pVar->GetValueAsString(szBuffer, 3000));
+                                                                                 s_allowVarbindConversion ? pVar->getValueAsPrintableString(szBuffer, 3000, &convertToHex) : pVar->getValueAsString(szBuffer, 3000));
       }
 
       // Write new trap to database
@@ -370,7 +370,7 @@ static void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transpo
                dwBufPos += _sntprintf(&pszTrapArgs[dwBufPos], dwBufSize - dwBufPos, _T("%s%s == '%s'"),
                                       (dwBufPos == 0) ? _T("") : _T("; "),
                                       pVar->GetName()->getValueAsText(), 
-                                                                                                 s_allowVarbindConversion ? pVar->getValueAsPrintableString(szBuffer, 512, &convertToHex) : pVar->GetValueAsString(szBuffer, 512));
+                                                                                                 s_allowVarbindConversion ? pVar->getValueAsPrintableString(szBuffer, 512, &convertToHex) : pVar->getValueAsString(szBuffer, 512));
             }
 
             // Generate default event for unmatched traps
index 511b338..f894b33 100644 (file)
@@ -167,7 +167,7 @@ static UINT32 HandlerVlanList(UINT32 version, SNMP_Variable *var, SNMP_Transport
        VlanInfo *vlan = new VlanInfo(var->GetName()->getValue()[var->GetName()->getLength() - 1], VLAN_PRM_SLOTPORT);
 
        TCHAR buffer[256];
-       vlan->setName(var->GetValueAsString(buffer, 256));
+       vlan->setName(var->getValueAsString(buffer, 256));
        vlanList->add(vlan);
 
    return SNMP_ERR_SUCCESS;
@@ -248,8 +248,8 @@ VlanList *AlliedTelesisDriver::getVlans(SNMP_Transport *snmp, StringMap *attribu
              (response->getVariable(1)->GetType() != ASN_NO_SUCH_INSTANCE))
          {
             TCHAR buffer[1024];
-            ParsePortList(response->getVariable(0)->GetValueAsString(buffer, 1024), vlan, 1);
-            ParsePortList(response->getVariable(1)->GetValueAsString(buffer, 1024), vlan, 1);
+            ParsePortList(response->getVariable(0)->getValueAsString(buffer, 1024), vlan, 1);
+            ParsePortList(response->getVariable(1)->getValueAsString(buffer, 1024), vlan, 1);
          }
          delete response;
       }
index a3c7fb8..7718e7f 100644 (file)
@@ -34,7 +34,7 @@ static UINT32 HandlerVlanList(UINT32 version, SNMP_Variable *var, SNMP_Transport
        VlanInfo *vlan = new VlanInfo(var->GetName()->getValue()[var->GetName()->getLength() - 1], VLAN_PRM_IFINDEX);
 
        TCHAR buffer[256];
-       vlan->setName(var->GetValueAsString(buffer, 256));
+       vlan->setName(var->getValueAsString(buffer, 256));
 
        vlanList->add(vlan);
    return SNMP_ERR_SUCCESS;
index d4f7a3d..3a09727 100644 (file)
@@ -109,7 +109,7 @@ static UINT32 HandlerAccessPointListUnadopted(UINT32 version, SNMP_Variable *var
    ObjectArray<AccessPointInfo> *apList = (ObjectArray<AccessPointInfo> *)arg;
 
    TCHAR model[128];
-   AccessPointInfo *info = new AccessPointInfo((BYTE *)"\x00\x00\x00\x00\x00\x00", AP_UNADOPTED, NULL, var->GetValueAsString(model, 128), NULL);
+   AccessPointInfo *info = new AccessPointInfo((BYTE *)"\x00\x00\x00\x00\x00\x00", AP_UNADOPTED, NULL, var->getValueAsString(model, 128), NULL);
    apList->add(info);
 
    return SNMP_ERR_SUCCESS;
@@ -152,7 +152,7 @@ static UINT32 HandlerAccessPointListAdopted(UINT32 version, SNMP_Variable *var,
       {
          TCHAR model[256], name[256];
          AccessPointInfo *ap = new AccessPointInfo((BYTE *)var->GetValue(), AP_ADOPTED, 
-            response->getVariable(1)->GetValueAsString(name, 256), response->getVariable(0)->GetValueAsString(model, 256), serial);
+            response->getVariable(1)->getValueAsString(name, 256), response->getVariable(0)->getValueAsString(model, 256), serial);
          apList->add(ap);
       }
       delete response;
index 75e14e9..e4fa5ac 100644 (file)
@@ -400,7 +400,7 @@ static UINT32 HandlerVlanList(UINT32 version, SNMP_Variable *var, SNMP_Transport
        VlanInfo *vlan = new VlanInfo(var->GetName()->getValue()[var->GetName()->getLength() - 1], VLAN_PRM_BPORT);
 
        TCHAR buffer[256];
-       vlan->setName(var->GetValueAsString(buffer, 256));
+       vlan->setName(var->getValueAsString(buffer, 256));
 
        vlanList->add(vlan);
    return SNMP_ERR_SUCCESS;
index a8529c6..87f93aa 100644 (file)
@@ -114,7 +114,7 @@ UINT32 LIBNXSRV_EXPORTABLE SnmpGetEx(SNMP_Transport *pTransport,
                }
                else if (dwFlags & SG_STRING_RESULT)
                {
-                  pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
+                  pVar->getValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
                }
                else if (dwFlags & SG_PSTRING_RESULT)
                {
@@ -136,10 +136,10 @@ UINT32 LIBNXSRV_EXPORTABLE SnmpGetEx(SNMP_Transport *pTransport,
                         *((UINT32 *)pValue) = ntohl(pVar->GetValueAsUInt());
                         break;
                      case ASN_OCTET_STRING:
-                        pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
+                        pVar->getValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
                         break;
                      case ASN_OBJECT_ID:
-                        pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
+                        pVar->getValueAsString((TCHAR *)pValue, dwBufferSize / sizeof(TCHAR));
                         break;
                      default:
                         nxlog_write(MSG_SNMP_UNKNOWN_TYPE, EVENTLOG_ERROR_TYPE, "x", pVar->GetType());
index a08488a..9c45d0e 100644 (file)
@@ -224,7 +224,7 @@ LONG SNMP_Variable::GetValueAsInt()
  * Get value as string
  * Note: buffer size is in characters
  */
-TCHAR *SNMP_Variable::GetValueAsString(TCHAR *pszBuffer, UINT32 dwBufferSize)
+TCHAR *SNMP_Variable::getValueAsString(TCHAR *pszBuffer, UINT32 dwBufferSize)
 {
    UINT32 dwLen;
 
@@ -257,14 +257,19 @@ TCHAR *SNMP_Variable::GetValueAsString(TCHAR *pszBuffer, UINT32 dwBufferSize)
          break;
       case ASN_OCTET_STRING:
          dwLen = min(dwBufferSize - 1, m_dwValueLength);
+         if (dwLen > 0)
+         {
 #ifdef UNICODE
-                       // received octet string can contain char sequences invalid for
-                       // current code page, so we don't use normal conversion functions here
-                       for(UINT32 i = 0; i < dwLen; i++)
-                               pszBuffer[i] = ((char *)m_pValue)[i];
+            if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)m_pValue, dwLen, pszBuffer, dwBufferSize) == 0)
+            {
+               // fallback if conversion fails
+                        for(UINT32 i = 0; i < dwLen; i++)
+                                pszBuffer[i] = ((char *)m_pValue)[i];
+            }
 #else
-         memcpy(pszBuffer, m_pValue, dwLen);
+            memcpy(pszBuffer, m_pValue, dwLen);
 #endif
+         }
          pszBuffer[dwLen] = 0;
          break;
       default:
@@ -289,54 +294,61 @@ TCHAR *SNMP_Variable::getValueAsPrintableString(TCHAR *buffer, UINT32 bufferSize
 
    if (m_dwType == ASN_OCTET_STRING)
        {
-         dwLen = min(bufferSize - 1, m_dwValueLength);
+      dwLen = min(bufferSize - 1, m_dwValueLength);
+      if (dwLen > 0)
+      {
 #ifdef UNICODE
-                       // received octet string can contain char sequences invalid for
-                       // current code page, so we don't use normal conversion functions here
-                       for(UINT32 i = 0; i < dwLen; i++)
-                               buffer[i] = ((char *)m_pValue)[i];
+         if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)m_pValue, dwLen, buffer, bufferSize) == 0)
+         {
+            // fallback if conversion fails
+                     for(UINT32 i = 0; i < dwLen; i++)
+                             buffer[i] = ((char *)m_pValue)[i];
+         }
 #else
          memcpy(buffer, m_pValue, dwLen);
 #endif
-         buffer[dwLen] = 0;
+      }
+      buffer[dwLen] = 0;
 
-                       if (convertToHexAllowed)
-                       {
-                               bool conversionNeeded = false;
-                               for(UINT32 i = 0; i < dwLen; i++)
-                                       if (!_istprint(buffer[i]) && (buffer[i] != 0x0D) && (buffer[i] != 0x0A))
-                                       {
-                                               conversionNeeded = true;
-                                               break;
-                                       }
-
-                               if (conversionNeeded)
+               if (convertToHexAllowed)
+               {
+                       bool conversionNeeded = false;
+                       for(UINT32 i = 0; i < dwLen; i++)
+                               if ((m_pValue[i] < 0x1F) && (m_pValue[i] != 0x0D) && (m_pValue[i] != 0x0A))
                                {
-                                       TCHAR *hexString = (TCHAR *)malloc((dwLen * 3 + 1) * sizeof(TCHAR));
-                                       UINT32 i, j;
-                                       for(i = 0, j = 0; i < dwLen; i++)
-                                       {
-                                               hexString[j++] = bin2hex((BYTE)buffer[i] >> 4);
-                                               hexString[j++] = bin2hex((BYTE)buffer[i] & 15);
-                                               hexString[j++] = _T(' ');
-                                       }
-                                       hexString[j] = 0;
-                                       nx_strncpy(buffer, hexString, bufferSize);
-                                       free(hexString);
-                                       *convertToHex = true;
+               if ((i == dwLen - 1) && (m_pValue[i] == 0))
+                  break;   // 0 at the end is OK
+                                       conversionNeeded = true;
+                                       break;
                                }
-                       }
-                       else
+
+                       if (conversionNeeded)
                        {
-                               // Replace non-printable characters with question marks
-                               for(UINT32 i = 0; i < dwLen; i++)
-                                       if (!_istprint(buffer[i]))
-                                               buffer[i] = _T('?');
+                               TCHAR *hexString = (TCHAR *)malloc((dwLen * 3 + 1) * sizeof(TCHAR));
+                               UINT32 i, j;
+                               for(i = 0, j = 0; i < dwLen; i++)
+                               {
+                                       hexString[j++] = bin2hex(m_pValue[i] >> 4);
+                                       hexString[j++] = bin2hex(m_pValue[i] & 15);
+                                       hexString[j++] = _T(' ');
+                               }
+                               hexString[j] = 0;
+                               nx_strncpy(buffer, hexString, bufferSize);
+                               free(hexString);
+                               *convertToHex = true;
                        }
+               }
+               else
+               {
+                       // Replace non-printable characters with question marks
+                       for(UINT32 i = 0; i < dwLen; i++)
+                               if ((buffer[i] < 0x1F) && (buffer[i] != 0x0D) && (buffer[i] != 0x0A))
+                                       buffer[i] = _T('?');
+               }
        }
        else
        {
-               return GetValueAsString(buffer, bufferSize);
+               return getValueAsString(buffer, bufferSize);
        }
 
        return buffer;
index 132eee2..ffd4779 100644 (file)
@@ -49,7 +49,7 @@ int GetData(TCHAR *pszHost, TCHAR *pszRootOid)
    UINT32 dwResult, dwRootLen, dwNameLen;
    UINT32 pdwRootName[MAX_OID_LEN], pdwName[MAX_OID_LEN];
    TCHAR szBuffer[1024], typeName[256];
-   int i, iExit = 0;
+   int iExit = 0;
    BOOL bRunning = TRUE;
 
    // Initialize WinSock
@@ -125,11 +125,6 @@ int GetData(TCHAR *pszHost, TCHAR *pszRootOid)
                      dwNameLen = pVar->GetName()->getLength();
 
                      // Print OID and value
-                     pVar->GetValueAsString(szBuffer, 1024);
-                     for(i = 0; szBuffer[i] != 0; i++)
-                        if (szBuffer[i] < ' ')
-                           szBuffer[i] = '.';
-
                                                        bool convert = true;
                                                        pVar->getValueAsPrintableString(szBuffer, 1024, &convert);
                                                        _tprintf(_T("%s [%s]: %s\n"), pVar->GetName()->getValueAsText(),