SF [2019857] Memory leak in Data::ODBC Extractor (fixed using Poco::Buffer)

This commit is contained in:
Aleksandar Fabijanic 2008-07-20 17:05:18 +00:00
parent 2589797359
commit d4f2be3fd2

View File

@ -39,6 +39,7 @@
#include "Poco/Data/ODBC/Utility.h" #include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/ODBCException.h" #include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/BLOB.h" #include "Poco/Data/BLOB.h"
#include "Poco/Buffer.h"
#include "Poco/Exception.h" #include "Poco/Exception.h"
@ -368,58 +369,49 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
std::size_t totalSize = 0; std::size_t totalSize = 0;
SQLLEN len; SQLLEN len;
char* pChar = 0; Poco::Buffer<char> apChar(CHUNK_SIZE);
try char* pChar = apChar.begin();
{ SQLRETURN rc = 0;
pChar = new char[CHUNK_SIZE];
SQLRETURN rc = 0; val.clear();
resizeLengths(pos);
val.clear();
resizeLengths(pos);
do do
{
std::memset(pChar, 0, CHUNK_SIZE);
len = 0;
rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
pChar, //returned value
CHUNK_SIZE, //buffer length
&len); //length indicator
if (SQL_NO_DATA != rc && Utility::isError(rc))
throw StatementException(_rStmt, "SQLGetData()");
if (SQL_NO_TOTAL == len)//unknown length, throw
throw UnknownDataLengthException("Could not determine returned data length.");
if (isNullLengthIndicator(len))
{ {
std::memset(pChar, 0, CHUNK_SIZE); _lengths[pos] = len;
len = 0; return false;
rc = SQLGetData(_rStmt, }
(SQLUSMALLINT) pos + 1,
cType, //C data type
pChar, //returned value
CHUNK_SIZE, //buffer length
&len); //length indicator
if (SQL_NO_DATA != rc && Utility::isError(rc)) if (SQL_NO_DATA == rc || !len)
throw StatementException(_rStmt, "SQLGetData()"); break;
if (SQL_NO_TOTAL == len)//unknown length, throw _lengths[pos] += len;
throw UnknownDataLengthException("Could not determine returned data length."); fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
totalSize += fetchedSize;
if (totalSize <= maxSize)
val.append(pChar, fetchedSize);
else
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
}while (true);
if (isNullLengthIndicator(len)) return true;
{
_lengths[pos] = len;
return false;
}
if (SQL_NO_DATA == rc || !len)
break;
_lengths[pos] += len;
fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
totalSize += fetchedSize;
if (totalSize <= maxSize)
val.append(pChar, fetchedSize);
else
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
}while (true);
delete[] pChar;
return true;
} catch (...)
{
delete[] pChar;
throw;
}
} }
@ -433,57 +425,48 @@ bool Extractor::extractManualImpl<Poco::Data::BLOB>(std::size_t pos,
std::size_t totalSize = 0; std::size_t totalSize = 0;
SQLLEN len; SQLLEN len;
char* pChar = 0; Poco::Buffer<char> apChar(CHUNK_SIZE);
try char* pChar = apChar.begin();
SQLRETURN rc = 0;
val.clear();
resizeLengths(pos);
do
{ {
pChar = new char[CHUNK_SIZE]; std::memset(pChar, 0, CHUNK_SIZE);
SQLRETURN rc = 0; len = 0;
rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
pChar, //returned value
CHUNK_SIZE, //buffer length
&len); //length indicator
val.clear(); _lengths[pos] += len;
resizeLengths(pos);
do if (SQL_NO_DATA != rc && Utility::isError(rc))
{ throw StatementException(_rStmt, "SQLGetData()");
std::memset(pChar, 0, CHUNK_SIZE);
len = 0;
rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
pChar, //returned value
CHUNK_SIZE, //buffer length
&len); //length indicator
_lengths[pos] += len;
if (SQL_NO_DATA != rc && Utility::isError(rc)) if (SQL_NO_TOTAL == len)//unknown length, throw
throw StatementException(_rStmt, "SQLGetData()"); throw UnknownDataLengthException("Could not determine returned data length.");
if (SQL_NO_TOTAL == len)//unknown length, throw if (isNullLengthIndicator(len))
throw UnknownDataLengthException("Could not determine returned data length."); return false;
if (isNullLengthIndicator(len)) if (SQL_NO_DATA == rc || !len)
return false; break;
if (SQL_NO_DATA == rc || !len) fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len;
break; totalSize += fetchedSize;
if (totalSize <= maxSize)
val.appendRaw(pChar, fetchedSize);
else
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len; }while (true);
totalSize += fetchedSize;
if (totalSize <= maxSize)
val.appendRaw(pChar, fetchedSize);
else
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
}while (true); return true;
delete[] pChar;
return true;
} catch (...)
{
delete[] pChar;
throw;
}
} }