Description:
If using SQLPrepare/SQLExecute to query sql with address sanitize/valgrind, it will report hep-build-overflow
How to repeat:
compiling the following code with -fsanitize=address, and run
#include <sql.h>
#include <sqlext.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
SQLHENV hEnv;
SQLHDBC hDbc;
SQLHSTMT hStmt;
SQLRETURN ret;
// Allocate environment handle
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
// Allocate connection handle
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
// Connect to the database
SQLConnect(hDbc, (SQLCHAR *)"xxx", SQL_NTS,
(SQLCHAR *)"xxx", SQL_NTS,
(SQLCHAR *)"xxx", SQL_NTS);
// Allocate statement handle
SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
// Execute query
if (SQLPrepare(hStmt, (SQLCHAR *)"SELECT * FROM xxx", SQL_NTS) != SQL_SUCCESS) {
printf("Unable to prepare SQL statement!\n");
return 0;
}
SQLRETURN result = SQLExecute(hStmt);
if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO && result != SQL_NO_DATA) {
printf("execute error!\n");
return 0;
}
// Get the number of columns
SQLSMALLINT numCols;
SQLNumResultCols(hStmt, &numCols);
printf("Number of columns: %d\n", numCols);
int done = 0;
while (!done) {
int name_len = 256;
char **names;
char **vals;
int y = 0;
SQLRETURN result = SQLFetch(hStmt);
if (result != SQL_SUCCESS) {
break;
}
names = calloc(numCols, sizeof(*names));
vals = calloc(numCols, sizeof(*vals));
for (int x = 1; x <= numCols; x++) {
SQLSMALLINT NameLength = 0, DataType = 0, DecimalDigits = 0, Nullable = 0;
SQLULEN ColumnSize = 0;
SQLLEN indicator = 0;
names[y] = malloc(name_len);
memset(names[y], 0, name_len);
SQLRETURN ret = SQLDescribeCol(hStmt, x, (SQLCHAR *)names[y], (SQLSMALLINT)name_len, &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
printf("Column:%d, ret:%d, name: %s, data_type:%d, size:%lu, nullable:%d\n", x, ret, names[y], DataType, ColumnSize, Nullable);
} else {
printf("Failed to describe column:%d, ret:%d\n", x, ret);
}
if (!ColumnSize) {
ColumnSize = 255;
}
ColumnSize++;
vals[y] = malloc(ColumnSize);
memset(vals[y], 0, ColumnSize);
ret = SQLGetData(hStmt, x, SQL_C_CHAR, (SQLCHAR *)vals[y], ColumnSize, &indicator);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
if (indicator == SQL_NULL_DATA) {
printf("Column:%d, ret:%d, name: %s, data_type:%d, size:%lu, nullable:%d\n", x, ret, names[y], DataType, ColumnSize, Nullable);
}
} else {
printf("Failed to retrieve data for column:%d, ret:%d\n", x, ret);
}
y++;
}
done = 1;
for (int x = 0; x < y; x++) {
free(names[x]);
free(vals[x]);
}
free(names);
free(vals);
}
// Cleanup
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
return 0;
}