C ++ [Microsoft] [ODBC SQL Server驱动程序]字符串数据,右截断

时间:2017-01-15 02:44:06

标签: c++ sql-server visual-c++ odbc


我需要有关ODBC准备查询的帮助。我在Windows 10(x64)上工作。我的VPS服务器是Windows Server 2012(x64)。我编译的应用程序是32位。我需要准备好的查询来使SQL注入不可能。但是有一个大问题

错误:

[QueryManager] State (22001), Diagnostic: [Microsoft][ODBC SQL Server Driver]String data, right truncation

代码:

gQueryManager.BindParameterAsString(1,Name,sizeof(Name)); 
gQueryManager.ExecQuery("SELECT Value FROM Table WHERE Name=?");
gQueryManager.Fetch();
...
gQueryManager.Close();

这是我使用的查询管理器的源代码:

// QueryManager.cpp: implementation of the CQueryManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "QueryManager.h"
#include "Util.h"

CQueryManager gQueryManager;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CQueryManager::CQueryManager() // OK
{
    this->m_SQLEnvironment = SQL_NULL_HANDLE;
    this->m_SQLConnection = SQL_NULL_HANDLE;
    this->m_STMT = SQL_NULL_HANDLE;
    this->m_RowCount = -1;
    this->m_ColCount = -1;

    memset(this->m_SQLColName,0,sizeof(this->m_SQLColName));
    memset(this->m_SQLData,0,sizeof(this->m_SQLData));

    SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&this->m_SQLEnvironment);
    SQLSetEnvAttr(this->m_SQLEnvironment,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER);
}

CQueryManager::~CQueryManager() // OK
{
    this->Disconnect();
}

bool CQueryManager::Connect(char* odbc,char* user,char* pass) // OK
{
    strcpy_s(this->m_odbc,odbc);

    strcpy_s(this->m_user,user);

    strcpy_s(this->m_pass,pass);

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC,this->m_SQLEnvironment,&this->m_SQLConnection)) == 0)
    {
        return 0;
    }

    if(SQL_SUCCEEDED(SQLConnect(this->m_SQLConnection,(SQLCHAR*)this->m_odbc,SQL_NTS,(SQLCHAR*)this->m_user,SQL_NTS,(SQLCHAR*)this->m_pass,SQL_NTS)) == 0)
    {
        return 0;
    }

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT,this->m_SQLConnection,&this->m_STMT)) == 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

void CQueryManager::Disconnect() // OK
{
    if(this->m_STMT != SQL_NULL_HANDLE)
    {
        SQLFreeHandle(SQL_HANDLE_STMT,this->m_STMT);
        this->m_STMT = SQL_NULL_HANDLE;
    }

    if(this->m_SQLConnection != SQL_NULL_HANDLE)
    {
        SQLFreeHandle(SQL_HANDLE_DBC,this->m_SQLConnection);
        this->m_SQLConnection = SQL_NULL_HANDLE;
    }

    if(this->m_SQLEnvironment != SQL_NULL_HANDLE)
    {
        SQLFreeHandle(SQL_HANDLE_ENV,this->m_SQLEnvironment);
        this->m_SQLEnvironment = SQL_NULL_HANDLE;
    }
}

void CQueryManager::Diagnostic(char* query) // OK
{
    LogAdd(LOG_BLACK,"%s",query);

    SQLINTEGER NativeError;
    SQLSMALLINT RecNumber=1,BufferLength;
    SQLCHAR SqlState[6],MessageText[SQL_MAX_MESSAGE_LENGTH];

    while(SQLGetDiagRec(SQL_HANDLE_STMT,this->m_STMT,(RecNumber++),SqlState,&NativeError,MessageText,sizeof(MessageText),&BufferLength) != SQL_NO_DATA)
    {
        LogAdd(LOG_RED,"[QueryManager] State (%s), Diagnostic: %s",SqlState,MessageText);
    }

    if(strcmp((char*)SqlState,"08S01") == 0)
    {
        this->Connect(this->m_odbc,this->m_user,this->m_pass);
    }
}

bool CQueryManager::ExecQuery(char* query,...) // OK
{
    char buff[4096];

    va_list arg;
    va_start(arg,query);
    vsprintf_s(buff,query,arg);
    va_end(arg);

    SQLRETURN result;

    if(SQL_SUCCEEDED((result=SQLExecDirect(this->m_STMT,(SQLCHAR*)buff,SQL_NTS))) == 0 && result != SQL_NO_DATA)
    {
        this->Diagnostic(buff);
        return 0;
    }

    SQLRowCount(this->m_STMT,&this->m_RowCount);

    if(this->m_RowCount == 0){return 1;}

    SQLNumResultCols(this->m_STMT,&this->m_ColCount);

    if(this->m_ColCount == 0){return 1;}

    if(this->m_ColCount > MAX_COLUMNS){return 0;}

    memset(this->m_SQLColName,0,sizeof(this->m_SQLColName));

    memset(this->m_SQLData,0,sizeof(this->m_SQLData));

    for(int n=0;n < this->m_ColCount;n++)
    {
        SQLDescribeCol(this->m_STMT,(n+1),this->m_SQLColName[n],sizeof(this->m_SQLColName[n]),0,0,0,0,0);
        SQLBindCol(this->m_STMT,(n+1),SQL_C_CHAR,this->m_SQLData[n],sizeof(this->m_SQLData[n]),&this->m_SQLDataLen[n]);
    }

    return 1;
}

void CQueryManager::Close() // OK
{
    SQLCloseCursor(this->m_STMT);
    SQLFreeStmt(this->m_STMT,SQL_UNBIND);
}

SQLRETURN CQueryManager::Fetch() // OK
{
    return SQLFetch(this->m_STMT);
}

int CQueryManager::FindIndex(char* ColName) // OK
{
    for(int n=0;n < this->m_ColCount;n++)
    {
        if(_stricmp(ColName,(char*)this->m_SQLColName[n]) == 0)
        {
            return n;
        }
    }

    return -1;
}

int CQueryManager::GetResult(int index) // OK
{
    return atoi(this->m_SQLData[index]);
}

int CQueryManager::GetAsInteger(char* ColName) // OK
{
    int index = this->FindIndex(ColName);

    if(index == -1)
    {
        return index;
    }
    else
    {
        return atoi(this->m_SQLData[index]);
    }
}

float CQueryManager::GetAsFloat(char* ColName) // OK
{
    int index = this->FindIndex(ColName);

    if(index == -1)
    {
        return (float)index;
    }
    else
    {
        return (float)atof(this->m_SQLData[index]);
    }
}

__int64 CQueryManager::GetAsInteger64(char* ColName) // OK
{
    int index = this->FindIndex(ColName);

    if(index == -1)
    {
        return index;
    }
    else
    {
        return _atoi64(this->m_SQLData[index]);
    }
}

void CQueryManager::GetAsString(char* ColName,char* OutBuffer,int OutBufferSize) // OK
{
    int index = this->FindIndex(ColName);

    if(index == -1)
    {
        memset(OutBuffer,0,OutBufferSize);
    }
    else
    {
        strncpy_s(OutBuffer,OutBufferSize,this->m_SQLData[index],(OutBufferSize-1));
    }
}

void CQueryManager::GetAsBinary(char* ColName,BYTE* OutBuffer,int OutBufferSize) // OK
{
    int index = this->FindIndex(ColName);

    if(index == -1)
    {
        memset(OutBuffer,0,OutBufferSize);
    }
    else
    {
        this->ConvertStringToBinary(this->m_SQLData[index],sizeof(this->m_SQLData[index]),OutBuffer,OutBufferSize);
    }
}

void CQueryManager::BindParameterAsString(int ParamNumber,void* InBuffer,int ColumnSize) // OK
{
    this->m_SQLBindValue[(ParamNumber-1)] = SQL_NTS;

    SQLBindParameter(this->m_STMT,ParamNumber,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR,ColumnSize,0,InBuffer,0,&this->m_SQLBindValue[(ParamNumber-1)]);
}

void CQueryManager::BindParameterAsBinary(int ParamNumber,void* InBuffer,int ColumnSize) // OK
{
    this->m_SQLBindValue[(ParamNumber-1)] = ColumnSize;

    SQLBindParameter(this->m_STMT,ParamNumber,SQL_PARAM_INPUT,SQL_C_BINARY,SQL_VARBINARY,ColumnSize,0,InBuffer,0,&this->m_SQLBindValue[(ParamNumber-1)]);
}

void CQueryManager::ConvertStringToBinary(char* InBuff,int InSize,BYTE* OutBuff,int OutSize) // OK
{
    int size = 0;

    memset(OutBuff,0,OutSize);

    for(int n=0;n < InSize,size < OutSize;n++)
    {
        if(InBuff[n] == 0)
        {
            break;
        }

        if((n%2) == 0)
        {
            OutBuff[size] = ((InBuff[n]>='A')?((InBuff[n]-'A')+10):(InBuff[n]-'0'))*16;
            size = size+0;
        }
        else
        {
            OutBuff[size] = OutBuff[size] | ((InBuff[n]>='A')?((InBuff[n]-'A')+10):(InBuff[n]-'0'));
            size = size+1;
        }
    }
}

void CQueryManager::ConvertBinaryToString(BYTE* InBuff,int InSize,char* OutBuff,int OutSize) // OK
{
    int size = 0;

    memset(OutBuff,0,OutSize);

    for(int n=0;n < OutSize,size < InSize;n++)
    {
        if((n%2) == 0)
        {
            OutBuff[n] = (((InBuff[size]/16)>=10)?('A'+((InBuff[size]/16)-10)):('0'+(InBuff[size]/16)));
            size = size+0;
        }
        else
        {
            OutBuff[n] = (((InBuff[size]%16)>=10)?('A'+((InBuff[size]%16)-10)):('0'+(InBuff[size]%16)));
            size = size+1;
        }
    }
}

0 个答案:

没有答案