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

A Nagappan anagappan at novell.com
Thu Jun 21 06:23:08 EDT 2007


Hi,
  Thanks for the patch and test :) Checked in both the patch and test
in SVN.

Test - Committed revision 80428.
Patch - Committed revision 80429.

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 Wed, Jun 20, 2007 at 12:10 PM, in message
<200706200840.47496.mbd at dbc.dk>,
Mads Bondo Dydensborg <mbd at dbc.dk> wrote: 
> 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
>> 
>> 
>> 
>> 




More information about the Mono-devel-list mailing list