Skip to Content.
Sympa Menu

freetds - [freetds] [PATCH] Problem with VARCHAR in sybase.

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Eddy Pronk <epronk AT muftor.com>
  • To: freetds AT lists.ibiblio.org
  • Subject: [freetds] [PATCH] Problem with VARCHAR in sybase.
  • Date: Tue, 01 Jul 2008 08:25:28 +1000

I used freetds from Linux to connect to a sybase server on Solaris.

My database had a table with a column which was VARCHAR(20)
One of the rows had exactly 20 characters.
With a simple SELECT it hit this piece of code which returns CS_FAIL
without logging anything:

538 case CS_FMT_NULLTERM:
539 if (src_len == destlen) {
540 ret = CS_FAIL; /* not enough room for
data + a null terminator - error */
541 } else {
542 memcpy(dest, srcdata, src_len);
543 dest[src_len] = '\0';
544 if (resultlen != NULL)
545 *resultlen = src_len + 1;
546 ret = CS_SUCCEED;
547 }
548 break;

and the similar:

765 case CS_FMT_NULLTERM:
766 tdsdump_log(TDS_DBG_FUNC, "cs_convert()
FMT_NULLTERM\n");
767 if (len == destlen) {
768 tdsdump_log(TDS_DBG_FUNC, "not enough room for
data + a null terminator - error\n");
769 ret = CS_FAIL; /* not enough room for data +
a null terminator - error */
770 } else {
771 memcpy(dest, cres.c, len);
772 dest[len] = 0;
773 if (resultlen != NULL)
774 *resultlen = len + 1;
775 ret = CS_SUCCEED;
776 }
777 break;

I included a patch below.
I'm not sure if the data structure which holds the length of the field
needs updating.
If I allocate 1 byte extra for the null terminator my query works.
I tried this with Debian testing.

Eddy


diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
index de6bbda..7fc0595 100644
--- a/src/ctlib/cs.c
+++ b/src/ctlib/cs.c
@@ -389,15 +389,12 @@ CS_RETCODE ret;
switch (destfmt->format) {

case CS_FMT_NULLTERM:
- if (src_len == destlen) {
- ret = CS_FAIL; /* not enough room for data +
a null terminator - error */
- } else {
- memcpy(dest, srcdata, src_len);
- dest[src_len] = '\0';
- if (resultlen != (CS_INT *) NULL)
- *resultlen = src_len + 1;
- ret = CS_SUCCEED;
- }
+ memcpy(dest, srcdata, src_len);
+ /* client code should allocate enough room for data
+ a null terminator */
+ dest[src_len] = '\0';
+ if (resultlen != (CS_INT *) NULL)
+ *resultlen = src_len + 1;
+ ret = CS_SUCCEED;
break;

case CS_FMT_PADBLANK:
@@ -615,16 +612,12 @@ CS_RETCODE ret;

case CS_FMT_NULLTERM:
tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n");
- if (len == destlen) {
- tdsdump_log(TDS_DBG_FUNC, "not enough room for data
+ a null terminator - error\n");
- ret = CS_FAIL; /* not enough room for data + a
null terminator - error */
- } else {
- memcpy(dest, cres.c, len);
- dest[len] = 0;
- if (resultlen != (CS_INT *) NULL)
- *resultlen = len + 1;
- ret = CS_SUCCEED;
- }
+ /* client code should allocate enough room for data + a
null terminator */
+ memcpy(dest, cres.c, len);
+ dest[len] = '\0';
+ if (resultlen != (CS_INT *) NULL)
+ *resultlen = len + 1;
+ ret = CS_SUCCEED;
break;

case CS_FMT_PADBLANK:
--








Archive powered by MHonArc 2.6.24.

Top of Page