From 21704830f10de7b782ad2d42bd8837f5072b53cb Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Wed, 29 Nov 2017 19:39:45 -0600 Subject: [PATCH] SQLite not handling parameter count mismatch correctly #2020 --- Data/SQLite/src/SQLiteStatementImpl.cpp | 17 +++++++++------ Data/SQLite/testsuite/src/SQLiteTest.cpp | 27 ++++++++++++------------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Data/SQLite/src/SQLiteStatementImpl.cpp b/Data/SQLite/src/SQLiteStatementImpl.cpp index 87830745f..174a1c623 100644 --- a/Data/SQLite/src/SQLiteStatementImpl.cpp +++ b/Data/SQLite/src/SQLiteStatementImpl.cpp @@ -88,7 +88,7 @@ void SQLiteStatementImpl::compileImpl() if (pStmt) sqlite3_finalize(pStmt); pStmt = 0; std::string errMsg = sqlite3_errmsg(_pDB); - Utility::throwException(rc, errMsg); + Utility::throwException(_pDB, rc, errMsg); } else if (rc == SQLITE_OK && pStmt) { @@ -158,13 +158,13 @@ void SQLiteStatementImpl::bindImpl() sqlite3_reset(_pStmt); int paramCount = sqlite3_bind_parameter_count(_pStmt); - BindIt bindEnd = bindings().end(); - if (0 == paramCount || bindEnd == _bindBegin) + if (0 == paramCount) { _canBind = false; return; } + BindIt bindEnd = bindings().end(); std::size_t availableCount = 0; Bindings::difference_type bindCount = 0; Bindings::iterator it = _bindBegin; @@ -175,6 +175,9 @@ void SQLiteStatementImpl::bindImpl() else break; } + if (availableCount < paramCount) + throw ParameterCountMismatchException(); + /**/ Bindings::difference_type remainingBindCount = bindEnd - _bindBegin; if (bindCount < remainingBindCount) { @@ -183,7 +186,7 @@ void SQLiteStatementImpl::bindImpl() } else if (bindCount > remainingBindCount) throw ParameterCountMismatchException(); - + /**/ std::size_t boundRowCount; if (_bindBegin != bindings().end()) { @@ -245,7 +248,7 @@ bool SQLiteStatementImpl::hasNext() _affectedRowCount += sqlite3_changes(_pDB); if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE) - Utility::throwException(_nextResponse); + Utility::throwException(_pDB, _nextResponse); _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 (extracts.begin() != extracts.end()) { - _affectedRowCount += (*extracts.begin())->numOfRowsHandled(); + _affectedRowCount += static_cast((*extracts.begin())->numOfRowsHandled()); } } else if (SQLITE_DONE == _nextResponse) @@ -282,7 +285,7 @@ std::size_t SQLiteStatementImpl::next() } 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; diff --git a/Data/SQLite/testsuite/src/SQLiteTest.cpp b/Data/SQLite/testsuite/src/SQLiteTest.cpp index a5371dafd..63361bd9e 100644 --- a/Data/SQLite/testsuite/src/SQLiteTest.cpp +++ b/Data/SQLite/testsuite/src/SQLiteTest.cpp @@ -427,7 +427,7 @@ void SQLiteTest::testNullCharPointer() bind("firstname"), bind("Address"), bind(pc), now; fail ("must fail"); - } catch (NullPointerException&) { } + } catch (NullPointerException&) { } tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); @@ -466,7 +466,7 @@ void SQLiteTest::testInsertCharPointer() bind("firstname"), bind("Address"), bind(133132)); - + std::free((void*) pc); pc = 0; assert (1 == stmt.execute()); @@ -2190,10 +2190,12 @@ void SQLiteTest::testAsync() assert (stmt1.wait() == rowCount); stmt1.execute(); - try { + try + { stmt1.execute(); fail ("must fail"); - } catch (InvalidAccessException&) + } + catch (InvalidAccessException&) { stmt1.wait(); stmt1.execute(); @@ -2206,10 +2208,12 @@ void SQLiteTest::testAsync() assert (stmt.execute() == 0); assert (stmt.isAsync()); - try { + try + { result = stmt.executeAsync(); fail ("must fail"); - } catch (InvalidAccessException&) + } + catch (InvalidAccessException&) { stmt.wait(); result = stmt.executeAsync(); @@ -2319,7 +2323,6 @@ void SQLiteTest::testPair() std::string tableName("Simpsons"); std::pair junior = std::make_pair("Junior", 12); std::pair senior = std::make_pair("Senior", 99); - int count = 0; std::string result; @@ -2329,7 +2332,6 @@ void SQLiteTest::testPair() tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; assert (result == tableName); - // these are fine tmp << "INSERT INTO Simpsons VALUES(?, ?)", use(junior), 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].first == "Junior" || ret[1].first == "Junior"); assert (ret[0].first == "Senior" || ret[1].first == "Senior"); - } @@ -2500,12 +2501,12 @@ void SQLiteTest::testBindingCount() tmp << "CREATE TABLE Ints (int0 INTEGER)", now; int i = 42; - try { tmp << "INSERT INTO Ints VALUES (?)", now; } + try { tmp << "INSERT INTO Ints VALUES (?)", now; fail("must fail"); } catch (ParameterCountMismatchException&) { } tmp << "INSERT INTO Ints VALUES (?)", use(i), now; 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&) { } tmp << "SELECT int0 from Ints where int0 = ?", bind(42), into(i), now; assert (42 == i); @@ -2513,8 +2514,8 @@ void SQLiteTest::testBindingCount() tmp << "DROP TABLE IF EXISTS Ints", now; tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; - try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; } - catch (ParameterCountMismatchException&) { } + try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; fail("must fail"); } + catch (ParameterCountMismatchException& ex) { } }