Skip to Content.
Sympa Menu

freetds - RE: Losing last character of TEXT fields

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Lowden, James K" <LowdenJK AT bernstein.com>
  • To: "'TDS Development Group'" <freetds AT franklin.metalab.unc.edu>
  • Subject: RE: Losing last character of TEXT fields
  • Date: Tue, 9 Jul 2002 14:33:49 -0400


> Errr.. I think you may be right. I changed my code to now read:
>
> case SYBTEXT:
> case SYBCHAR:
> cplen = srclen > destlen ? destlen : srclen;
> memcpy(dest, src, cplen);
> return cplen;
> case SYBBINARY:
> cplen = srclen > destlen ? destlen : srclen;
> memcpy(dest, src, cplen);
> return cplen;
>
> and it seems to work fine. So perhaps the real question is,
> why were we ever fooling around with \0 termination in the first place?

For someone who doesn't "understand the deeper issues", you're sure moving
this along. ;)

Thing is, destlen can be negative, and if it is -- and desttype is SYBCHAR
-- we null terminate:

<MS doc>
destlen

Is the length, in bytes, of the destination variable. This length is used
for the following desttype data type tokens:
SQLCHAR, SQLVARCHAR, SQLTEXT
SQLBINARY, SQLVARBINARY, SQLIMAGE
SQLINTN, SQLFLTN, SQLMONEYN, SQLDATETIMN

The destlen is ignored for all fixed-length, non-NULL data types.

When dest points to a DBCHAR string or a DBBINARY array, the value of
destlen must be the total length of the destination buffer space, or -1 to
indicate that there is sufficient space available. Note that when dest
points to a DBCHAR string, a destlen of -1 causes the character string to be
given a terminating null.
</doc>

I think this would work better:

if (destlen > 0) memset (dest, ' ', destlen); // see below

case SYBCHAR:
if (destlen == -1) {
memcpy(dest, src, srclen);
dest[srclen++] = '\0';
return srclen;
}
/* else fall through */
case SYBTEXT:
case SYBBINARY:
cplen = srclen < destlen ? srclen : destlen;
memcpy(dest, src, cplen);
return cplen;

I think reversing the sense aids clarity, but I wouldn't insist.) Wanna
give that a go?

That would penalize someone who passed a destlen < -1 (because cplen would
be interpreted as an enormous unsigned integer). We could say "if (destlen
< 0)", but that would reward them. <shrug>

I just read Michael's message. I think the ct-lib decisions need to be made
in ct-lib, and a destination length set accordingly when calling
tds_convert. That would be the case with dbbind() as well. By initializing
the buffer to blanks, returning the true length, and null terminating only
when necessary, I think we address all permutations.

Who knew 10 lines could be so worked over?

--jkl




Archive powered by MHonArc 2.6.24.

Top of Page