fix(Extractor): check encoding validity early and make Extractor encodings SharedPtr

This commit is contained in:
Alex Fabijanic
2020-11-20 14:40:27 +01:00
parent cf2d7c75c1
commit 84b58db83b
5 changed files with 19 additions and 16 deletions

View File

@@ -56,7 +56,7 @@ public:
Extractor(const StatementHandle& rStmt, Extractor(const StatementHandle& rStmt,
Preparator::Ptr pPreparator, Preparator::Ptr pPreparator,
const std::string& dbEncoding = "UTF-8"); Poco::TextEncoding::Ptr pDBEncoding = nullptr);
/// Creates the Extractor. /// Creates the Extractor.
~Extractor(); ~Extractor();
@@ -586,7 +586,7 @@ private:
val.clear(); val.clear();
if (ret) if (ret)
{ {
Poco::TextConverter conv(_dbEncoding, _toEncoding); Poco::TextConverter conv(*_pDBEncoding, *_pToEncoding);
val.resize(res.size()); val.resize(res.size());
C::iterator vIt = val.begin(); C::iterator vIt = val.begin();
C::iterator it = res.begin(); C::iterator it = res.begin();
@@ -622,9 +622,9 @@ private:
PreparatorPtr _pPreparator; PreparatorPtr _pPreparator;
Preparator::DataExtraction _dataExtraction; Preparator::DataExtraction _dataExtraction;
std::vector<SQLLEN> _lengths; std::vector<SQLLEN> _lengths;
Poco::TextEncoding& _dbEncoding; Poco::TextEncoding::Ptr _pDBEncoding;
Poco::TextEncoding& _toEncoding;
bool _transcode; bool _transcode;
Poco::TextEncoding::Ptr _pToEncoding;
}; };

View File

@@ -25,6 +25,7 @@
#include "Poco/Data/ODBC/Handle.h" #include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/ODBCException.h" #include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/AbstractSessionImpl.h" #include "Poco/Data/AbstractSessionImpl.h"
#include "Poco/TextEncoding.h"
#include "Poco/SharedPtr.h" #include "Poco/SharedPtr.h"
#include "Poco/Mutex.h" #include "Poco/Mutex.h"
#ifdef POCO_OS_FAMILY_WINDOWS #ifdef POCO_OS_FAMILY_WINDOWS
@@ -302,12 +303,6 @@ inline int SessionImpl::queryTimeout() const
} }
inline void SessionImpl::setDBEncoding(const std::string&, const Poco::Any& value)
{
_dbEncoding = Poco::AnyCast<std::string>(value);
}
inline Poco::Any SessionImpl::getDBEncoding(const std::string&) const inline Poco::Any SessionImpl::getDBEncoding(const std::string&) const
{ {
return _dbEncoding; return _dbEncoding;

View File

@@ -34,13 +34,13 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
Extractor::Extractor(const StatementHandle& rStmt, Extractor::Extractor(const StatementHandle& rStmt,
Preparator::Ptr pPreparator, Preparator::Ptr pPreparator,
const std::string& dbEncoding): TextEncoding::Ptr pDBEncoding):
_rStmt(rStmt), _rStmt(rStmt),
_pPreparator(pPreparator), _pPreparator(pPreparator),
_dataExtraction(pPreparator->getDataExtraction()), _dataExtraction(pPreparator->getDataExtraction()),
_dbEncoding(Poco::TextEncoding::byName(dbEncoding)), _pDBEncoding(pDBEncoding),
_toEncoding(Poco::TextEncoding::byName("UTF-8")), _transcode(_pDBEncoding && !_pDBEncoding->isA("UTF-8")),
_transcode(!_dbEncoding.isA("UTF-8")) _pToEncoding(_transcode ? Poco::TextEncoding::find("UTF-8") : nullptr)
{ {
} }
@@ -679,7 +679,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
ret = extractManualImpl(pos, result, SQL_C_CHAR); ret = extractManualImpl(pos, result, SQL_C_CHAR);
else else
ret = extractBoundImpl(pos, result); ret = extractBoundImpl(pos, result);
Poco::TextConverter converter(_dbEncoding, _toEncoding); Poco::TextConverter converter(*_pDBEncoding, *_pToEncoding);
converter.convert(result, val); converter.convert(result, val);
} }

View File

@@ -146,7 +146,7 @@ void ODBCStatementImpl::addPreparator()
_preparations.push_back(new Preparator(*_preparations[0])); _preparations.push_back(new Preparator(*_preparations[0]));
_extractors.push_back(new Extractor(_stmt, _preparations.back(), _extractors.push_back(new Extractor(_stmt, _preparations.back(),
Poco::RefAnyCast<std::string>(session().getProperty("dbEncoding")))); TextEncoding::find(Poco::RefAnyCast<std::string>(session().getProperty("dbEncoding")))));
} }

View File

@@ -170,6 +170,14 @@ void SessionImpl::open(const std::string& connect)
} }
void SessionImpl::setDBEncoding(const std::string&, const Poco::Any& value)
{
const std::string& enc = Poco::RefAnyCast<std::string>(value);
Poco::TextEncoding::byName(enc); // throws if not found
_dbEncoding = enc;
}
bool SessionImpl::isConnected() const bool SessionImpl::isConnected() const
{ {
SQLULEN value = 0; SQLULEN value = 0;