diff --git a/AUTHORS b/AUTHORS index 3ea8e28..ab4e79c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -33,6 +33,7 @@ Craig A Berry Dave Berry David Brown Dmitriy Yusupov +Donnie Pinkston Emile Heitor Erik Lundqvist Frediano Ziglio @@ -80,7 +81,7 @@ Martin Kittel Martin Lacko Max Khon Michael Koch -Michael Vetter +Michael Vetter Miloslav Marik Mike Schultz Mikko Vierula diff --git a/ChangeLog b/ChangeLog index 0f259c9..1f517a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ * Add --with-stats-ftok-name configure option to allow the selection of a file name used to generate the IPC id when collecting stats. Default is the system odbc.ini file * Improve diag record handling with the behavior of Windows DM and export SQLCancelHandle + * bug fix when SQLGetPrivateProfileString() is called to get a list of sections or a list of keys 19-March-2018 2.3.6 diff --git a/include/odbcinstext.h b/include/odbcinstext.h index a7275c1..3000d3b 100644 --- a/include/odbcinstext.h +++ b/include/odbcinstext.h @@ -337,6 +337,7 @@ void _single_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ); SQLWCHAR* _multi_string_alloc_and_expand( LPCSTR in ); SQLWCHAR* _single_string_alloc_and_expand( LPCSTR in ); void _single_copy_from_wide( SQLCHAR *out, LPCWSTR in, int len ); +int _multi_string_length( LPCSTR in ); /* * To support finding UI plugin diff --git a/odbcinst/SQLCreateDataSource.c b/odbcinst/SQLCreateDataSource.c index fe07b2d..ff80f9e 100644 --- a/odbcinst/SQLCreateDataSource.c +++ b/odbcinst/SQLCreateDataSource.c @@ -180,6 +180,22 @@ void _multi_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) *out++ = 0; } +int _multi_string_length( LPCSTR in ) +{ + LPCSTR ch; + + if ( !in ) + return 0; + + for ( ch = in ; !(*ch == 0 && *(ch + 1) == 0) ; ch ++ ); + + /* The convention seems to be to exclude the very last '\0' character from + * the count, so that is what we do here. + */ + return ch - in + 1; +} + + /*! * \brief Invokes a UI (a wizard) to walk User through creating a DSN. * diff --git a/odbcinst/SQLGetPrivateProfileString.c b/odbcinst/SQLGetPrivateProfileString.c index 035a117..cad08c0 100644 --- a/odbcinst/SQLGetPrivateProfileString.c +++ b/odbcinst/SQLGetPrivateProfileString.c @@ -542,6 +542,11 @@ int SQLGetPrivateProfileString( LPCSTR pszSection, if ( pszSection == NULL ) { _odbcinst_GetSections( hIni, pRetBuffer, nRetBuffer, &nBufPos ); + + if (nBufPos > 0) + ret = _multi_string_length(pRetBuffer); + else + ret = 0; /* Indicate not found */ } /***************************************************** * EXTRACT ENTRIES @@ -549,6 +554,10 @@ int SQLGetPrivateProfileString( LPCSTR pszSection, else if ( pszEntry == NULL ) { _odbcinst_GetEntries( hIni, pszSection, pRetBuffer, nRetBuffer, &nBufPos ); + if (nBufPos > 0) + ret = _multi_string_length(pRetBuffer); + else + ret = 0; /* Indicate not found */ } /***************************************************** * EXTRACT AN ENTRY @@ -577,19 +586,19 @@ int SQLGetPrivateProfileString( LPCSTR pszSection, else { iniValue( hIni, szValue ); - if ( pRetBuffer ) - { - strncpy( pRetBuffer, szValue, nRetBuffer ); - pRetBuffer[ nRetBuffer - 1 ] = '\0'; - } + if ( pRetBuffer ) + { + strncpy( pRetBuffer, szValue, nRetBuffer ); + pRetBuffer[ nRetBuffer - 1 ] = '\0'; + } nBufPos = strlen( szValue ); } + + ret = strlen( pRetBuffer ); } iniClose( hIni ); - ret = strlen( pRetBuffer ); - save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ); return ret; @@ -647,7 +656,10 @@ int INSTAPI SQLGetPrivateProfileStringW( LPCWSTR lpszSection, { if ( buf && lpszRetBuffer ) { - _single_copy_to_wide( lpszRetBuffer, buf, ret + 1 ); + if ( !lpszSection || !lpszEntry ) + _multi_string_copy_to_wide( lpszRetBuffer, buf, ret ); + else + _single_copy_to_wide( lpszRetBuffer, buf, ret ); } }