[Mono-dev] Odbc and varchar - patch for varchars longer than 255

Mads Bondo Dydensborg mbd at dbc.dk
Tue Jun 19 06:23:32 EDT 2007


Hi there.

I have had problems with strings containing binary 0, when retrieved through 
the mono stack. Looking at OdbcDataReader, there seems to be a difference 
between how GetBytes and GetValue( "varchar" ) works. 

GetBytes has this:

10                         if (copyBuffer) {
    311                                 int i = 0;
    312                                 while (tbuff [i] != libodbc.C_NULL) {
    313                                         buffer [bufferIndex + i] = 
tbuff [i];
    314                                         i++;
    315                                 }
    316                                 returnVal = i;
    317                         }
    318                         return returnVal;
    31

Whereas GetValue has this (sorry about the formatting):

 696                                 case OdbcType.VarChar:
    697                                         bufsize = (col.MaxLength < 
255 ? (col.MaxLength+1) : 255);
    698                                         buffer = new 
byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and 
varchar
    699                                         StringBuilder sb1 = new 
StringBuilder ();
    700                                         do {
    701                                                 ret = 
libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref 
outsize);
    702                                                 if (ret == 
OdbcReturn.Error)
    703                                                         break;
    704                                                 if (ret != 
OdbcReturn.NoData && outsize!=-1) {
    705                                                         if (outsize < 
bufsize)
    706                                                                 
sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,outsize));
    707                                                         else
    708                                                                 
sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,bufsize));
    709                                                 }
    710                                         } while (ret != 
OdbcReturn.NoData);
    711                                         DataValue = sb1.ToString ();
    712                                         break;

According to 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlgetdata.asp
"It is up to the application to reassemble the parts, taking care to remove 
the null-termination character from intermediate parts of character data. "

This patch fixes my problem:

Index: OdbcDataReader.cs
===================================================================
--- OdbcDataReader.cs   (revision 80063)
+++ OdbcDataReader.cs   (working copy)
@@ -705,7 +705,7 @@
                                                        if (outsize < bufsize)
                                                                sb1.Append 
(System.Text.Encoding.Default.GetString(buffer,0,outsize));
                                                        else
-                                                               sb1.Append 
(System.Text.Encoding.Default.GetString(buffer,0,bufsize));
+                                                               sb1.Append 
(System.Text.Encoding.Default.GetString(buffer,0,bufsize-1));
                                                }
                                        } while (ret != OdbcReturn.NoData);
                                        DataValue = sb1.ToString ();

It assumes any fragment, with more data, always contains a binary zero on the 
last position. This may or may not be the case - some Odbc expert should 
probably look at it. There could be a problem with NVarchar also.

Regards,

Mads

-- 
Med venlig hilsen/Regards

Systemudvikler/Systemsdeveloper cand.scient.dat, Ph.d., Mads Bondo Dydensborg
Dansk BiblioteksCenter A/S, Tempovej 7-11, 2750 Ballerup, Tlf. +45 44 86 77 34




More information about the Mono-devel-list mailing list