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)
*/
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) */