Check column index ranges
Don't write \0 past buffer in column names
Warn if column name trucated
Repport driver version
This commit is contained in:
Nirgal Vourgère
2013-07-07 14:26:08 +02:00
parent b728fc1e45
commit 00a66cc57f

View File

@@ -759,9 +759,11 @@ static SQLRETURN SQL_API _SQLDescribeCol(
MdbSQLColumn *sqlcol; MdbSQLColumn *sqlcol;
MdbColumn *col; MdbColumn *col;
MdbTableDef *table; MdbTableDef *table;
SQLRETURN ret;
TRACE("_SQLDescribeCol"); TRACE("_SQLDescribeCol");
if (icol<1 || icol>sql->num_columns) { if (icol<1 || icol>sql->num_columns) {
strcpy(sqlState, "07009"); // Invalid descriptor index
return SQL_ERROR; return SQL_ERROR;
} }
sqlcol = g_ptr_array_index(sql->columns,icol - 1); sqlcol = g_ptr_array_index(sql->columns,icol - 1);
@@ -774,18 +776,31 @@ static SQLRETURN SQL_API _SQLDescribeCol(
} }
if (i==table->num_cols) { if (i==table->num_cols) {
fprintf(stderr, "Column %s lost\n", (char*)sqlcol->name); fprintf(stderr, "Column %s lost\n", (char*)sqlcol->name);
strcpy(sqlState, "07009"); // Invalid descriptor index
return SQL_ERROR; return SQL_ERROR;
} }
ret = SQL_SUCCESS;
namelen = strlen(sqlcol->name);
if (pcbColName)
*pcbColName=namelen;
if (szColName) { if (szColName) {
namelen = MIN(cbColNameMax,strlen(sqlcol->name)); if (cbColNameMax < 0) {
strncpy((char*)szColName, sqlcol->name, namelen); strcpy(sqlState, "HY090"); // Invalid string or buffer length
szColName[namelen]='\0'; return SQL_ERROR;
if (pcbColName) }
*pcbColName=namelen; if (namelen + 1 < cbColNameMax) {
} else { // Including \0
if (pcbColName) strcpy((char*)szColName, sqlcol->name);
*pcbColName = strlen(sqlcol->name); } else {
if (cbColNameMax > 1) {
strncpy((char*)szColName, sqlcol->name, cbColNameMax-1);
szColName[cbColNameMax-1] = '\0';
}
// So there is no \0 if cbColNameMax was 0
strcpy(sqlState, "01004"); // String data, right truncated
ret = SQL_SUCCESS_WITH_INFO;
}
} }
if (pfSqlType) { if (pfSqlType) {
*pfSqlType = _odbc_get_client_type(col); *pfSqlType = _odbc_get_client_type(col);
@@ -801,7 +816,7 @@ static SQLRETURN SQL_API _SQLDescribeCol(
*pfNullable = !col->is_fixed; *pfNullable = !col->is_fixed;
} }
return SQL_SUCCESS; return ret;
} }
SQLRETURN SQL_API SQLDescribeCol( SQLRETURN SQL_API SQLDescribeCol(
@@ -862,6 +877,7 @@ static SQLRETURN SQL_API _SQLColAttributes(
MdbSQLColumn *sqlcol; MdbSQLColumn *sqlcol;
MdbColumn *col; MdbColumn *col;
MdbTableDef *table; MdbTableDef *table;
SQLRETURN ret;
TRACE("_SQLColAttributes"); TRACE("_SQLColAttributes");
stmt = (struct _hstmt *) hstmt; stmt = (struct _hstmt *) hstmt;
@@ -872,11 +888,14 @@ static SQLRETURN SQL_API _SQLColAttributes(
/* dont check column index for these */ /* dont check column index for these */
switch(fDescType) { switch(fDescType) {
case SQL_COLUMN_COUNT: case SQL_COLUMN_COUNT:
case SQL_DESC_COUNT:
*pfDesc = env->sql->num_columns;
return SQL_SUCCESS; return SQL_SUCCESS;
break; break;
} }
if (icol<1 || icol>sql->num_columns) { if (icol<1 || icol>sql->num_columns) {
strcpy(sqlState, "07009"); // Invalid descriptor index
return SQL_ERROR; return SQL_ERROR;
} }
@@ -890,28 +909,47 @@ static SQLRETURN SQL_API _SQLColAttributes(
} }
} }
if (i==table->num_cols) { if (i==table->num_cols) {
strcpy(sqlState, "07009"); // Invalid descriptor index
return SQL_ERROR; return SQL_ERROR;
} }
// fprintf(stderr,"fDescType = %d\n", fDescType); // fprintf(stderr,"fDescType = %d\n", fDescType);
ret = SQL_SUCCESS;
switch(fDescType) { switch(fDescType) {
case SQL_COLUMN_NAME: case SQL_COLUMN_NAME: case SQL_DESC_NAME:
case SQL_COLUMN_LABEL: case SQL_COLUMN_LABEL: /* = SQL_DESC_LABEL */
namelen = MIN(cbDescMax,strlen(sqlcol->name)); if (cbDescMax < 0) {
strncpy(rgbDesc, sqlcol->name, namelen); strcpy(sqlState, "HY090"); // Invalid string or buffer length
((char *)rgbDesc)[namelen]='\0'; return SQL_ERROR;
}
namelen = strlen(sqlcol->name);
if (namelen + 1 < cbDescMax) {
strcpy(rgbDesc, sqlcol->name);
} else {
if (cbDescMax > 1) {
strncpy(rgbDesc, sqlcol->name, cbDescMax-1);
((char*)rgbDesc)[cbDescMax-1] = '\0';
}
// So there is no \0 if cbDescMax was 0
strcpy(sqlState, "01004"); // String data, right truncated
ret = SQL_SUCCESS_WITH_INFO;
}
break; break;
case SQL_COLUMN_TYPE: case SQL_COLUMN_TYPE: /* =SQL_DESC_CONCISE_TYPE */
*pfDesc = SQL_CHAR; //*pfDesc = SQL_CHAR;
*pfDesc = _odbc_get_client_type(col);
break; break;
case SQL_COLUMN_LENGTH: case SQL_COLUMN_LENGTH:
break; break;
//case SQL_COLUMN_DISPLAY_SIZE: case SQL_COLUMN_DISPLAY_SIZE: /* =SQL_DESC_DISPLAY_SIZE */
case SQL_DESC_DISPLAY_SIZE:
*pfDesc = mdb_col_disp_size(col); *pfDesc = mdb_col_disp_size(col);
break; break;
default:
strcpy(sqlState, "HYC00"); // Driver not capable
ret = SQL_ERROR;
break;
} }
return SQL_SUCCESS; return ret;
} }
SQLRETURN SQL_API SQLColAttributes( SQLRETURN SQL_API SQLColAttributes(
@@ -1953,6 +1991,12 @@ static SQLRETURN SQL_API _SQLGetInfo(
if (pcbInfoValue) if (pcbInfoValue)
*pcbInfoValue = 9; *pcbInfoValue = 9;
break; break;
case SQL_DBMS_VER:
if (rgbInfoValue)
strncpy(rgbInfoValue, VERSION, cbInfoValueMax);
if (pcbInfoValue)
*pcbInfoValue = sizeof(VERSION)+1;
break;
default: default:
if (pcbInfoValue) if (pcbInfoValue)
*pcbInfoValue = 0; *pcbInfoValue = 0;