diff --git a/dsn/odbc_dsn.c b/dsn/odbc_dsn.c index e2482086..3215a466 100644 --- a/dsn/odbc_dsn.c +++ b/dsn/odbc_dsn.c @@ -153,6 +153,11 @@ my_bool SetDialogFields() int i= 0; MADB_Dsn *Dsn= (MADB_Dsn *)GetWindowLongPtr(GetParent(hwndTab[0]), DWLP_USER); + /* Basically - if dialog does not exist yet */ + if (Dsn == NULL) + { + return TRUE; + } while (DsnMap[i].Key) { switch (DsnMap[i].Key->Type) { @@ -492,7 +497,8 @@ static SQLRETURN TestDSN(MADB_Dsn *Dsn, SQLHANDLE *Conn, SQLCHAR *ConnStrBuffer) } DsnApplyDefaults(Dsn); - /* If defaults has changed actual values - let them be reflected in the dialog */ + /* If defaults has changed actual values - let them be reflected in the dialog(if it exists - SetDialogFields + cares about that) */ SetDialogFields(); MADB_DsnToString(Dsn, ConnStr, CONNSTR_BUFFER_SIZE); @@ -852,10 +858,10 @@ void CenterWindow(HWND hwndWindow) BOOL DSNDialog(HWND hwndParent, - WORD fRequest, - LPCSTR lpszDriver, - LPCSTR lpszAttributes, - MADB_Dsn *Dsn) + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszAttributes, + MADB_Dsn *Dsn) { MSG msg; BOOL ret; @@ -927,13 +933,18 @@ BOOL DSNDialog(HWND hwndParent, Dsn->Driver= _strdup(lpszDriver); } - if (SQL_SUCCEEDED(TestDSN(Dsn, NULL, NULL))) - { - return MADB_SaveDSN(Dsn); - } - else if (hwndParent == NULL) + /* If we don't have parent window - we are not supposed to show the dialog, but only + perform operation, if sufficient data has been provided */ + if (hwndParent == NULL) { - return FALSE; + if (SQL_SUCCEEDED(TestDSN(Dsn, NULL, NULL))) + { + return MADB_SaveDSN(Dsn); + } + else + { + return FALSE; + } } break; @@ -963,7 +974,7 @@ BOOL DSNDialog(HWND hwndParent, { return MADB_SaveDSN(Dsn); } - else if (hwndParent == NULL) + else { return FALSE; } diff --git a/dsn_test.c b/dsn_test.c index c97d815b..c5cfa395 100644 --- a/dsn_test.c +++ b/dsn_test.c @@ -19,6 +19,7 @@ #include #include +#include #include typedef BOOL (*DSNDialog)(HWND hwndParent, @@ -33,7 +34,17 @@ int main() DSNDialog DsnFunc= NULL; HWND hWnd; DWORD dwProcID= GetCurrentProcessId(); + const char *driver= getenv("TEST_DRIVER"); + if (driver == NULL) + { + printf("Test requires environment variable TEST_DRIVER to be set!\n"); + return 1; + } + else + { + printf("# Using Driver=%s for testing.\n", driver); + } hWnd= GetConsoleWindow(); if (hWnd == NULL) { @@ -52,30 +63,30 @@ int main() { if (DsnFunc= (DSNDialog)GetProcAddress(hmod, "ConfigDSN")) { - ret= DsnFunc(NULL, ODBC_ADD_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0OPTIONS=2\0\0"); + ret= DsnFunc(NULL, ODBC_ADD_DSN, driver, "DSN=dsn_test\0OPTIONS=2\0\0"); printf("%s 1 Null hWnd and not enough info\n", ret ? "not ok" : "ok"); printf("# The dialog is supposed to show up now - please complete info for connection\n"); - ret= DsnFunc(hWnd, ODBC_ADD_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0OPTIONS=2\0\0"); + ret= DsnFunc(hWnd, ODBC_ADD_DSN, driver, "DSN=dsn_test\0OPTIONS=2\0\0"); if (ret != FALSE) { printf("ok 2 hWnd and not enough info\n"); - ret= DsnFunc(NULL, ODBC_ADD_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0OPTIONS=2\0\0"); + ret= DsnFunc(NULL, ODBC_ADD_DSN, driver, "DSN=dsn_test\0OPTIONS=2\0\0"); printf("%s 3 Null hWnd trying to add existing dsn \n", ret ? "not ok" : "ok"); - ret= DsnFunc(NULL, ODBC_CONFIG_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); + ret= DsnFunc(NULL, ODBC_CONFIG_DSN, driver, "DSN=dsn_test\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); printf("%s 4 Null hWnd trying to config with insufficient data \n", ret ? "not ok" : "ok"); printf("# The dialog asking if you want to overwrite existing DSN is supposed to show up. Please say 'No'. Otherwise please cancel config dialog\n"); - ret= DsnFunc(hWnd, ODBC_ADD_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); + ret= DsnFunc(hWnd, ODBC_ADD_DSN, driver, "DSN=dsn_test\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); printf("%s 5 Replace Prompt \n", ret ? "not ok" : "ok"); - ret= DsnFunc(NULL, ODBC_CONFIG_DSN, getenv("TEST_DRIVER"), "DSN=inexistent_dsn\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); + ret= DsnFunc(NULL, ODBC_CONFIG_DSN, driver, "DSN=inexistent_dsn\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); printf("%s 6 Null hWnd trying to config inexisting DSN\n", ret ? "not ok" : "ok"); - ret= DsnFunc(NULL, ODBC_CONFIG_DSN, getenv("TEST_DRIVER"), "DSN=inexistent_dsn\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); + ret= DsnFunc(NULL, ODBC_CONFIG_DSN, driver, "DSN=inexistent_dsn\0UID=garbage\0PWD=DoubleGarbage\0OPTIONS=2\0\0"); printf("%s 7 hWnd trying to config inexisting DSN\n", ret ? "not ok" : "ok"); - ret= DsnFunc(NULL, ODBC_CONFIG_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0OPTIONS=0\0\0"); + ret= DsnFunc(NULL, ODBC_CONFIG_DSN, driver, "DSN=dsn_test\0OPTIONS=0\0\0"); printf("%s 8 Null hWnd config with sufficient data \n", ret ? "ok" : "not ok"); printf("# Please make sure that in dialog Named pipe is selected, and all options are un-checked\n"); - ret= DsnFunc(hWnd, ODBC_CONFIG_DSN, getenv("TEST_DRIVER"), "DSN=dsn_test\0NamedPipe=1\0\0"); + ret= DsnFunc(hWnd, ODBC_CONFIG_DSN, driver, "DSN=dsn_test\0NamedPipe=1\0\0"); printf("%s 9 hWnd config with sufficient data \n", ret ? "ok" : "not ok"); } else @@ -96,5 +107,5 @@ int main() FreeLibrary(hmod); } - return 1; + return 0; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f280b290..dea85c0a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,7 +63,7 @@ FOREACH (ODBC_TEST ${ODBC_TESTS}) ENDIF() IF (NOT ${ODBC_TEST} STREQUAL "interactive" OR USE_INTERACTIVE_TESTS) ADD_TEST(odbc_${ODBC_TEST} ${EXECUTABLE_OUTPUT_PATH}/odbc_${ODBC_TEST}) - SET_TESTS_PROPERTIES(odbc_${ODBC_TEST} PROPERTIES TIMEOUT 120) + SET_TESTS_PROPERTIES(odbc_${ODBC_TEST} PROPERTIES TIMEOUT 600) ENDIF() ENDFOREACH() diff --git a/test/interactive.c b/test/interactive.c index a82bd527..5ace66c0 100644 --- a/test/interactive.c +++ b/test/interactive.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. - 2016 MariaDB Corporation AB + 2016, 2021 MariaDB Corporation AB The MySQL Connector/ODBC is licensed under the terms of the GPLv2 , like most @@ -27,6 +27,57 @@ HWND hWnd; +/* {{{ ltrim + copied from ma_common.c +*/ +char* ltrim(char* Str) +{ + /* I am not sure using iswspace, and not isspace makes any sense here. But probably does not hurt either */ + while (Str && iswspace(Str[0])) + ++Str; + return Str; +} +/* }}} */ +/* Connstr has to be null-terminated - copied from config dialog(odbc_dsn) */ +char* HidePwd(char* ConnStr) +{ + char* Ptr = ConnStr; + + while (*Ptr) + { + BOOL IsPwd = FALSE; + char* KeyValBorder = strchr(Ptr, '='); + char StopChr = ';'; + + Ptr = ltrim(Ptr); + + if (_strnicmp(Ptr, "PWD", 3) == 0 || _strnicmp(Ptr, "PASSWORD", 8) == 0) + { + IsPwd = TRUE; + } + if (KeyValBorder != NULL) + { + Ptr = ltrim(KeyValBorder + 1); + } + if (*Ptr == '{') + { + StopChr = '}'; + } + while (*Ptr && *Ptr != StopChr) + { + if (IsPwd) + { + *Ptr = '*'; + } + ++Ptr; + } + ++Ptr; + } + + return ConnStr; +} + + /* Test of NO_PROMPT option. Normally it is not interactive. Dialog appearance means test failure */ ODBC_TEST(ti_bug30840) { @@ -40,6 +91,7 @@ ODBC_TEST(ti_bug30840) CHECK_ENV_RC(Env, SQLAllocHandle(SQL_HANDLE_DBC, Env, &hdbc1)); /* NO_PROMPT is supposed to supress dialog invocation, and connect should fail */ + diag("You are supposed *not* to see config dialog in this test."); EXPECT_DBC(hdbc1, SQLDriverConnect(hdbc1, NULL, conn, (SQLSMALLINT)strlen(conn), conn_out, (SQLSMALLINT)sizeof(conn_out), &conn_out_len, SQL_DRIVER_COMPLETE_REQUIRED), SQL_ERROR); @@ -59,7 +111,7 @@ ODBC_TEST(ti_dialogs) SQLCHAR conna[512], conna_out[1024]; /* Testing how driver's doing if no out string given. ODBC-17 */ - sprintf((char*)conna, "DRIVER=%s;TCPIP=1;SERVER=%s%s", my_drivername, my_servername, ma_strport); + sprintf((char*)conna, "DRIVER=%s;TCPIP=1;SERVER=%s;%s", my_drivername, my_servername, ma_strport); CHECK_ENV_RC(Env, SQLAllocHandle(SQL_HANDLE_DBC, Env, &hdbc1)); CHECK_DBC_RC(hdbc1, SQLDriverConnect(hdbc1, hWnd, conna, SQL_NTS, NULL, @@ -72,7 +124,7 @@ ODBC_TEST(ti_dialogs) CHECK_DBC_RC(hdbc1, SQLDriverConnect(hdbc1, hWnd, conna, SQL_NTS, conna_out, sizeof(conna_out), &conn_out_len, SQL_DRIVER_PROMPT)); - diag("In %d OutString %s(%d)", strlen(conna), hide_pwd(conna_out), conn_out_len); + diag("In %d OutString %s(%d)", strlen(conna), HidePwd(conna_out), conn_out_len); /* We can't say much about the out string length, but it supposed to be bigger, than of the in string */ FAIL_IF((size_t)conn_out_len <= strlen(conna), "OutString length is too short"); @@ -81,7 +133,7 @@ ODBC_TEST(ti_dialogs) CHECK_DBC_RC(hdbc1, SQLDriverConnect(hdbc1, hWnd, conna, SQL_NTS, conna_out, sizeof(conna_out), &conn_out_len, SQL_DRIVER_COMPLETE)); - diag("In %d OutString %s(%d)", strlen(conna), hide_pwd(conna_out), conn_out_len); + diag("In %d OutString %s(%d)", strlen(conna), HidePwd(conna_out), conn_out_len); FAIL_IF((size_t)conn_out_len <= strlen(conna), "OutString length is too short"); CHECK_DBC_RC(hdbc1, SQLDisconnect(hdbc1));