[freetds] SQLGetData (bug in ODBC driver)

Suren A. Chilingaryan csa at dside.dyndns.org
Tue Jun 10 05:54:21 EDT 2008


Dear developers,

FreeTDS 0.82 ODBC driver is corrupting data if SQLGetData is called
multiple times on a single column and if the data conversion have been
involved.

The actual problem is about tracking current position in the column
data. The 'SQLGetData' function (from src/odbc/odbc.c) using
colinfo->column_text_sqlgetdatapos variable to store information about
current position within the column data. Unfortunately, there is a mess
about of positioning with internal/converted data buffers. To move
'column_text_sqlgetdatapos' pointer, the number of readed bytes in
output(converted) buffer is used:
        colinfo->column_text_sqlgetdatapos += readed;
However, afterwards this information is just used (without any
processing) to adjust position in the source(internal) buffer.
	src += readed;

It is OK if  there is only byte-to-byte conversion is involved. In other
case the data corruption will occur. The most important case is data
corruption while accessing binary data (SYBBINARY, SYBIMAGE) in the
character form (SQL_C_CHAR). In this case to a single byte in the
internal binary buffer correspond two bytes (hex characters, like FF) in
the converted/output buffer.

This conversion is done by PHP's PDO/ODBC driver (and plain ODBC driver
as well, I suppose). Therefore, it is now not possible to access a
binary data over 256 bytes from PhP using FreeTDS driver. Which makes a
bug being of a highest priority from my point of view.

I wrote a small patch fixing that behavior for
 a) The described BINARY to CHAR conversion (tested and fixes problems
with PHP for me)
 b) CHAR (SYBVARCHAR, SYBTEXT, ...) to binary (SQL_C_BINARY) conversion
(not tested).

The patch is available at:
http://dside.dyndns.org/projects/patches.dir/freetds-ds-odbc.patch


best regards,
Suren



More information about the FreeTDS mailing list