Description:
When trying to create/modify a DSN using SQLConfigDataSource() in combination with Unicode and null-terminated key-value pairs, the given attributes are not read. As a side-effect, the call fails completely unless the DSN is given first.
There are two workarounds:
1. Use semicolon as a delimeter (breaks compatibility I guess)
2. Use the prompt dialog and enter the data manually (scales badly)
How to repeat:
if( !SQLConfigDataSource( NULL, ODBC_CONFIG_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("server=OnlyThisIsRead\0")
_T("DSN=NotReadSoWhoCares\0")
_T("Description=This should not work at all\0")
) )
AfxMessageBox(_T("We failed, but we knew it!"));
if( !SQLConfigDataSource( AfxGetMainWnd()->m_hWnd, ODBC_ADD_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("DSN=A\0")
_T("server=not visible\0")
_T("Description=This is not read by ds_from_kvpair() :-( so you will get prompted\0")
) )
AfxMessageBox(_T("This should not be shown. What went wrong?"));
if( !SQLConfigDataSource( AfxGetMainWnd()->m_hWnd, ODBC_ADD_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("server=You can only see me\0")
_T("DSN=B\0")
_T("Description=Not visible\0")
) )
AfxMessageBox(_T("Unexpected!"));
if( !SQLConfigDataSource( AfxGetMainWnd()->m_hWnd, ODBC_ADD_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("DSN=C;")
_T("server=localhost;")
_T("Description=The sweet taste of success!")
) )
AfxMessageBox(_T("This should not be shown either. What went wrong?"));
if( !SQLConfigDataSource( AfxGetMainWnd()->m_hWnd, ODBC_ADD_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("server=localhost;")
_T("DSN=D;")
_T("Description=The order is no longer important!")
) )
AfxMessageBox(_T("This should not be shown at all. What went wrong?"));
if( !SQLConfigDataSource( NULL, ODBC_ADD_DSN, _T("MySQL ODBC 5.1 Driver"),
_T("server=localhost\0")
_T("DSN=NotReadSoWhoCares\0")
_T("Description=Access violation reading location 0x00000000\0")
) )
AfxMessageBox(_T("We will never reach this!"));
AfxMessageBox(_T("We will never reach this either!"));
/* The crash is in configDSN.c: 153
/* if the name is changed, remove the old dsn */
if (origdsn && memcmp(origdsn, ds->name,
(sqlwcharlen(origdsn) + 1) * sizeof(SQLWCHAR)))
*/
Suggested fix:
/* installer.c:1002-1005 could be altered as below */
/* If delim is NULL then double-NULL is the end of key-value pairs list */
while ((delim && *attrs == delim) || *attrs == ' ')
++attrs;
/* If delim is NULL we need to take one more step */
if (delim == 0 && *attrs == delim)
++attrs;
}
/* end of suggested fix */
/* While at it, the following issues could be wise to fix as well:
* Possible buffer overrun at line 943: (Triggered if key longer than 100 chars
memcpy(attribute, attrs, len * sizeof(SQLWCHAR));
* Possibly unsafe case at line 946-951: (If len == 0)
*/