Skip to Content.
Sympa Menu

freetds - Re: dbdata() broken? alignment error, overflow, Returns length+data, not just data.

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Brian Bruns <camber AT ais.org>
  • To: TDS Development Group <freetds AT franklin.oit.unc.edu>
  • Subject: Re: dbdata() broken? alignment error, overflow, Returns length+data, not just data.
  • Date: Sat, 9 Sep 2000 08:46:51 -0400 (EDT)




On Fri, 8 Sep 2000, Dennis Nicklaus wrote:

> Does anyone else use freetds's dbdata() function?
> How about with SYBVARBINARY data?
>
dbdata generally works but SYBVARBINARY is apparently broken. Let me look
at the docs and see what it should do.

> I don't believe it functions correctly, at least with SYBVARBINARY.
>
> My understanding of dbdata is that it is supposed to return the buffer
> full of data that is read for the column. However, for SYBVARBINARY,
> it returns a (TDS_VARBINARY *), that is a pointer to a structure having its
> first 4
> bytes as the length of data, followed by the data of that length.
> >From other applications written by colleagues, I don't think that is
> correct. See the function tds_process_row() in src/tds/token.c, the lines:
>
> } else if (curcol->column_type == SYBVARBINARY) {
> varbin = (TDS_VARBINARY *)
> &(info->current_row[curcol->column_offset]);
> varbin->len = colsize;
> tds_get_n(tds,varbin->array,colsize);
>
> which are processed during the dbnextrow() call.
> That, coupled with the src/dblib/dblib.c function dbdata which has this
> line:
> return &resinfo->current_row[colinfo->column_offset];
>
>
> Also, can someone explain the use of colinfo->column_offset here.
> It gets set to 1 with my SYBVARBINARY data. And I think that may be a
> mistake.
> All that seems to do is to cause some alignment run-time errors,
> (which crashes the program under Sun-solaris).
> In particular, the assignment above:
> varbin->len = colsize;
> crashes because varbin->len isn't word aligned, it is offset by
> that column_offset=1.
>
curcol->column_offset is the offset in the row buffer to the current
column. It will start at (cols / 8) to store null indicator bits. Again
this appears to be a problem with only the SYBVARBINARY and Sparc
architecture. I had thought we had caught all of those. Although looking
at mem.c (line 97) it should be working. Are you using 0.50 or the CVS
version?

> In this SYBVARBINARY case, my
> res_info->row_size
> gets set to 1 in tds_alloc_results() from tds/mem.c during the dbresults()
> processing.
> My actual data rows have size: curcol->column_size=128 (from
> tds_process_col_info()).
>
> So tracing through tds_process_col_info() with SYBVARBINARY data, it
> will execute:
> curcol->column_offset = info->row_size;
> info->row_size += curcol->column_size + 1;
> so column_offset get set to 1 (old value of row_size),
> and then info->row_size gets increased to 130.
> Then, finally, since I have configured for tds 4.2, I execute:
> remainder = info->row_size % align;
> if (remainder)
> info->row_size += (align - remainder);
> which increases row_size to 132. Then it calls tds_alloc_row()
> which will malloc 132 bytes.
> Now, when we call dbnextrow, look again at the code with the "varbin"
> variable
> in tds_process_row(). If I really have 128 bytes of data in this row, it
> is going to overflow the malloced area.
>
space in the row buffer is allocated fro the maximum size, if you have
varchar(255) and the data is 1 byte long you get 255 reserved in the row
buffer.

> So, the big question I have: Why is column_offset being set to 1 here?
> Should it be? I don't have any idea what column_offset is for, so I don't
> feel good about fixing it one way or the other.
>
Again, NULL indicators are packed at the begining of the row buffer.

> Thanks!
> Dennis Nicklaus nicklaus AT fnal.gov
>





Archive powered by MHonArc 2.6.24.

Top of Page