=== modified file 'ChangeLog' --- ChangeLog 2012-11-30 14:57:50 +0000 +++ ChangeLog 2012-12-03 09:47:30 +0000 @@ -7,6 +7,8 @@ (Bug# 11766724/59900) * Corrected calculation for length indicator descriptor field (Bug# 11766437) * is_minimum_version() function does not work correctly (Bug# 15926340) + * Driver use the char ';' as separator in attributes string instead + of the '\0' (Bug# 15940689/66548) ---- === modified file 'test/CMakeLists.txt' --- test/CMakeLists.txt 2012-11-12 14:40:45 +0000 +++ test/CMakeLists.txt 2012-12-03 08:37:36 +0000 @@ -40,7 +40,7 @@ FOREACH(T my_basics my_blob my_bulk my_catalog1 my_catalog2 my_curext my_cursor my_datetime my_desc my_dyn_cursor my_error my_info my_keys my_param - my_prepare my_relative my_result1 my_result2 my_scroll my_tran + my_prepare my_relative my_result1 my_result2 my_scroll my_setup my_tran my_types my_unicode my_unixodbc my_use_result my_bug13766) ADD_EXECUTABLE(${T} ${T}.c) === added file 'test/my_setup.c' --- test/my_setup.c 1970-01-01 00:00:00 +0000 +++ test/my_setup.c 2012-11-30 13:06:18 +0000 @@ -0,0 +1,101 @@ +/* + Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + + The MySQL Connector/ODBC is licensed under the terms of the GPLv2 + , like most + MySQL Connectors. There are special exceptions to the terms and + conditions of the GPLv2 as it is applied to this software, see the + FLOSS License Exception + . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "odbctap.h" + +/** + Bug #66548: Driver use the char ';' as separator in attributes string + instead of the '\0' +*/ +DECLARE_TEST(t_bug66548) +{ + /* TODO: remove #ifdef _WIN32 when Linux and MacOS setup is released */ +#ifdef _WIN32 + SQLCHAR attrs[8192]; + SQLCHAR drv[128]; + SQLCHAR conn_out[512]; + SQLSMALLINT conn_out_len; + int i, len; + HDBC hdbc1; + + /* + Use ';' as separator because sprintf doesn't work after '\0' + The last attribute in the list must end with ';' + */ + + sprintf((char*)attrs, "DSN=bug66548dsn;SERVER=%s;USER=%s;PASSWORD=%s;" + "DATABASE=%s;", myserver, myuid, mypwd, mydb); + + len= strlen(attrs); + + /* replacing ';' by '\0' */ + for (i= 0; i < len; ++i) + { + if (attrs[i] == ';') + attrs[i]= '\0'; + } + + /* Adding the extra string termination to get \0\0 */ + attrs[i]= '\0'; + + if (mydriver[0] == '{') + { + /* We need to remove {} in the driver name or it will not register */ + len= strlen(mydriver); + memcpy(drv, mydriver+1, sizeof(SQLCHAR)*(len-2)); + drv[len-2]= '\0'; + } + + /* + Trying to remove the DSN if it is left from the previous run, + no need to check the result + */ + SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drv, "DSN=bug66548dsn\0\0"); + + /* Create the DSN */ + ok_install(SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drv, attrs)); + + ok_env(henv, SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1)); + + /* Try connecting using the newly created DSN */ + ok_con(hdbc1, SQLDriverConnect(hdbc1, NULL, "DSN=bug66548dsn", SQL_NTS, conn_out, + sizeof(conn_out), &conn_out_len, + SQL_DRIVER_NOPROMPT)); + ok_con(hdbc1, SQLDisconnect(hdbc1)); + ok_con(hdbc1, SQLFreeHandle(SQL_HANDLE_DBC, hdbc1)); + + ok_install(SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drv, "DSN=bug66548dsn\0\0")); +#endif + + return OK; +} + + +BEGIN_TESTS + ADD_TEST(t_bug66548) +END_TESTS + + +RUN_TESTS + === modified file 'test/odbctap.h' --- test/odbctap.h 2012-09-18 00:32:56 +0000 +++ test/odbctap.h 2012-12-03 09:54:41 +0000 @@ -53,6 +53,7 @@ #include #include +#include /* for clock() */ #include @@ -472,6 +473,21 @@ /** + Verify that the results of an ODBC function call on an environment handle + was SQL_SUCCESS or SQL_SUCCESS_WITH_INFO. + + @param call The function call +*/ +#define ok_install(call) \ +do { \ + BOOL rc= (call); \ + print_diag_installer(rc, #call, __FILE__, __LINE__); \ + if (!rc) \ + return FAIL; \ +} while (0) + + +/** Verify that a Boolean expression is true. It's recommended to use is_num, is_str, etc macros instead of "is(a==b)", since those will show values being compared, in a log. @@ -570,6 +586,8 @@ /** + Print error and diagnostic information for ODBC API functions that did not + finish with SQL_SUCCESS(_WITH_INFO) result */ static void print_diag(SQLRETURN rc, SQLSMALLINT htype, SQLHANDLE handle, const char *text, const char *file, int line) @@ -598,6 +616,32 @@ } +/** + Print error and diagnostic information for ODBC INSTALLER API functions + that did not return TRUE (1) +*/ +static void print_diag_installer(BOOL is_success, const char *text, + const char *file, int line) +{ + if (!is_success) + { + SQLCHAR message[SQL_MAX_MESSAGE_LENGTH]; + SQLINTEGER error_code; + SQLSMALLINT length; + SQLRETURN drc; + + drc= SQLInstallerError(1, &error_code, message, SQL_MAX_MESSAGE_LENGTH - 1, &length); + + if (SQL_SUCCEEDED(drc)) + printf("# [%s] %s in %s on line %d\n", + text, message, file, line); + else + printf("# Did not get expected diagnostics from SQLInstallerError() = %d" + " in file %s on line %d\n", drc, file, line); + } +} + + /* UTILITY MACROS */ #define myenv(henv,r) \ do { \ === modified file 'util/installer.c' --- util/installer.c 2012-06-15 11:09:25 +0000 +++ util/installer.c 2012-11-30 14:03:32 +0000 @@ -1007,7 +1007,9 @@ attrs= end; /* If delim is NULL then double-NULL is the end of key-value pairs list */ - while ((delim && *attrs == delim) || *attrs == ' ') + while ((delim && *attrs == delim) || + (!delim && !*attrs && *(attrs+1)) || + *attrs == ' ') ++attrs; } === modified file 'util/stringutil.c' --- util/stringutil.c 2012-09-17 20:17:05 +0000 +++ util/stringutil.c 2012-11-30 13:34:34 +0000 @@ -593,7 +593,8 @@ */ const SQLWCHAR *sqlwcharchr(const SQLWCHAR *wstr, SQLWCHAR wchr) { - while (*wstr) + /* if wchr is \0 the function returns the address of its position anyway */ + while (*wstr || (wchr == 0)) { if (*wstr == wchr) {