Overview
Features
Download
Documentation
Community
Add-Ons & Services

Run-Time Check Failure #2 - Stack around the variable 'value

A general discussion forum.

Run-Time Check Failure #2 - Stack around the variable 'value

Postby hbdevelop1 » 06 Aug 2014, 21:13

Hello,

We were getting a crash in debug mode with the message :
Run-Time Check Failure #2 - Stack around the variable 'value' was corrupted
the crash was happening in bool SessionImpl::isTransaction().

The cause was that 'value' is declared as Poco::UInt32 but some ODBC function writes a 64-bit value to the address of 'value'.
I am correcting this in our version of Poco, and I thought I inform the Poco dev team to correct this in the official release of the Poco.

Best Regards,
hbdevelop1
 
Posts: 2
Joined: 06 Aug 2014, 21:05

Re: Run-Time Check Failure #2 - Stack around the variable 'v

Postby alex » 08 Aug 2014, 04:25

It would be nice if you could send a diff and even better if you could send a github pull request.
alex
 
Posts: 1158
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Run-Time Check Failure #2 - Stack around the variable 'v

Postby alex » 08 Aug 2014, 10:55

also, see if this pull fixes your problem: https://github.com/pocoproject/poco/com ... 6936d1aa1e
alex
 
Posts: 1158
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Run-Time Check Failure #2 - Stack around the variable 'v

Postby hbdevelop1 » 08 Aug 2014, 21:45

The code in the commit you showed is similar to what I did. (see the diff below)
Whenever there is a "Get something" request to ODBC, I have passed the address of a 64-bit variable.
This pushed me to change other functions signatures to avoid the "possible loss of data" warning.

Here is the diff :

diff --git a/Data/ODBC/include/Poco/Data/ODBC/Binder.h b/Data/ODBC/include/Poco/Data/ODBC/Binder.h

template <typename C>
void bindImplContainerLOB(std::size_t pos, const C& val, Direction dir)
{
typedef typename C::value_type LOBType;
typedef typename LOBType::ValueType CharType;

if (isOutBound(dir) || !isInBound(dir))
throw NotImplementedException("BLOB container parameter type can only be inbound.");

if (PB_IMMEDIATE != _paramBinding)
throw InvalidAccessException("Containers can only be bound immediately.");

if (0 == val.size())
throw InvalidArgumentException("Empty container not allowed.");

setParamSetSize(val.size());

- SQLINTEGER size = 0;
+ SQLLEN size = 0;

if (_vecLengthIndicator.size() <= pos)
_vecLengthIndicator.resize(pos + 1);
diff --git a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
index b272f51..5ed24d2 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
@@ -128,10 +128,20 @@ public:
bool canTransact();
/// Returns true if connection is transaction-capable.

- void setTransactionIsolation(Poco::UInt32 ti);
+ void setTransactionIsolation(Poco::UInt64 ti);
/// Sets the transaction isolation level.

- Poco::UInt32 getTransactionIsolation();
+ Poco::UInt64 getTransactionIsolation();
/// Returns the transaction isolation level.

bool hasTransactionIsolation(Poco::UInt32);
@@ -197,7 +207,12 @@ private:

Poco::UInt32 getDefaultTransactionIsolation();

- Poco::UInt32 transactionIsolation(SQLUINTEGER isolation);
+ Poco::UInt32 transactionIsolation(SQLULEN isolation);

std::string _connector;
const ConnectionHandle _db;
diff --git a/Data/ODBC/src/SessionImpl.cpp b/Data/ODBC/src/SessionImpl.cpp
index 01dee55..134126d 100644
--- a/Data/ODBC/src/SessionImpl.cpp
+++ b/Data/ODBC/src/SessionImpl.cpp
@@ -120,7 +120,13 @@ void SessionImpl::open(const std::string& connect)

poco_assert_dbg (!connectionString().empty());

- SQLUINTEGER tout = static_cast<SQLUINTEGER>(getLoginTimeout());
+ SQLULEN tout = static_cast<SQLULEN>(getLoginTimeout());
if (Utility::isError(SQLSetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) tout, 0)))
{
if (Utility::isError(SQLGetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, &tout, 0, 0)) ||
@@ -182,8 +188,13 @@ void SessionImpl::open(const std::string& connect)

bool SessionImpl::isConnected()
{
- SQLUINTEGER value = 0;
+ SQLULEN value = 0;
if (Utility::isError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
SQL_ATTR_CONNECTION_DEAD,
&value,
@@ -207,8 +218,13 @@ void SessionImpl::setConnectionTimeout(std::size_t timeout)

std::size_t SessionImpl::getConnectionTimeout()
{
- SQLUINTEGER value = 0;
+ SQLULEN value = 0;
checkError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
SQL_ATTR_CONNECTION_TIMEOUT,
&value,
@@ -236,7 +252,12 @@ bool SessionImpl::canTransact()
}


-void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
+void SessionImpl::setTransactionIsolation(Poco::UInt64 ti)
{
Poco::UInt32 isolation = 0;

@@ -256,9 +277,20 @@ void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
}


-Poco::UInt32 SessionImpl::getTransactionIsolation()
+Poco::UInt64 SessionImpl::getTransactionIsolation()
{
- SQLUINTEGER isolation = 0;
+ SQLULEN isolation = 0;
checkError(SQLGetConnectAttr(_db, SQL_ATTR_TXN_ISOLATION,
&isolation,
0,
@@ -273,7 +305,12 @@ bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
if (isTransaction()) throw InvalidAccessException();

bool retval = true;
- Poco::UInt32 old = getTransactionIsolation();
+ Poco::UInt64 old = getTransactionIsolation();
try { setTransactionIsolation(ti); }
catch (Poco::Exception&) { retval = false; }
setTransactionIsolation(old);
@@ -293,7 +330,11 @@ Poco::UInt32 SessionImpl::getDefaultTransactionIsolation()
}


-Poco::UInt32 SessionImpl::transactionIsolation(SQLUINTEGER isolation)
+Poco::UInt32 SessionImpl::transactionIsolation(SQLULEN isolation)
{
if (0 == isolation)
throw InvalidArgumentException("transactionIsolation(SQLUINTEGER)");
@@ -331,8 +372,13 @@ void SessionImpl::autoCommit(const std::string&, bool val)

bool SessionImpl::isAutoCommit(const std::string&)
{
- Poco::UInt32 value = 0;
+ Poco::UInt64 value = 0;
checkError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
SQL_ATTR_AUTOCOMMIT,
&value,
@@ -347,8 +393,14 @@ bool SessionImpl::isTransaction()
{
if (!canTransact()) return false;

- Poco::UInt32 value = 0;
+ Poco::UInt64 value = 0;
checkError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
SQL_ATTR_AUTOCOMMIT,
&value,
0,
diff --git a/Data/include/Poco/Data/PooledSessionImpl.h b/Data/include/Poco/Data/PooledSessionImpl.h
index 6ee85b4..6cba9d5 100644
--- a/Data/include/Poco/Data/PooledSessionImpl.h
+++ b/Data/include/Poco/Data/PooledSessionImpl.h
@@ -77,8 +77,18 @@ public:
std::size_t getConnectionTimeout();
bool canTransact();
bool isTransaction();
- void setTransactionIsolation(Poco::UInt32);
+ void setTransactionIsolation(Poco::UInt64);
- Poco::UInt32 getTransactionIsolation();
+ Poco::UInt64 getTransactionIsolation();
bool hasTransactionIsolation(Poco::UInt32);
bool isTransactionIsolation(Poco::UInt32);
const std::string& connectorName() const;
diff --git a/Data/include/Poco/Data/Session.h b/Data/include/Poco/Data/Session.h
index 5811ff1..642e661 100644
--- a/Data/include/Poco/Data/Session.h
+++ b/Data/include/Poco/Data/Session.h
@@ -263,8 +263,13 @@ public:
void setTransactionIsolation(Poco::UInt32);
/// Sets the transaction isolation level.

- Poco::UInt32 getTransactionIsolation();
+ Poco::UInt64 getTransactionIsolation();
/// Returns the transaction isolation level.

bool hasTransactionIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponding
@@ -425,7 +430,12 @@ inline void Session::setTransactionIsolation(Poco::UInt32 ti)
}


-inline Poco::UInt32 Session::getTransactionIsolation()
+inline Poco::UInt64 Session::getTransactionIsolation()
{
return _pImpl->getTransactionIsolation();
}
diff --git a/Data/include/Poco/Data/SessionImpl.h b/Data/include/Poco/Data/SessionImpl.h
index abc21ea..e1de667 100644
--- a/Data/include/Poco/Data/SessionImpl.h
+++ b/Data/include/Poco/Data/SessionImpl.h
@@ -125,11 +125,21 @@ public:
virtual bool isTransaction() = 0;
/// Returns true iff a transaction is a transaction is in progress, false otherwise.

- virtual void setTransactionIsolation(Poco::UInt32) = 0;
+ virtual void setTransactionIsolation(Poco::UInt64) = 0;
/// Sets the transaction isolation level.

- virtual Poco::UInt32 getTransactionIsolation() = 0;
+ virtual Poco::UInt64 getTransactionIsolation() = 0;
/// Returns the transaction isolation level.

virtual bool hasTransactionIsolation(Poco::UInt32) = 0;
/// Returns true iff the transaction isolation level corresponding
diff --git a/Data/include/Poco/Data/Transaction.h b/Data/include/Poco/Data/Transaction.h
index 784f59e..7ac636b 100644
--- a/Data/include/Poco/Data/Transaction.h
+++ b/Data/include/Poco/Data/Transaction.h
@@ -113,7 +113,12 @@ public:
void setIsolation(Poco::UInt32 ti);
/// Sets the transaction isolation level.

- Poco::UInt32 getIsolation();
+ Poco::UInt64 getIsolation();
/// Returns the transaction isolation level.

bool hasIsolation(Poco::UInt32 ti);
@@ -186,7 +191,12 @@ inline void Transaction::setIsolation(Poco::UInt32 ti)
}


-inline Poco::UInt32 Transaction::getIsolation()
+inline Poco::UInt64 Transaction::getIsolation()
{
return _rSession.getTransactionIsolation();
}
diff --git a/Data/src/PooledSessionImpl.cpp b/Data/src/PooledSessionImpl.cpp
index 8c8c0bd..a535b29 100644
--- a/Data/src/PooledSessionImpl.cpp
+++ b/Data/src/PooledSessionImpl.cpp
@@ -104,14 +104,23 @@ bool PooledSessionImpl::isTransaction()
return access()->isTransaction();
}

-
-void PooledSessionImpl::setTransactionIsolation(Poco::UInt32 ti)
+void PooledSessionImpl::setTransactionIsolation(Poco::UInt64 ti)
{
access()->setTransactionIsolation(ti);
}


-Poco::UInt32 PooledSessionImpl::getTransactionIsolation()
+Poco::UInt64 PooledSessionImpl::getTransactionIsolation()
{
return access()->getTransactionIsolation();
}
diff --git a/Data/testsuite/src/SessionImpl.cpp b/Data/testsuite/src/SessionImpl.cpp
index f80df74..1630f5e 100644
--- a/Data/testsuite/src/SessionImpl.cpp
+++ b/Data/testsuite/src/SessionImpl.cpp
@@ -121,13 +121,21 @@ bool SessionImpl::isTransaction()
return false;
}

-void SessionImpl::setTransactionIsolation(Poco::UInt32)
+void SessionImpl::setTransactionIsolation(Poco::UInt64)
{
}

-
-Poco::UInt32 SessionImpl::getTransactionIsolation()
+Poco::UInt64 SessionImpl::getTransactionIsolation()
{
return 0;
}
diff --git a/Data/testsuite/src/SessionImpl.h b/Data/testsuite/src/SessionImpl.h
index 6e728a2..1257135 100644
--- a/Data/testsuite/src/SessionImpl.h
+++ b/Data/testsuite/src/SessionImpl.h
@@ -91,10 +91,20 @@ public:
bool isTransaction();
/// Returns true iff a transaction is a transaction is in progress, false otherwise.

- void setTransactionIsolation(Poco::UInt32);
+ void setTransactionIsolation(Poco::UInt64);
/// Sets the transaction isolation level.

- Poco::UInt32 getTransactionIsolation();
+ Poco::UInt64 getTransactionIsolation();
/// Returns the transaction isolation level.

bool hasTransactionIsolation(Poco::UInt32);
hbdevelop1
 
Posts: 2
Joined: 06 Aug 2014, 21:05


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests