Stop SQLite results being used before being fetched (#1709)

The DB API requires FetchRow to be called before accessing any values
from a row, but the SQLite driver did not enforce that requirement and
alowed accessing the first row immediately. A plugin developer hit this
when developing against SQLite locally but using MySQL in production,
where the API misuse threw an error as expected.

Resolves #1691
This commit is contained in:
Asher Baker 2022-02-06 16:34:14 +00:00 committed by Your Name
parent c206ac3099
commit 19f1ffa401
2 changed files with 10 additions and 10 deletions

View File

@ -37,7 +37,7 @@
SqResults::SqResults(SqQuery *query) :
m_pStmt(query->GetStmt()), m_Strings(1024),
m_RowCount(0), m_MaxRows(0), m_Rows(NULL),
m_CurRow(0), m_NextRow(0)
m_CurRow(-1), m_NextRow(0)
{
m_ColCount = sqlite3_column_count(m_pStmt);
if (m_ColCount)
@ -99,7 +99,7 @@ bool SqResults::FieldNameToNum(const char *name, unsigned int *columnId)
void SqResults::ResetResultCount()
{
m_RowCount = 0;
m_CurRow = 0;
m_CurRow = -1;
m_NextRow = 0;
m_pMemory->Reset();
}
@ -163,7 +163,7 @@ void SqResults::PushResult()
bool SqResults::MoreRows()
{
return (m_CurRow < m_RowCount);
return (m_CurRow < 0) ? (m_RowCount > 0) : (m_CurRow < m_RowCount);
}
IResultRow *SqResults::FetchRow()
@ -179,7 +179,7 @@ IResultRow *SqResults::FetchRow()
IResultRow *SqResults::CurrentRow()
{
if (!m_RowCount || m_CurRow >= m_RowCount)
if (!m_RowCount || m_CurRow < 0 || m_CurRow >= m_RowCount)
{
return NULL;
}
@ -188,14 +188,14 @@ IResultRow *SqResults::CurrentRow()
bool SqResults::Rewind()
{
m_CurRow = 0;
m_CurRow = -1;
m_NextRow = 0;
return true;
}
SqField *SqResults::GetField(unsigned int col)
{
if (m_CurRow >= m_RowCount || col >= m_ColCount)
if (m_CurRow < 0 || m_CurRow >= m_RowCount || col >= m_ColCount)
{
return NULL;
}

View File

@ -90,11 +90,11 @@ private:
unsigned int m_ColCount; /** DOES NOT CHANGE */
BaseStringTable m_Strings; /** DOES NOT CHANGE */
BaseMemTable *m_pMemory; /** DOES NOT CHANGE */
unsigned int m_RowCount;
unsigned int m_MaxRows;
int m_RowCount;
int m_MaxRows;
SqField *m_Rows;
unsigned int m_CurRow;
unsigned int m_NextRow;
int m_CurRow;
int m_NextRow;
};
#endif //_INCLUDE_SQLITE_SOURCEMOD_RESULT_SET_H_