mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 09:24:55 +02:00
SF [2019857] Memory leak in Data::ODBC Extractor (fixed using Poco::Buffer)
This commit is contained in:
parent
2589797359
commit
d4f2be3fd2
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user