soci icon indicating copy to clipboard operation
soci copied to clipboard

Bug: Bad bounds check when retrieving a uint32_t value into an optional

Open seelabs opened this issue 3 years ago • 0 comments

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;
}

seelabs avatar Jan 18 '22 15:01 seelabs