soci
soci copied to clipboard
Bug: Bad bounds check when retrieving a uint32_t value into an optional
If a uint32_t
with a value of numeric_limits<std::uint32_t>::max();
is stored in a database and then retrieved into a variable of type optional<uint32_t>
an exception is thrown:
Value outside of allowed range for the parameter number 1
Note that retrieving the value into a variable of type std::uint32_t
works correctly. The following small program demonstrates the behavior:
#define SOCI_USE_BOOST
#include <soci/soci.h>
#include <soci/sqlite3/soci-sqlite3.h>
#include <boost/optional.hpp>
#include <cassert>
#include <iostream>
void
testSQLiteSelect()
{
std::uint32_t const uid = std::numeric_limits<std::uint32_t>::max();
{
soci::backend_factory const& backEnd = *soci::factory_sqlite3();
soci::session s(backEnd, "db_test.sqlite3");
s << "CREATE TABLE T (UI INTEGER UNSIGNED);";
s << "INSERT INTO T (UI) VALUES(:idu);", soci::use(uid);
// Retrieving an std::uint32_t::max value into a std::uint_t variable
// works.
try
{
std::uint32_t uig = 0;
s << "SELECT UI from T;", soci::into(uig);
assert(uig == uid);
}
catch (std::exception& e)
{
std::cerr << "Got exception for std::uint32_t: " << e.what();
assert(0);
}
// Retrieving an std::uint32_t::max value into a
// boost::optional<std::uint_t> variable throws an exception:
// "Value outside of allowed range for the parameter number 1"
try
{
boost::optional<std::uint32_t> uig;
s << "SELECT UI from T;", soci::into(uig);
}
catch (std::exception& e)
{
std::cerr << "Got exception for optional<std::uint32_t>: "
<< e.what();
assert(0);
}
}
}
int
main()
{
testSQLiteSelect();
return 0;
}