MS SQL Server 2000 ODBC driver crash

From: Jason Hinsperger (NOjason_hinspergerSPAM_at_hotmail.com)
Date: 03/03/04

  • Next message: JeffO: "Re: Can't connect error"
    Date: Wed, 3 Mar 2004 09:36:08 -0800
    
    

    If the SQL Server driver's option "Use ANSI nulls, paddings and warnings"
    is not set and the length of char is over 623, MS SQL Server driver will
    crash in calling SQLFreeHandle.

    Repro:

    Version of SQL Server Driver: 2000.81.9042.00
    Database: SQL Server 2000

    1. Create the table ssint2:

    create table ssint2(
    id int not null primary key,
    source char( 1000 ) )

    2. Create a dsn using SQL server driver, don't set the option "Use ANSI
    nulls, paddings and warnings". Run the repro as:

    charcrash "DSN=SQL_Server_Data_source;UID=userid;PWD=password"

    You will see the repro crashing in calling SQLFreeHandle of the
    statement "select id, source from ssint2".

    Notes: This crash is related to the size of char column. If the size is
    less than 623, it won't crash.

    Here is a sample program which demonstrates the problem:
    #include <stdio.h>
    #include <stdlib.h>
    #include <d:\odbcbug\odbc.h>
    #include <string.h>

    #if ODBCVER < 0x0350
        #error "***** This module requires ODBC 3.5 or higher *****"
    #endif

    typedef struct ml_host_data {
            SQLHENV env;
    } ml_host_data, *p_ml_host_data;

    typedef struct ml_host_conn {
        p_ml_host_data host;
        SQLHDBC dbc;
    } ml_host_conn, *p_ml_host_conn;

    p_ml_host_data Init( void )
    /*************************/
    {
        p_ml_host_data host;
        RETCODE ret;

        host = (p_ml_host_data) malloc( sizeof( *host ) );
        if( host != NULL ) {
            ret = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &host->env );
        
            ret = SQLSetEnvAttr( host->env,
                           SQL_ATTR_ODBC_VERSION,
                           (SQLPOINTER)SQL_OV_ODBC3,
                           0 );
        }

        return( host );
    }

    void Fini( p_ml_host_data host )
    /******************************/
    {
        RETCODE ret;

        // Clean up any resources and shut the module down.
        if( host->env != SQL_NULL_HENV ) {
            ret = SQLFreeHandle( SQL_HANDLE_ENV, host->env );
        }
    }

    p_ml_host_conn Connect(
    /**********************/
        p_ml_host_data host,
        char * conn_str )
    {
        // Establish a connection with the host database. This may
        // create a new connection or just grab one from a pool
        // of connections.
        p_ml_host_conn conn;
        SQLSMALLINT conn_str_len;
        char out_str[ 2048 ];
        RETCODE ret = SQL_ERROR;

        conn = (p_ml_host_conn) malloc( sizeof( ml_host_conn ) );
        if( conn == NULL ) {
            goto done;
        }

        conn->host = host;
        conn->dbc = SQL_NULL_HDBC;

        ret = SQLAllocHandle( SQL_HANDLE_DBC, host->env, &conn->dbc );

        ret = SQLDriverConnect( conn->dbc,
                                NULL, // HWND_NULL,
                                (SQLCHAR *)conn_str,
                                SQL_NTS,
                                (SQLCHAR *)out_str,
                                sizeof( out_str ),
                                &conn_str_len,
                                SQL_DRIVER_NOPROMPT );
        if( ret == 0 ) printf( "Connection succeed\n" );

        // Establish connection options

        // Use transactions instead of auto-commit
        ret = SQLSetConnectAttr( conn->dbc,
                                 SQL_ATTR_AUTOCOMMIT,
                                 (SQLPOINTER)SQL_AUTOCOMMIT_OFF,
                                 SQL_IS_UINTEGER );
        if( ret == 0 ) printf( "Set Connection succeed\n" );

    done:
        return( conn );
    }

    void Disconnect( p_ml_host_conn conn )
    /************************************/
    {
        if( conn != NULL ) {
            if( conn->dbc != SQL_NULL_HDBC ) {
                SQLDisconnect( conn->dbc );
                SQLFreeHandle( SQL_HANDLE_DBC, conn->dbc );
            }
        
            free( conn );
        }
    }

    void ShowBug( p_ml_host_conn conn )
    /*********************************/
    {

        SQLHSTMT stmt;
        RETCODE ret;
        int id;
        SQLINTEGER ind1=0, ind2=0;
        SQLWCHAR source[1001];
     

        ret = SQLAllocHandle( SQL_HANDLE_STMT, conn->dbc, &stmt );
        ret = SQLPrepare( stmt,
                          (SQLCHAR *)"select id, source from ssint2", SQL_NTS );
        ret = SQLExecute( stmt );

        ret = SQLBindCol( stmt, 1, SQL_C_SLONG, &id, 4, ind1 );
        ret = SQLBindCol( stmt, 2, SQL_C_WCHAR, source, sizeof( source), ind2);

        
        ret = SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 );

        while( ret == SQL_NO_DATA_FOUND ) {
           ret = SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 );
        }

        ret = SQLFreeHandle( SQL_HANDLE_STMT, stmt );

        ret = SQLEndTran( SQL_HANDLE_DBC, conn->dbc, SQL_ROLLBACK );
    }

    int main( int argc, char *argv[] )
    /********************************/
    {
        p_ml_host_data host = NULL;
        p_ml_host_conn conn = NULL;

        host = Init();
        if( host != NULL ) {
            argc = argc; // Unused
            conn = Connect( host, argv[ 1 ] );
            if( conn != NULL ) {
                // ===========================
                ShowBug( conn );
                // ===========================
                Disconnect( conn );
            }
            Fini( host );
        }

        return( 0 );
    }

     
      
     


  • Next message: JeffO: "Re: Can't connect error"

    Relevant Pages

    • MSSQL Server ODBC driver crash
      ... If the SQL Server driver's option "Use ANSI nulls, paddings and warnings" ... is not set and the length of char is over 623, MS SQL Server driver will ...
      (microsoft.public.data.odbc)
    • Re: Run As Command
      ... Declare @VCHCOMMAND Char, ... if you are using BACKUP DATABASE command to backup the database then ... to use a seperate logon for the destination server. ... to SQL server bacause SQL Server cannot see that domain. ...
      (microsoft.public.sqlserver.security)
    • Re: Maintaining Field Length in .txt format
      ... If the types are VARCHAR, ... converts them to CHAR types. ... >are on a SQL Server 2000 environment and I can create ... The header information for the feed to be ...
      (microsoft.public.sqlserver.programming)
    • Re: returning @@RowCount
      ... use VARCHAR. ... CHAR will pad the data with spaces ... SQL Server MVP ... >> alter procedure stp_Family ...
      (microsoft.public.sqlserver.programming)
    • Re: CLOB Problem with DBD::ODBC/DBD::ADO for SQL Server
      ... I am unsure why the code does not insert CR\LF as I am 100% sure the file itself contains CR\LF. ... At 24000 chrs it works and at 48000 chrs you lose each \ followed by a. ... It is of no consolation to you but I have duplicated it with the MS SQL Server driver and also demonstrated it works fine with our sql server driver. ...
      (perl.dbi.users)