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

Mads Bondo Dydensborg mbd at dbc.dk
Wed Jun 20 02:40:47 EDT 2007


tirsdag 19 juni 2007 13:26 skrev A Nagappan:
> Hi,
>   Can you provide a sample test-case ?

Hi again. Please find attached a test case.

This is tested against a Sybase ASA 9.0.2 - but I believe other DB's using 
Odbc should/will give the same behaviour. When running the program, the 
following output is  produced:

$ mono --debug ZeroBug.exe
readAsString:
Looking for binary zero in string 'This string has more than 255 
charactersThis string has more than 255 charactersThis string has more than 
255 charactersThis string has more than 255 charactersThis string has more 
than 255 charactersThis string has more than 255 charactersThis string has 
more than 255 charactersThis string has more than 255 charactersThis string 
has more than 255 charactersThis string has more than 255 charactersThis 
string has more than 255 charactersThis string has more than 255 
charactersThis string has more than 255 charactersThis string has more than 
255 charactersThis string has more than 255 charactersThis string has more 
than 255 charactersThis string has more than 255 charactersThis string has 
more than 255 charactersThis string has more than 255 charactersThis string 
has more than 255 charactersThis string has more than 255 charactersThis 
string has more than 255 charactersThis string has more than 255 
charactersThis string has more than 255 characters'
Found binary zero at pos 254
Found binary zero at pos 509
Found binary zero at pos 764
readAsBytes:
Looking for binary zero in string 'This string has more than 255 
charactersThis string has more than 255 charactersThis string has more than 
255 charactersThis string has more than 255 charactersThis string has more 
than 255 charactersThis string has more than 255 charactersThis string has 
more than 255 charactersThis string has more than 255 charactersThis string 
has more than 255 charactersThis string has more than 255 charactersThis 
string has more than 255 charactersThis string has more than 255 
charactersThis string has more than 255 charactersThis string has more than 
255 charactersThis string has more than 255 charactersThis string has more 
than 255 charactersThis string has more than 255 charactersThis string has 
more than 255 charactersThis string has more than 255 charactersThis string 
has more than 255 charactersThis string has more than 255 charactersThis 
string has more than 255 charactersThis string has more than 255 
charactersThis string has more than 255 characters'

The pattern is, that for each 255 characters, a binary zero is inserted. Not 
good. :-)

when applying this patch (sorry for the formatting, only '-1' is added)

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 ();

no binary zeros are found.

There may be issues for NVarchar too.

Regards, 

> 
> Thanks
> Nagappan
> 
> 
> --
> Nagappan A <anagappan at novell.com>
> Linux Desktop Testing Project - http://ldtp.freedesktop.org
> http://nagappanal.blogspot.com
> 
> Novell, Inc.
> SUSE* Linux Enterprise 10
> Your Linux is ready*
> http://www.novell.com/linux
> 
> 
> 
> 
> >>> On Tue, Jun 19, 2007 at  3:53 PM, in message
> <200706191223.32378.mbd at dbc.dk>,
> Mads Bondo Dydensborg <mbd at dbc.dk> wrote: 
> > 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/odb
> > csqlgetdata.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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ZeroBug.cs
Type: text/x-java
Size: 3953 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070620/46dd0485/attachment.bin 


More information about the Mono-devel-list mailing list