Esempio n. 1
0
// pdo error handler for the dbh context.
bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, 
                                  va_list* print_args )
{
    pdo_dbh_t* dbh = reinterpret_cast<pdo_dbh_t*>( ctx.driver());
    SQLSRV_ASSERT( dbh != NULL, "pdo_sqlsrv_handle_dbh_error: Null dbh passed" );

    sqlsrv_error_auto_ptr error;

    if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
        
        core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args );
    }
    else {
        bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
        SQLSRV_ASSERT( err == true, "No ODBC error was found" );
    }

    SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( dbh->error_code ));
    strcpy_s( dbh->error_code, sizeof( dbh->error_code ), reinterpret_cast<const char*>( error->sqlstate ));

    switch( dbh->error_mode ) {
        case PDO_ERRMODE_EXCEPTION:
            if( !warning ) {

                pdo_sqlsrv_throw_exception( error TSRMLS_CC );
            }
            ctx.set_last_error( error );
            break;
        case PDO_ERRMODE_WARNING:
            if( !warning ) {
                unsigned int msg_len = strlen( reinterpret_cast<const char*>( error->native_message )) + SQL_SQLSTATE_BUFSIZE 
                    + MAX_DIGITS + 1;
                sqlsrv_malloc_auto_ptr<char> msg;
                msg = static_cast<char*>( sqlsrv_malloc( msg_len ));
                core_sqlsrv_format_message( msg, msg_len, WARNING_TEMPLATE, error->sqlstate, error->native_code, 
                                            error->native_message );
                php_error( E_WARNING, msg );
                sqlsrv_free( msg );
            }
            ctx.set_last_error( error );
            break;
        case PDO_ERRMODE_SILENT:
            ctx.set_last_error( error );
            break;
        default:
            DIE( "Unknown error mode. %1!d!", dbh->error_mode );
            break;
    }

    // return error ignored = true for warnings.
    return ( warning ? true : false );
}
Esempio n. 2
0
bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const wchar_t* inString, SQLINTEGER cchInLen, char** outString, SQLINTEGER& cchOutLen )
{
    SQLSRV_ASSERT( inString != NULL, "Input string must be specified" );
    SQLSRV_ASSERT( outString != NULL, "Output buffer pointer must be specified" );
    SQLSRV_ASSERT( *outString == NULL, "Output buffer pointer must not be set" );

    if (cchInLen == 0 && inString[0] == L'\0') {
        *outString = reinterpret_cast<char*>( sqlsrv_malloc ( 1 ) );
        *outString[0] = '\0';
        cchOutLen = 0;
        return true;
    }

    // flags set to 0 by default, which means that any invalid characters are dropped rather than causing
    // an error.   This happens only on XP.
    DWORD flags = 0;
    if( encoding == CP_UTF8 && g_osversion.dwMajorVersion >= SQLSRV_OS_VISTA_OR_LATER ) {
        // Vista (and later) will detect invalid UTF-16 characters and raise an error.
        flags = WC_ERR_INVALID_CHARS;
    }

    // calculate the number of characters needed
    cchOutLen = WideCharToMultiByte( encoding, flags,
                                   inString, cchInLen, 
                                   NULL, 0, NULL, NULL );
    if( cchOutLen == 0 ) {
        return false;
    }

    // Create a buffer to fit the encoded string
    char* newString = reinterpret_cast<char*>( sqlsrv_malloc( cchOutLen + 1 /* NULL char*/ ));
    int rc = WideCharToMultiByte( encoding, flags,
                                  inString, cchInLen, 
                                  newString, cchOutLen, NULL, NULL );
    if( rc == 0 ) {
        cchOutLen = 0;
        sqlsrv_free( newString );
        return false;
    }

    *outString = newString;
    newString[cchOutLen] = '\0';   // null terminate the encoded string

    return true;
}
Esempio n. 3
0
// Check for end of string.
inline bool string_parser::is_eos( void )
{
    if( this->pos == len )
    {
        return true; // EOS
    }

    SQLSRV_ASSERT(this->pos < len, "Unexpected cursor position in conn_string_parser::is_eos" );
    
    return false;
}
Esempio n. 4
0
// write to the php log if the severity and subsystem match the filters currently set in the INI or 
// the script (sqlsrv_configure).
void write_to_log( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, ...)
{
    SQLSRV_ASSERT( !(g_driver_log == NULL), "Must register a driver log function." );

    va_list args;
    va_start( args, msg );

    g_driver_log( severity TSRMLS_CC, msg, &args );

    va_end( args );
}
Esempio n. 5
0
// PDO error handler for the environment context.
bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, 
                                  va_list* print_args )
{
    SQLSRV_ASSERT(( ctx != NULL ), "pdo_sqlsrv_handle_env_error: sqlsrv_context was null" );
    pdo_dbh_t* dbh = reinterpret_cast<pdo_dbh_t*>( ctx.driver());    
    SQLSRV_ASSERT(( dbh != NULL ), "pdo_sqlsrv_handle_env_error: pdo_dbh_t was null" );
    
    sqlsrv_error_auto_ptr error;

    if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {

        core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args );
    }
    else {

        bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
        SQLSRV_ASSERT( err == true, "No ODBC error was found" );
    }

    strcpy_s( dbh->error_code, sizeof( pdo_error_type ), reinterpret_cast<const char*>( error->sqlstate ));

    switch( dbh->error_mode ) {

        case PDO_ERRMODE_EXCEPTION:
            if( !warning ) {

                pdo_sqlsrv_throw_exception( error TSRMLS_CC );
            }
            ctx.set_last_error( error );
            break;

        default:
            DIE( "pdo_sqlsrv_handle_env_error: Unexpected error mode. %1!d!", dbh->error_mode );
            break;
    }
    
    // we don't transfer the zval_auto_ptr since set_last_error increments the zval ref count
    // return error ignored = true for warnings.
    return ( warning ? true : false );

}
Esempio n. 6
0
// Returns a sqlsrv_error for a given error code.
sqlsrv_error_const* get_error_message( unsigned int sqlsrv_error_code ) {
    
    sqlsrv_error_const *error_message = NULL;
    int zr = zend_hash_index_find( g_pdo_errors_ht, sqlsrv_error_code, reinterpret_cast<void**>( &error_message ));
    if( zr == FAILURE ) {
        DIE( "get_error_message: zend_hash_index_find returned failure for sqlsrv_error_code = %1!d!", sqlsrv_error_code );   
    }
    
    SQLSRV_ASSERT( error_message != NULL, "get_error_message: error_message was null");

    return error_message;
}
Esempio n. 7
0
// Move to the next character
inline bool string_parser::next( void )
{
    // if already at the end then return false
    if( this->is_eos() ) {

        return false;
    }
        
    SQLSRV_ASSERT( this->pos < len, "Unexpected cursor position in conn_string_parser::next" );

    this->pos++;    

    if ( this->is_eos() ) {
    
        return false;
    }
    
    return true;
}
Esempio n. 8
0
bool convert_string_from_utf16_inplace( SQLSRV_ENCODING encoding, char** string, SQLLEN& len)
{
    SQLSRV_ASSERT( string != NULL && *string != NULL, "String must be specified" );

    // for the empty string, we simply returned we converted it
    if( len == 0 && *string[0] == '\0' ) {
        return true;
    }

    char* outString = NULL;
    SQLINTEGER outLen = 0;
    bool result = convert_string_from_utf16( encoding, reinterpret_cast<const wchar_t*>(*string), len / sizeof(wchar_t), &outString, outLen);

    if (result)
    {
        sqlsrv_free( *string );
        *string = outString;
        len = outLen;
    }

    return result;
}
Esempio n. 9
0
// Primary function which parses the connection string/DSN.
void conn_string_parser:: parse_conn_string( TSRMLS_D ) 
{
    States state = FirstKeyValuePair; // starting state
    int start_pos = -1;

    try {

        while( !this->is_eos() ) {
        
            switch( state ) {
            
                case FirstKeyValuePair:
                {
                    // discard leading spaces
                    if( !next() || !discard_white_spaces() ) {
                        
                        THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_STRING ); //EOS
                    }
                  
                    state = Key;
                    break;
                }

                case Key:
                {
                    start_pos = this->pos;

                    // read the key name
                    while( this->conn_str[ pos ] != '=' ) {
                    
                        if( !next() ) {
                            
                            THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_DSN_STRING_ENDED_UNEXPECTEDLY ); //EOS 
                        }      
                    } 

                    this->validate_key( &( this->conn_str[ start_pos ] ), ( pos - start_pos ) TSRMLS_CC ); 
                
                    state = Value;

                    break;
                }

                case Value:
                {
                    SQLSRV_ASSERT(( this->conn_str[ pos ] == '=' ), "conn_string_parser:: parse_conn_string: "
                                   "Equal was expected" );

                    next(); // skip "="

                    // if EOS encountered after 0 or more spaces OR semi-colon encountered.
                    if( !discard_white_spaces() || this->conn_str[ pos ] == ';' ) {

                        add_key_value_pair( NULL, 0 TSRMLS_CC );

                        if( this->is_eos() ) {
                            
                            break; // EOS
                        }
                        else {

                            // this->conn_str[ pos ] == ';' 
                            state = NextKeyValuePair;
                        }
                    }
                    
                    // if LCB
                    else if( this->conn_str[ pos ] == '{' ) {
                        
                        start_pos = this->pos; // starting character is LCB
                        state = ValueContent1;
                    }
                    
                    // If NonSP-LCB-SC
                    else  {

                        start_pos = this->pos;
                        state = ValueContent2;
                    }

                    break;
                }

                case ValueContent1:
                {
                    while ( this->conn_str[ pos ] != '}' ) {
                    
                        if ( ! next() ) {

                            THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE, this->current_key_name ); 
                        }
                    }

                    // If we reached here than RCB encountered
                    state = RCBEncountered;

                    break;
                }

                case ValueContent2:
                {
                    while( this->conn_str[ pos ] != ';' ) {

                        if( ! next() ) {
                            
                            break; //EOS
                        }
                    }

                    if( !this->is_eos() && this->conn_str[ pos ] == ';' ) {
                    
                        // semi-colon encountered, so go to next key-value pair
                        state = NextKeyValuePair;
                    }
                    
                    add_key_value_pair( &( this->conn_str[ start_pos ] ), this->pos - start_pos TSRMLS_CC );
              
                    SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )), 
                                  "conn_string_parser::parse_conn_string: Invalid state encountered " );

                    break;
                }

                case RCBEncountered:
                {
                    
                    // Read the next character after RCB.
                    if( !next() ) {

                        // EOS
                        add_key_value_pair( &( this->conn_str[ start_pos ] ), this->pos - start_pos TSRMLS_CC );
                        break;
                    }

                    SQLSRV_ASSERT( !this->is_eos(), "conn_string_parser::parse_conn_string: Unexpected EOS encountered" );

                    // if second RCB encountered than go back to ValueContent1
                    if( this->conn_str[ pos ] == '}' ) {
                        
                        if( !next() ) {

                            // EOS after a second RCB is error
                            THROW_PDO_ERROR( this->ctx, SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN, this->current_key_name );                              
                        }

                        state = ValueContent1;
                        break;
                    }

                    int end_pos = this->pos;

                    // discard any trailing white-spaces.
                    if( this->is_white_space( this->conn_str[ pos ] )) {
                    
                        if( ! this->discard_white_spaces() ) {
                            
                            //EOS
                            add_key_value_pair( &( this->conn_str[ start_pos ] ), end_pos - start_pos TSRMLS_CC );
                            break;
                        }
                    }

                    // if semi-colon than go to next key-value pair
                    if ( this->conn_str[ pos ] == ';' ) {
                        
                        add_key_value_pair( &( this->conn_str[ start_pos ] ), end_pos - start_pos TSRMLS_CC );
                        state = NextKeyValuePair;
                        break;
                    }

                    // Non - (RCB, SP*, SC, EOS) character. Any other character after an RCB is an error.
                    THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_VALUE, this->current_key_name );      
                    break;    
                }
                case NextKeyValuePair:
                {
                    SQLSRV_ASSERT(( this->conn_str[ pos ] == ';' ), 
                                  "conn_string_parser::parse_conn_string: semi-colon was expected." );

                    // Call next() to skip the semi-colon.
                    if( !next() || !this->discard_white_spaces() ) {
                    
                        // EOS
                        break;
                    }
                    
                    if( this->conn_str[ pos ] == ';' ) {
                    
                        // a second semi-colon is error case.
                        THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING, this->pos );      
                    }

                    else {

                        // any other character leads to the next key
                        state = Key;
                        break;
                    }
                } //case NextKeyValuePair
            } // switch
        } //while
    } 
    catch( pdo::PDOException& ) {

        throw;
    }
}