diff options
author | Lionel Elie Mamane <lionel@mamane.lu> | 2012-01-24 22:20:31 +0100 |
---|---|---|
committer | Lionel Elie Mamane <lionel@mamane.lu> | 2012-01-29 19:00:38 +0100 |
commit | 63b6b1d6120d82c4baf5cb679d75dcc5427dbbc3 (patch) | |
tree | bd2f0165d5d6ace3616d244c9d8b0afeef75fd18 /connectivity/source/drivers/odbcbase/OTools.cxx | |
parent | bec18a80f59085c034e5adb1bb61d8365c1406c3 (diff) |
make OTools::getValue insanely safe, factorise get{Int,Long,Byte,...}
Diffstat (limited to 'connectivity/source/drivers/odbcbase/OTools.cxx')
-rw-r--r-- | connectivity/source/drivers/odbcbase/OTools.cxx | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx index 4da70ef9f812..9e8714cb0ca8 100644 --- a/connectivity/source/drivers/odbcbase/OTools.cxx +++ b/connectivity/source/drivers/odbcbase/OTools.cxx @@ -45,6 +45,82 @@ using namespace com::sun::star::uno; using namespace com::sun::star::sdbc; using namespace com::sun::star::util; +namespace { +size_t sqlTypeLen ( SQLSMALLINT _nType ) +{ + switch (_nType) + { + case SQL_C_CHAR: + return sizeof(SQLCHAR *); + case SQL_C_WCHAR: + return sizeof(SQLWCHAR *); + case SQL_C_SSHORT: + case SQL_C_SHORT: + return sizeof(SQLSMALLINT); + case SQL_C_USHORT: + return sizeof(SQLUSMALLINT); + case SQL_C_SLONG: + case SQL_C_LONG: + return sizeof(SQLINTEGER); + case SQL_C_ULONG: + return sizeof(SQLUINTEGER); + case SQL_C_FLOAT: + return sizeof(SQLREAL); + case SQL_C_DOUBLE: + OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion"); + return sizeof(SQLDOUBLE); + case SQL_C_BIT: + return sizeof(SQLCHAR); + case SQL_C_STINYINT: + case SQL_C_TINYINT: + return sizeof(SQLSCHAR); + case SQL_C_UTINYINT: + return sizeof(SQLCHAR); + case SQL_C_SBIGINT: + return sizeof(SQLBIGINT); + case SQL_C_UBIGINT: + return sizeof(SQLUBIGINT); + /* UnixODBC gives this the same value as SQL_C_UBIGINT + case SQL_C_BOOKMARK: + return sizeof(BOOKMARK); */ + case SQL_C_BINARY: + // UnixODBC gives these the same value + //case SQL_C_VARBOOKMARK: + return sizeof(SQLCHAR*); + case SQL_C_TYPE_DATE: + case SQL_C_DATE: + return sizeof(SQL_DATE_STRUCT); + case SQL_C_TYPE_TIME: + case SQL_C_TIME: + return sizeof(SQL_TIME_STRUCT); + case SQL_C_TYPE_TIMESTAMP: + case SQL_C_TIMESTAMP: + return sizeof(SQL_TIMESTAMP_STRUCT); + case SQL_C_NUMERIC: + return sizeof(SQL_NUMERIC_STRUCT); + case SQL_C_GUID: + return sizeof(SQLGUID); + case SQL_C_INTERVAL_YEAR: + case SQL_C_INTERVAL_MONTH: + case SQL_C_INTERVAL_DAY: + case SQL_C_INTERVAL_HOUR: + case SQL_C_INTERVAL_MINUTE: + case SQL_C_INTERVAL_SECOND: + case SQL_C_INTERVAL_YEAR_TO_MONTH: + case SQL_C_INTERVAL_DAY_TO_HOUR: + case SQL_C_INTERVAL_DAY_TO_MINUTE: + case SQL_C_INTERVAL_DAY_TO_SECOND: + case SQL_C_INTERVAL_HOUR_TO_MINUTE: + case SQL_C_INTERVAL_HOUR_TO_SECOND: + case SQL_C_INTERVAL_MINUTE_TO_SECOND: + return sizeof(SQL_INTERVAL_STRUCT); + default: + return static_cast<size_t>(-1); + } +} +} + + void OTools::getValue( OConnection* _pConnection, SQLHANDLE _aStatementHandle, sal_Int32 columnIndex, @@ -55,6 +131,23 @@ void OTools::getValue( OConnection* _pConnection, SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" ); + const size_t properSize = sqlTypeLen(_nType); + if ( properSize == static_cast<size_t>(-1) ) + OSL_FAIL("connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size"); + else + { + OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to"); + if ( static_cast<size_t>(_nSize) > properSize ) + { + OSL_FAIL("memory region is too big - trying to fudge it"); + memset(_pValue, 0, _nSize); +#ifdef OSL_BIGENDIAN + // This is skewed in favour of integer types + _pValue += _nSize - properSize; +#endif + } + } + OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small"); SQLLEN pcbValue = SQL_NULL_DATA; OTools::ThrowException(_pConnection, (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, |