From bb3c7bb2ab8a0d3288a2647b56c799d8d3ebb968 Mon Sep 17 00:00:00 2001 From: Kisoo Han Date: Sat, 8 Oct 2022 11:23:35 +0900 Subject: [PATCH] [APIS-936] Handle TextLength2Ptr NULL exception in SQLNativeSql (#64) Handle NULL pointer exception, SQLNativeSql --- UnitTest-CPP/UnitTest-CPP/UnitTest.cpp | 48 ++++++++++++++++++++++++++ odbc_interface.c | 6 ++++ odbc_version.i | 4 +-- unicode.c | 3 +- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/UnitTest-CPP/UnitTest-CPP/UnitTest.cpp b/UnitTest-CPP/UnitTest-CPP/UnitTest.cpp index 4eb3d70..643b612 100644 --- a/UnitTest-CPP/UnitTest-CPP/UnitTest.cpp +++ b/UnitTest-CPP/UnitTest-CPP/UnitTest.cpp @@ -345,6 +345,54 @@ namespace UnitTestCPP retcode = SQLFreeHandle(SQL_HANDLE_ENV, hEnv); } + TEST_METHOD(APIS_936_TextLength2Ptr_NULL_CHK) + { + SQLHENV hEnv; + SQLHDBC hDbc; + SQLHSTMT hStmt; + WCHAR query2 [512] = L"select date_format(now(),'%T')"; + WCHAR query [512] = L"show tables"; + WCHAR converted_qry [512]; + WCHAR col1[512]; + WCHAR msg[512]; + SQLINTEGER length; + SQLINTEGER retcode; + SQLLEN len; + int num_rows = 0; + + retcode = SQLAllocEnv(&hEnv); + retcode = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); + retcode = SQLAllocConnect(hEnv, &hDbc); + retcode = SQLDriverConnect(hDbc, NULL, L"DRIVER=CUBRID Driver Unicode;server=test-db-server;port=33000;uid=public;pwd=;db_name=demodb;charset=utf-8;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); + Assert::AreNotEqual((int)retcode, SQL_ERROR); + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); + + // Case-1: Check if SQL_ERROR is returned when TextLength2Ptr is NULL + retcode = SQLNativeSqlW (hDbc, query, sizeof(query), converted_qry, sizeof(converted_qry), NULL); + Assert::AreEqual((int)retcode, SQL_ERROR); + + // Case-2: Convert and execute with proper TextLength2Ptr + retcode = SQLNativeSqlW(hDbc, query, sizeof(query), converted_qry, sizeof(converted_qry), &length); + Assert::AreNotEqual((int)retcode, SQL_ERROR); + wsprintf(msg, L"len = %d, converted qry = '%s'", length, converted_qry); + Logger::WriteMessage(msg); + + retcode = SQLPrepareW(hStmt, converted_qry, SQL_NTS); + retcode = SQLExecute(hStmt); + retcode = SQLBindCol(hStmt, 1, SQL_C_WCHAR, (SQLPOINTER)col1, sizeof(col1), &len); + + memset(col1, 0, sizeof(col1)); + while ((retcode = SQLFetch(hStmt)) == SQL_SUCCESS) { + wsprintf (msg, L"rows [%2d]: col1 = '%s'\n", ++num_rows, col1); + Logger::WriteMessage(msg); + memset(col1, 0, sizeof(col1)); + } + + retcode = SQLDisconnect(hDbc); + retcode = SQLFreeHandle(SQL_HANDLE_DBC, hDbc); + retcode = SQLFreeHandle(SQL_HANDLE_ENV, hEnv); + } + TEST_METHOD(APIS_794_QueryPlanMultiByte) { RETCODE retcode; diff --git a/odbc_interface.c b/odbc_interface.c index 6345693..615748b 100644 --- a/odbc_interface.c +++ b/odbc_interface.c @@ -1389,6 +1389,12 @@ SQLNativeSql (SQLHDBC ConnectionHandle, odbc_free_diag (((ODBC_CONNECTION *) ConnectionHandle)->diag, RESET); + if (TextLength2Ptr == NULL) + { + odbc_set_diag (((ODBC_CONNECTION *) ConnectionHandle)->diag, "HY009", 0, "NULL pointer: TextLength2Ptr"); + return ODBC_ERROR; + } + stInStatementText = UT_MAKE_STRING (InStatementText, TextLength1); diff --git a/odbc_version.i b/odbc_version.i index 97d644e..491f512 100644 --- a/odbc_version.i +++ b/odbc_version.i @@ -1,5 +1,5 @@ #define MAJOR_VERSION 11 #define MINOR_VERSION 2 -#define PATCH_VERSION 0 +#define PATCH_VERSION 1 #define BUILD_SERIAL_NUMBER 0001 -#define VERSION_STRING "11.2.0.0001" +#define VERSION_STRING "11.2.1.0055" diff --git a/unicode.c b/unicode.c index b529d6f..a6fa2c2 100644 --- a/unicode.c +++ b/unicode.c @@ -333,13 +333,14 @@ SQLNativeSqlW (SQLHDBC hdbc, SQLWCHAR *in, SQLINTEGER in_len, memset (sql_text_buffer, 0 , out_max); ret = SQLNativeSql(hdbc, sql_state, sql_state_len, sql_text_buffer, out_max, out_len); - sql_state_len = *out_len; if (ret == ODBC_ERROR) { UT_FREE (sql_text_buffer); return ret; } + + sql_state_len = *out_len; bytes_to_wide_char (sql_text_buffer, sql_state_len, &out, out_max, out_len, conn->charset); UT_FREE (sql_text_buffer); return ret;