SQLite not handling parameter count mismatch correctly #2020

This commit is contained in:
Alex Fabijanic
2017-11-29 19:39:45 -06:00
parent de692354b4
commit 21704830f1
2 changed files with 24 additions and 20 deletions

View File

@@ -88,7 +88,7 @@ void SQLiteStatementImpl::compileImpl()
if (pStmt) sqlite3_finalize(pStmt); if (pStmt) sqlite3_finalize(pStmt);
pStmt = 0; pStmt = 0;
std::string errMsg = sqlite3_errmsg(_pDB); std::string errMsg = sqlite3_errmsg(_pDB);
Utility::throwException(rc, errMsg); Utility::throwException(_pDB, rc, errMsg);
} }
else if (rc == SQLITE_OK && pStmt) else if (rc == SQLITE_OK && pStmt)
{ {
@@ -158,13 +158,13 @@ void SQLiteStatementImpl::bindImpl()
sqlite3_reset(_pStmt); sqlite3_reset(_pStmt);
int paramCount = sqlite3_bind_parameter_count(_pStmt); int paramCount = sqlite3_bind_parameter_count(_pStmt);
BindIt bindEnd = bindings().end(); if (0 == paramCount)
if (0 == paramCount || bindEnd == _bindBegin)
{ {
_canBind = false; _canBind = false;
return; return;
} }
BindIt bindEnd = bindings().end();
std::size_t availableCount = 0; std::size_t availableCount = 0;
Bindings::difference_type bindCount = 0; Bindings::difference_type bindCount = 0;
Bindings::iterator it = _bindBegin; Bindings::iterator it = _bindBegin;
@@ -175,6 +175,9 @@ void SQLiteStatementImpl::bindImpl()
else break; else break;
} }
if (availableCount < paramCount)
throw ParameterCountMismatchException();
/**/
Bindings::difference_type remainingBindCount = bindEnd - _bindBegin; Bindings::difference_type remainingBindCount = bindEnd - _bindBegin;
if (bindCount < remainingBindCount) if (bindCount < remainingBindCount)
{ {
@@ -183,7 +186,7 @@ void SQLiteStatementImpl::bindImpl()
} }
else if (bindCount > remainingBindCount) else if (bindCount > remainingBindCount)
throw ParameterCountMismatchException(); throw ParameterCountMismatchException();
/**/
std::size_t boundRowCount; std::size_t boundRowCount;
if (_bindBegin != bindings().end()) if (_bindBegin != bindings().end())
{ {
@@ -245,7 +248,7 @@ bool SQLiteStatementImpl::hasNext()
_affectedRowCount += sqlite3_changes(_pDB); _affectedRowCount += sqlite3_changes(_pDB);
if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE) if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE)
Utility::throwException(_nextResponse); Utility::throwException(_pDB, _nextResponse);
_pExtractor->reset();//clear the cached null indicators _pExtractor->reset();//clear the cached null indicators
@@ -273,7 +276,7 @@ std::size_t SQLiteStatementImpl::next()
if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0; if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0;
if (extracts.begin() != extracts.end()) if (extracts.begin() != extracts.end())
{ {
_affectedRowCount += (*extracts.begin())->numOfRowsHandled(); _affectedRowCount += static_cast<int>((*extracts.begin())->numOfRowsHandled());
} }
} }
else if (SQLITE_DONE == _nextResponse) else if (SQLITE_DONE == _nextResponse)
@@ -282,7 +285,7 @@ std::size_t SQLiteStatementImpl::next()
} }
else else
{ {
Utility::throwException(_nextResponse, std::string("Iterator Error: trying to access the next value")); Utility::throwException(_pDB, _nextResponse, std::string("Iterator Error: trying to access the next value"));
} }
return 1u; return 1u;

View File

@@ -427,7 +427,7 @@ void SQLiteTest::testNullCharPointer()
bind("firstname"), bind("firstname"),
bind("Address"), bind(pc), now; bind("Address"), bind(pc), now;
fail ("must fail"); fail ("must fail");
} catch (NullPointerException&) { } } catch (NullPointerException&) { }
tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
assert (count == 1); assert (count == 1);
@@ -466,7 +466,7 @@ void SQLiteTest::testInsertCharPointer()
bind("firstname"), bind("firstname"),
bind("Address"), bind("Address"),
bind(133132)); bind(133132));
std::free((void*) pc); pc = 0; std::free((void*) pc); pc = 0;
assert (1 == stmt.execute()); assert (1 == stmt.execute());
@@ -2190,10 +2190,12 @@ void SQLiteTest::testAsync()
assert (stmt1.wait() == rowCount); assert (stmt1.wait() == rowCount);
stmt1.execute(); stmt1.execute();
try { try
{
stmt1.execute(); stmt1.execute();
fail ("must fail"); fail ("must fail");
} catch (InvalidAccessException&) }
catch (InvalidAccessException&)
{ {
stmt1.wait(); stmt1.wait();
stmt1.execute(); stmt1.execute();
@@ -2206,10 +2208,12 @@ void SQLiteTest::testAsync()
assert (stmt.execute() == 0); assert (stmt.execute() == 0);
assert (stmt.isAsync()); assert (stmt.isAsync());
try { try
{
result = stmt.executeAsync(); result = stmt.executeAsync();
fail ("must fail"); fail ("must fail");
} catch (InvalidAccessException&) }
catch (InvalidAccessException&)
{ {
stmt.wait(); stmt.wait();
result = stmt.executeAsync(); result = stmt.executeAsync();
@@ -2319,7 +2323,6 @@ void SQLiteTest::testPair()
std::string tableName("Simpsons"); std::string tableName("Simpsons");
std::pair<std::string, int> junior = std::make_pair("Junior", 12); std::pair<std::string, int> junior = std::make_pair("Junior", 12);
std::pair<std::string, int> senior = std::make_pair("Senior", 99); std::pair<std::string, int> senior = std::make_pair("Senior", 99);
int count = 0; int count = 0;
std::string result; std::string result;
@@ -2329,7 +2332,6 @@ void SQLiteTest::testPair()
tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
assert (result == tableName); assert (result == tableName);
// these are fine // these are fine
tmp << "INSERT INTO Simpsons VALUES(?, ?)", use(junior), now; tmp << "INSERT INTO Simpsons VALUES(?, ?)", use(junior), now;
tmp << "INSERT INTO Simpsons VALUES(?, ?)", useRef(senior), now; tmp << "INSERT INTO Simpsons VALUES(?, ?)", useRef(senior), now;
@@ -2343,7 +2345,6 @@ void SQLiteTest::testPair()
assert (ret[0].second == 99 || ret[1].second == 99); assert (ret[0].second == 99 || ret[1].second == 99);
assert (ret[0].first == "Junior" || ret[1].first == "Junior"); assert (ret[0].first == "Junior" || ret[1].first == "Junior");
assert (ret[0].first == "Senior" || ret[1].first == "Senior"); assert (ret[0].first == "Senior" || ret[1].first == "Senior");
} }
@@ -2500,12 +2501,12 @@ void SQLiteTest::testBindingCount()
tmp << "CREATE TABLE Ints (int0 INTEGER)", now; tmp << "CREATE TABLE Ints (int0 INTEGER)", now;
int i = 42; int i = 42;
try { tmp << "INSERT INTO Ints VALUES (?)", now; } try { tmp << "INSERT INTO Ints VALUES (?)", now; fail("must fail"); }
catch (ParameterCountMismatchException&) { } catch (ParameterCountMismatchException&) { }
tmp << "INSERT INTO Ints VALUES (?)", use(i), now; tmp << "INSERT INTO Ints VALUES (?)", use(i), now;
i = 0; i = 0;
try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; } try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; fail("must fail"); }
catch (ParameterCountMismatchException&) { } catch (ParameterCountMismatchException&) { }
tmp << "SELECT int0 from Ints where int0 = ?", bind(42), into(i), now; tmp << "SELECT int0 from Ints where int0 = ?", bind(42), into(i), now;
assert (42 == i); assert (42 == i);
@@ -2513,8 +2514,8 @@ void SQLiteTest::testBindingCount()
tmp << "DROP TABLE IF EXISTS Ints", now; tmp << "DROP TABLE IF EXISTS Ints", now;
tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now;
try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; } try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; fail("must fail"); }
catch (ParameterCountMismatchException&) { } catch (ParameterCountMismatchException& ex) { }
} }