Bug #16259 SQLGetData, SQLBindCol, SQLBindParameter make assumptions about buffer sizes
Submitted: 6 Jan 2006 18:01 Modified: 8 Mar 2007 1:30
Reporter: tom hindle Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:3.51.12 OS:IBM AIX (AIX 5.2, 64-bit)
Assigned to: CPU Architecture:Any

[6 Jan 2006 18:01] tom hindle
Description:
When binding SQL_C_SLONG (and other integer types), the SQLGetData(), SQLBindCol and SQLBindParameter routines blanketly ignore the buffer length argument.

Each assumes that the data pointer is to a long host variable which isn't strictly the case according to the ODBC spec (and certainly how the system I'm working on uses the ODBC interface). For example, if I pass a pointer to an integer, the cast (from driver/results.c): 

  *(long *)rgbValue = (long)atol(value)

is extremely dangerous. Particularly on 64-bit systems where the size of integer and long are not consistent. This happens to walk all over memory. It is essential to pay attention to the buffer size indicator if there is any possibility of variance in the input type.

How to repeat:
 Just a simple call such as: 

  int i, count;

  SQLGetData(some_stmt_handle,1,SQL_C_SLONG,&i,sizeof(int),&count);
[18 Jul 2006 7:41] Sveta Smirnova
test case

Attachment: bug16259.c (text/plain), 1.69 KiB.

[18 Jul 2006 7:49] Sveta Smirnova
I can not raise error using test case attached to the bug. Please, look into it and if it is not correct, provide correct test case. Thank you.
[18 Jul 2006 8:56] tom hindle
The testcase will only demonstrate a problem if sizeof(int)!=sizeof(long)

Which is the case on (at least) some 64bit systems.

Your test case needs to be run on a 64bit system, where long and int sizes differ.
[18 Jul 2006 9:17] Sveta Smirnova
But it runs on 64-bit system without problems. So I steel need test case from you.
[18 Jul 2006 9:43] tom hindle
testcase showing basic problem.

Attachment: main64bittest.c (text/x-csrc), 520 bytes.

[18 Jul 2006 9:46] tom hindle
Modifyied your testcase to try and show the problem

Attachment: bug16259.c (text/x-csrc), 1.75 KiB.

[24 Jul 2006 12:38] tom hindle
Just to confirm (as status is still Need Feedback) testcases have been attached.
[24 Jul 2006 18:13] Sveta Smirnova
Thank you for the reminder and test cases. I am working for the problem.
[24 Jul 2006 20:14] Sveta Smirnova
Verified on 64-bit Linux using test provided by reporter:

 Connecting to 'myodbc3' with user name 'root'...
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
1
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
2
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
3
j should be 500 j == 500
bug16259_2(5431): unaligned access to 0x60000fffffffae0c, ip=0x200000000006a731
4
j should be 500 j == 500
5
j should be 500 j == 500
6
j should be 500 j == 500
7
j should be 500 j == 500
[13 Feb 2007 1:45] Jim Winstead
The BufferLength parameter should be ignored when handling fixed size data. Here's a quote from the SQLGetData() documentation from MSDN:

 When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the buffer is large enough to hold the data. It is therefore important for the application to allocate a large enough buffer for fixed-length data or the driver will write past the end of the buffer.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlgetdata.a...

SQLBindCol() and SQLBindParameter() have similar text. IBM's DB/2 ODBC documentation also indicates that BufferLength is ignored for fixed-length data.

This isn't to say there have not been problems in this area with C/ODBC 3.51. Until recently (and possibly still), it often assumed that the argument of type SQL_C_LONG was actually of the C long type, but it should have been SQLINTEGER (which may or may not be a C long).