Discussion:
[freetds] SQLPutData() with a size of zero
Sebastien FLAESCH
2013-03-11 15:36:52 UTC
Permalink
Hello,

I believe I found a defect (0.92.377): with SQL_DATA_AT_EXEC binding, when a
blob is empty but not null, it should be possible to call SQLPutData() with
a size of zero:

r = SQLPutData(st->stmtHandle, (SQLPOINTER) "", 0L);

This is working with SQL Native Client and Easysoft ODBC for SQL Server...

But FreeTDS returns:

HY001 / [FreeTDS][SQL Server]Memory allocation failure

...

It appears that the code in prepare_query.c:continue_parse_prepared_query()
is not prepared to get a StrLen_or_Ind of zero...

In fact we end up in this part, with len=0:

if (blob->textvalue)
p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);
else {
assert(curcol->column_cur_size == 0);
p = (TDS_CHAR *) malloc(len);
}
if (!p) {
odbc_errs_add(&stmt->errs, "HY001", NULL); /* Memory allocation error */
return SQL_ERROR;
}


and here malloc(0) returns zero (AIX 6.1)...

Seb
James K. Lowden
2013-03-11 16:51:33 UTC
Permalink
On Mon, 11 Mar 2013 16:36:52 +0100
Post by Sebastien FLAESCH
p = (TDS_CHAR *) malloc(len);
}
if (!p) {
odbc_errs_add(&stmt->errs, "HY001",
NULL); /* Memory allocation error */ return SQL_ERROR;
}
and here malloc(0) returns zero (AIX 6.1)...
http://publib.boulder.ibm.com/infocenter/pseries/v5r3/topic/com.ibm.aix.basetechref/doc/basetrf1/malloc.htm#malloc

http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html

Huh. Learn something new every day. I thought malloc could return
NULL only for failure. But the standard says,

"If size is 0, either a null pointer or a unique pointer that
can be successfully passed to free() shall be returned. "

It looks like you want _LINUX_SOURCE_COMPAT. Either that, or change
the test to

if( len && !p )

While you're at it, you can remove the casts to to malloc. We got rid
of them once, but they keep regenerating.

Thanks for pointing this out, no pun intended.

--jkl
Sebastien FLAESCH
2013-04-09 10:23:07 UTC
Permalink
Version 0.92.556 seems to fix this problem.
Thank you Frediano.
Seb
Post by James K. Lowden
On Mon, 11 Mar 2013 16:36:52 +0100
Post by Sebastien FLAESCH
p = (TDS_CHAR *) malloc(len);
}
if (!p) {
odbc_errs_add(&stmt->errs, "HY001",
NULL); /* Memory allocation error */ return SQL_ERROR;
}
and here malloc(0) returns zero (AIX 6.1)...
http://publib.boulder.ibm.com/infocenter/pseries/v5r3/topic/com.ibm.aix.basetechref/doc/basetrf1/malloc.htm#malloc
http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
Huh. Learn something new every day. I thought malloc could return
NULL only for failure. But the standard says,
"If size is 0, either a null pointer or a unique pointer that
can be successfully passed to free() shall be returned. "
It looks like you want _LINUX_SOURCE_COMPAT. Either that, or change
the test to
if( len&& !p )
While you're at it, you can remove the casts to to malloc. We got rid
of them once, but they keep regenerating.
Thanks for pointing this out, no pun intended.
--jkl
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
Loading...