Modified:
trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverExports.def
trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverLib.pro
trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverMain.cpp
trunk/MYODBCDriver/MYODBCDriverLib/SQLGetDiagRecW.cpp
trunk/MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp
trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
Log:
Fixed bug where null args to SQLGetDiagRec/SQLGetDiagField were not handled properly and
driver crashed.
Modified: trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverExports.def
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverExports.def 2006-06-17 22:25:53 UTC
(rev 349)
+++ trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverExports.def 2006-06-18 23:33:18 UTC
(rev 350)
@@ -73,8 +73,8 @@
SQLTablePrivilegesW
SQLTablesW
;
-DllMain
-LoadByOrdinal
+; DllMain
+; LoadByOrdinal
Modified: trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverLib.pro
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverLib.pro 2006-06-17 22:25:53 UTC (rev
349)
+++ trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverLib.pro 2006-06-18 23:33:18 UTC (rev
350)
@@ -63,7 +63,7 @@
MYODBCDriverInternal.h
SOURCES = \
- MYODBCDriverMain.cpp \
+# MYODBCDriverMain.cpp \
SQLAllocHandle.cpp \
SQLBindCol.cpp \
SQLBindParameter.cpp \
Modified: trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverMain.cpp
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverMain.cpp 2006-06-17 22:25:53 UTC (rev
349)
+++ trunk/MYODBCDriver/MYODBCDriverLib/MYODBCDriverMain.cpp 2006-06-18 23:33:18 UTC (rev
350)
@@ -51,6 +51,7 @@
DWORD nReason,
LPVOID pReserved )
{
+printf( "[PAH][%s][%d]\n", __FILE__, __LINE__ );
switch ( nReason )
{
case DLL_PROCESS_ATTACH:
Modified: trunk/MYODBCDriver/MYODBCDriverLib/SQLGetDiagRecW.cpp
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/SQLGetDiagRecW.cpp 2006-06-17 22:25:53 UTC (rev
349)
+++ trunk/MYODBCDriver/MYODBCDriverLib/SQLGetDiagRecW.cpp 2006-06-18 23:33:18 UTC (rev
350)
@@ -27,6 +27,7 @@
case SQL_HANDLE_ENV:
MYODBCDbgReturn( ((MEnvironment*)hHandle)->getDiagRec( nRecNumber,
psSQLState, pnNativeError, psMessageText, nBufferLength, pnTextLength ) );
case SQL_HANDLE_DBC:
+// printf( "[PAH][%s][%s][%d] nRecNumber=%d pnNativeError=%d psMessageText=%p\n",
__FILE__, __FUNCTION__, __LINE__, nRecNumber, pnNativeError, psMessageText );
MYODBCDbgReturn( ((MConnection*)hHandle)->getDiagRec( nRecNumber,
psSQLState, pnNativeError, psMessageText, nBufferLength, pnTextLength ) );
case SQL_HANDLE_STMT:
MYODBCDbgReturn( ((MStatement*)hHandle)->getDiagRec( nRecNumber,
psSQLState, pnNativeError, psMessageText, nBufferLength, pnTextLength ) );
Modified: trunk/MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp 2006-06-17 22:25:53 UTC (rev 349)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp 2006-06-18 23:33:18 UTC (rev 350)
@@ -246,16 +246,51 @@
MYODBCDbgReturn( SQL_SUCCESS );
}
-SQLRETURN MDiagnostic::getDiagRec( SQLSMALLINT nRecNumber, SQLWCHAR *psSqlstate,
SQLINTEGER *pnNativeErrorPtr, SQLWCHAR *pszMessageText, SQLSMALLINT nBufferLength,
SQLSMALLINT *pnTextByteLength )
+SQLRETURN MDiagnostic::getDiagRec( SQLSMALLINT nRecNumber, SQLWCHAR *psSqlstate,
SQLINTEGER *pnNativeError, SQLWCHAR *pszMessageText, SQLSMALLINT nBufferCharLength,
SQLSMALLINT *pnTextByteLength )
{
MYODBCDbgEnter();
- if ( nRecNumber < 1 )
+ SQLRETURN nReturn;
+ SQLRETURN nReturnHolistic = SQL_SUCCESS;
+
+ /*!
+ \internal ODBC RULE
+
+ SQL_ERROR.... BufferLength was less than zero.
+ */
+ if ( nBufferCharLength < 0 )
MYODBCDbgReturn( SQL_ERROR );
- if ( nRecNumber > getNumber() )
- MYODBCDbgReturn( SQL_NO_DATA );
- MYODBCDbgReturn( ((MDiagnosticRecord*)(children().at( nRecNumber - 1
)))->getDiagRec( psSqlstate, pnNativeErrorPtr, pszMessageText, nBufferLength,
pnTextByteLength ) );
+ /*!
+ \internal MYODBC RULE
+
+ psSqlstate and pnNativeError are optional - pszMessageText is not.
+ */
+ if ( psSqlstate )
+ {
+ nReturn = getDiagField( nRecNumber, SQL_DIAG_SQLSTATE, psSqlstate, 5, NULL );
+ if ( nReturn == SQL_SUCCESS_WITH_INFO )
+ nReturnHolistic = SQL_SUCCESS_WITH_INFO;
+ if ( !SQL_SUCCEEDED( nReturn ) )
+ MYODBCDbgReturn( nReturn );
+ }
+
+ if ( pnNativeError )
+ {
+ nReturn = getDiagField( nRecNumber, SQL_DIAG_NATIVE, pnNativeError,
SQL_IS_INTEGER, NULL );
+ if ( nReturn == SQL_SUCCESS_WITH_INFO )
+ nReturnHolistic = SQL_SUCCESS_WITH_INFO;
+ if ( !SQL_SUCCEEDED( nReturn ) )
+ MYODBCDbgReturn( nReturn );
+ }
+
+ nReturn = getDiagField( nRecNumber, SQL_DIAG_MESSAGE_TEXT, pszMessageText,
nBufferCharLength, pnTextByteLength );
+ if ( nReturn == SQL_SUCCESS_WITH_INFO )
+ nReturnHolistic = SQL_SUCCESS_WITH_INFO;
+ if ( !SQL_SUCCEEDED( nReturn ) )
+ MYODBCDbgReturn( nReturn );
+
+ MYODBCDbgReturn( nReturnHolistic );
}
/*!
@@ -287,6 +322,14 @@
if ( !pnStringLengthPtr )
pnStringLengthPtr = &nStringLength;
+ /*!
+ \internal MYODBC RULE
+
+ We must get a viable pDiagInfoPtr.
+ */
+ if ( !pDiagInfoPtr )
+ MYODBCDbgReturn( SQL_ERROR );
+
/*
These are the fields we know about listed by category
(header/record) and in _alpha_ order.
@@ -309,6 +352,17 @@
break;
case SQL_DIAG_DYNAMIC_FUNCTION:
+ /*!
+ \internal ODBC RULE
+
+ The contents of this field are defined only for statement handles and
only after a call to SQLExecute, SQLExecDirect, or SQLMoreResults.
+ Calling SQLGetDiagField with a DiagIdentifier of
SQL_DIAG_DYNAMIC_FUNCTION_CODE on other than a statement handle will return SQL_ERROR.
+ */
+ if ( parent() && parent()->objectName() != "MStatement" )
+ MYODBCDbgReturn( SQL_ERROR );
+ if ( ((MStatement*)parent())->getState() < MStatement::STATE_S4 )
+ MYODBCDbgReturn( SQL_ERROR );
+
{
QString stringDynamicFunction = getDynamicFunction();
if ( nBufferLength < 1 || stringDynamicFunction.isNull() )
@@ -321,6 +375,17 @@
break;
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
+ /*!
+ \internal ODBC RULE
+
+ The contents of this field are defined only for statement handles and
only after a call to SQLExecute, SQLExecDirect, or SQLMoreResults.
+ Calling SQLGetDiagField with a DiagIdentifier of
SQL_DIAG_DYNAMIC_FUNCTION_CODE on other than a statement handle will return SQL_ERROR.
+ */
+ if ( parent() && parent()->objectName() != "MStatement" )
+ MYODBCDbgReturn( SQL_ERROR );
+ if ( ((MStatement*)parent())->getState() < MStatement::STATE_S4 )
+ MYODBCDbgReturn( SQL_ERROR );
+
*(SQLINTEGER*)pDiagInfoPtr = getDynamicFunctionCode();
break;
@@ -348,11 +413,24 @@
break;
default:
+ /*!
+ \internal ODBC RULE
+
+ SQL_ERROR.... RecNumber was negative or 0.
+ */
if ( nRecNumber < 1 )
MYODBCDbgReturn( SQL_ERROR );
+
+ /*!
+ \internal ODBC RULE
+
+ SQL_NO_DATA.... RecNumber was greater than the number of diagnostic
records that existed for
+ the handle specified in Handle.
+ */
if ( nRecNumber > getNumber() )
MYODBCDbgReturn( SQL_NO_DATA );
- MYODBCDbgReturn( ((MDiagnosticRecord*)(children()[nRecNumber -
1]))->getDiagField( nDiagIdentifier, pDiagInfoPtr, nBufferLength, pnStringLengthPtr )
);
+
+ MYODBCDbgReturn( ((MDiagnosticRecord*)(children().at( nRecNumber - 1
)))->getDiagField( nDiagIdentifier, pDiagInfoPtr, nBufferLength, pnStringLengthPtr )
);
}
MYODBCDbgReturn( SQL_SUCCESS );
Modified: trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp 2006-06-17 22:25:53 UTC (rev 349)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp 2006-06-18 23:33:18 UTC (rev 350)
@@ -2396,6 +2396,13 @@
pResult = NULL;
}
+ /*!
+ \internal
+ \todo
+
+ Set SQL_DIAG_DYNAMIC_FUNCTION and SQL_DIAG_DYNAMIC_FUNCTION_CODE diagnostic
header fields and possibly use them instead
+ of MResult statement type.
+ */
switch ( pResult->getStatementType() )
{
case MResult::STATEMENT_TYPE_UPDATE:
| Thread |
|---|
| • Connector/ODBC 5 commit: r350 - in trunk: MYODBCDriver/MYODBCDriverLib MYSQLPlus/MYSQLPlusLib | pharvey | 19 Jun |