Bug #58796 SQLConfigDataSource not accepting null delimeter in attribute list in Unicode
Submitted: 7 Dec 2010 18:50 Modified: 17 Dec 2010 7:13
Reporter: Björn Hammarberg Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:5.1.8 OS:Any
Assigned to: CPU Architecture:Any
Tags: attributes, Contribution, ds_from_kvpair, DSN, key-value pairs, Unicode

[7 Dec 2010 18:50] Björn Hammarberg
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)

*/
[17 Dec 2010 7:13] Tonci Grgin
Hello Bjorn and thanks for your report.

This is actually a duplicate of verified bug report Bug#41796. I will escalate it now.