| Bug #16300 | inserting with bind values makes assumptions about long size | ||
|---|---|---|---|
| Submitted: | 9 Jan 2006 13:12 | Modified: | 8 Mar 2007 1:31 |
| Reporter: | tom hindle | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | Connector / ODBC | Severity: | S2 (Serious) |
| Version: | 3.51.12 | OS: | IBM AIX (aix 5.2 64bit) |
| Assigned to: | CPU Architecture: | Any | |
[27 Jul 2006 11:30]
tom hindle
Futher to my previous comments:
A better change would be (if you want to be able to deal with 8 bits long's)
length=int2str(getlong(data,cbValueMax),buff,-10,0) - buff;
where getlong defined as:
#define BITS 8
long getlong(void * data,int size) {
long val=0;
unsigned char * cptr=(char *)ptr;
int i= size>sizeof(long)?sizeof(long):size;
for (i=size-1;i>=0;i--) {
val += (cptr[i] << (size-(size-i))*BITS);
}
return(val);
}
[28 Aug 2006 20:42]
Sveta Smirnova
test case to recreate the error
Attachment: bug16300.c (text/x-csrc), 1.64 KiB.
[28 Aug 2006 20:46]
Sveta Smirnova
Thank you for the report. Verified as described on SuSe Linux using attached test case: ssmirnova@sles9-ia64:~> ./bug16300 Connecting to 'myodbc3' with user name 'root'... bug16300(11692): unaligned access to 0x60000fffffffadec, ip=0x2000000000062bd0
[8 Mar 2007 1:31]
Jim Winstead
cbValueMax should be ignored, as you can't specify the size of a SQL_C_LONG (it's always an SQLINTEGER).

Description: inserting with bind values makes assumptions about long size On a 64bit systems the long int type is 8 bytes. SQLBindParameter has previous been called with a cbValueMax value of 4 and type of SQL_C_SLONG, it corretly stores this value in param However in driver/execute.c about line 375: case SQL_C_SLONG length=int2str(*(long int *)data),buff,-10,0) -buff; this cbValueMax is ignored, and the assumption made that SQL_C_SLONG is sizeof(long) which happens to work on 32bit systems. How to repeat: Here is a trace of what my testcase did. Just do this on a 64 bit system then select the inserted values too see the error. Application 00000000 EXIT SQLBindParameter with return code 0 (SQL_SUCCESS) SQLHSTMT 1100899f0 SQLSMALLINT 1 SQLSMALLINT 1 (SQL_PARAM_INPUT) SQLSMALLINT -16 (SQL_C_SLONG) SQLSMALLINT 4 (SQL_INTEGER) SQLUINTEGER 4 SQLSMALLINT 0 SQLPOINTER ffffffffffffd2c SQLINTEGER 4 SQLPOINTER 110089878 Application 00000000 ENTER SQLBindParameter SQLHSTMT 1100899f0 SQLSMALLINT 2 SQLSMALLINT 1 (SQL_PARAM_INPUT) SQLSMALLINT -16 (SQL_C_SLONG) SQLSMALLINT 4 (SQL_INTEGER) SQLUINTEGER 4 SQLSMALLINT 0 SQLPOINTER ffffffffffffd2c SQLINTEGER 4 SQLPOINTER 1100898a0 Application 00000000 EXIT SQLBindParameter with return code 0 (SQL_SUCCESS) SQLHSTMT 1100899f0 SQLSMALLINT 2 SQLSMALLINT 1 (SQL_PARAM_INPUT) SQLSMALLINT -16 (SQL_C_SLONG) SQLSMALLINT 4 (SQL_INTEGER) SQLUINTEGER 4 SQLSMALLINT 0 SQLPOINTER ffffffffffffd2c SQLINTEGER 4 SQLPOINTER 1100898a0 Application 00000000 ENTER SQLSetStmtOption SQLHSTMT 1100899f0 SQLUSMALLINT 0 (SQL_QUERY_TIMEOUT) SQLUINTEGER 0 Application 00000000 EXIT SQLSetStmtOption with return code 0 (SQL_SUCCESS) SQLHSTMT 1100899f0 SQLUSMALLINT 0 (SQL_QUERY_TIMEOUT) SQLUINTEGER 0 Application 00000000 ENTER SQLExecDirect SQLHSTMT 1100899f0 SQLCHAR * 11008b860 | INSERT INTO integer1 (a , b ) VALUES ( | | ? , ? ) | SQLINTEGER 51 Application 00000000 EXIT SQLExecDirect with return code 0 (SQL_SUCCESS) SQLHSTMT 1100899f0 SQLCHAR * 11008b860 SQLINTEGER 51 Suggested fix: I changed: length=int2str(*(long int *)data),buff,-10,0) -buff; to: length=int2str(*(int *)data),buff,-10,0) -buff; which works for me but not the best way to fix this. really need to check cbValueMax when ever conversions are done between Integer types and strings.