Index: ChangeLog =================================================================== --- ChangeLog (revision 886) +++ ChangeLog (working copy) @@ -23,6 +23,7 @@ 5.1.1 Functionality added or changed: + * Disallow 'SET NAMES' in initial statement and in executed statements. * Replaced the internal library which handles creation and loading of DSN information. The new library, which was originally a part of Connector/ODBC 5.0, supports Unicode option values. Index: driver/myutil.h =================================================================== --- driver/myutil.h (revision 886) +++ driver/myutil.h (working copy) @@ -133,6 +133,7 @@ char *check_if_positioned_cursor_exists(STMT FAR *stmt, STMT FAR **stmtNew); char *insert_param(DBC *dbc, char *to,DESCREC *aprec,DESCREC *iprec); char *add_to_buffer(NET *net,char *to,const char *from,ulong length); +int is_set_names_statement(SQLCHAR *query); void reset_getdata_position(STMT *stmt); Index: driver/utility.c =================================================================== --- driver/utility.c (revision 886) +++ driver/utility.c (working copy) @@ -2557,3 +2557,13 @@ *truncptr= trunc; } +/** + Detect if a statement is a SET NAMES statement. +*/ +int is_set_names_statement(SQLCHAR *query) +{ + /* Skip leading spaces */ + while (query && isspace(*query)) + query++; + return strncasecmp(query, "SET NAMES", 9) == 0; +} Index: driver/connect.c =================================================================== --- driver/connect.c (revision 886) +++ driver/connect.c (working copy) @@ -181,8 +181,15 @@ mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "odbc"); if (ds->initstmt && ds->initstmt[0]) - mysql_options(mysql, MYSQL_INIT_COMMAND, - ds_get_utf8attr(ds->initstmt, &ds->initstmt8)); + { + /* Check for SET NAMES */ + if (is_set_names_statement(ds_get_utf8attr(ds->initstmt, &ds->initstmt8))) + { + return set_dbc_error(dbc, "HY000", + "SET NAMES not allowed by driver", 0); + } + mysql_options(mysql, MYSQL_INIT_COMMAND, ds->initstmt8); + } if (dbc->login_timeout) mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, Index: driver/execute.c =================================================================== --- driver/execute.c (revision 886) +++ driver/execute.c (working copy) @@ -649,6 +649,10 @@ return set_error(pStmt, MYERR_S1010, "No previous SQLPrepare done", 0); + if (is_set_names_statement(pStmt->query)) + return set_error(pStmt, MYERR_42000, + "SET NAMES not allowed by driver", 0); + if ( (cursor_pos= check_if_positioned_cursor_exists(pStmt, &pStmtCursor)) ) { /* Save a copy of the query, because we're about to modify it. */ Index: test/my_basics.c =================================================================== --- test/my_basics.c (revision 886) +++ test/my_basics.c (working copy) @@ -592,6 +592,43 @@ } +DECLARE_TEST(setnames) +{ + expect_sql(hstmt, "SET NAMES utf8", SQL_ERROR); + expect_sql(hstmt, "SeT NamES utf8", SQL_ERROR); + expect_sql(hstmt, " set names utf8", SQL_ERROR); + expect_sql(hstmt, " set names utf8", SQL_ERROR); + return OK; +} + + +DECLARE_TEST(setnames_conn) +{ + HDBC hdbc1; + SQLCHAR conn[256], conn_out[256]; + SQLSMALLINT conn_out_len; + + sprintf((char *)conn, "DSN=%s;UID=%s;PWD=%s;INITSTMT={set names utf8}", + mydsn, myuid, mypwd); + if (mysock != NULL) + { + strcat((char *)conn, ";SOCKET="); + strcat((char *)conn, (char *)mysock); + } + + ok_env(henv, SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1)); + + expect_dbc(hdbc1, SQLDriverConnect(hdbc1, NULL, conn, sizeof(conn), conn_out, + sizeof(conn_out), &conn_out_len, + SQL_DRIVER_NOPROMPT), + SQL_ERROR); + + ok_con(hdbc1, SQLFreeHandle(SQL_HANDLE_DBC, hdbc1)); + + return OK; +} + + BEGIN_TESTS ADD_TEST(my_basics) ADD_TEST(t_max_select) @@ -609,6 +646,8 @@ ADD_TEST(t_bug30983) /* TODO fix this test create a comparable output string */ ADD_TODO(t_driverconnect_outstring) + ADD_TEST(setnames) + ADD_TEST(setnames_conn) END_TESTS