[unixODBC-dev] Bug ? SQLGetDiagFieldW() assume buffer lengths in SQLWCHAR instead of bytes

Marc Herbert Marc.Herbert at continuent.com
Fri Jan 13 17:50:57 GMT 2006


According to article ID 294169 from Microsoft
 <http://support.microsoft.com/default.aspx?scid=kb;EN-US;q294169>
SQLGetDiagFieldW() should always assume sizes are in bytes. The
rationale goes like this: "some returned values are strings, but other
are not, so let's standardize on bytes." Check the article for more.

I think I spotted a bug where unixodbc assumes some sizes are in SQLW
characters instead of bytes, see attached patch to see where is
located the issue.

The bug is by chance not very harmful: it ends up _under_estimating
the size of the buffer given by the user, and returning a size twice
too big.

This patch is untested, consider it as a pointer to the relevant part
of the code and a suggestion only.

This bug probably occurs at other similar places.


Index: SQLGetDiagField.c
===================================================================
RCS file: /cvsroot/unixodbc/unixODBC/DriverManager/SQLGetDiagField.c,v
retrieving revision 1.9
diff -u -r1.9 SQLGetDiagField.c
--- SQLGetDiagField.c	19 Dec 2005 18:43:26 -0000	1.9
+++ SQLGetDiagField.c	13 Jan 2006 17:44:13 -0000
@@ -467,10 +467,12 @@
         {
             SQLRETURN ret;
             SQLWCHAR *s1 = NULL;
+            // UNTESTED
+	    SQLSMALLINT res_size, s1_size = sizeof( SQLWCHAR ) * buffer_length;
 
             if ( buffer_length > 0 )
             {
-                s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ));
+                s1 = malloc( s1_size );
             }
 
             ret = SQLGETDIAGFIELDW( __get_connection( head ),
@@ -479,12 +481,14 @@
                     rec_number,
                     diag_identifier,
                     s1 ? s1 : diag_info_ptr,
-                    buffer_length,
-                    string_length_ptr );
+                    s1_size,
+                    &res_size );
 
             if ( SQL_SUCCEEDED( ret ) && s1 && diag_info_ptr )
             {
                 unicode_to_ansi_copy( diag_info_ptr, s1, SQL_NTS, __get_connection( head ));
+                // the ansi-converted string is less long in bytes!
+                *string_length_ptr = res_size / sizeof(SQLWCHAR);
             }
 
             if ( s1 )





More information about the unixODBC-dev mailing list