~aleteoryx/muditaos

7495d1b6e16f419c567ac6ace4e725349f495dc9 — Marek Niepieklo 4 years ago 63ae16f
[CP-327] Fix UB in QueryResult

QueryResult iterator nextRow() may get into infinite loop.
Additionally, fixed handling of the case when each row of result
could have a different count of fields.
M module-db/Database/Database.cpp => module-db/Database/Database.cpp +5 -3
@@ 195,11 195,13 @@ uint32_t Database::getLastInsertRowId()
    return sqlite3_last_insert_rowid(dbConnection);
}

void Database::pragmaQuery(const std::string &pragmaStatemnt)
void Database::pragmaQuery(const std::string &pragmaStatement)
{
    if (auto results = query(pragmaStatemnt.c_str()); results) {
        const auto fieldsCount = results->getFieldCount();
    auto results = query(pragmaStatement.c_str());

    if (results && results->getRowCount()) {
        do {
            const auto fieldsCount = results->getFieldCount();
            for (uint32_t i = 0; i < fieldsCount; i++) {
                Field field = (*results)[i];
            }

M module-db/Database/Database.hpp => module-db/Database/Database.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 37,7 37,7 @@ class Database
    bool storeIntoFile(const std::filesystem::path &backupPath);

    uint32_t getLastInsertRowId();
    void pragmaQuery(const std::string &pragmaStatemnt);
    void pragmaQuery(const std::string &pragmaStatement);

    [[nodiscard]] bool isInitialized() const noexcept
    {

M module-db/Database/QueryResult.cpp => module-db/Database/QueryResult.cpp +6 -12
@@ 1,25 1,19 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "QueryResult.hpp"

QueryResult::QueryResult() : currentRow(0), fieldCount(0), rowCount(0)
QueryResult::QueryResult() : currentRow(0)
{}

void QueryResult::addRow(const std::vector<Field> &row)
{
    rows.push_back(row);
    rowCount++;
    fieldCount = row.size();
}

bool QueryResult::nextRow()
{
    if (currentRow < (rowCount - 1)) {
        currentRow++;
        return true;
    }
    else {
        return false;
    }
}
\ No newline at end of file
    ++currentRow;

    return (currentRow < rows.size());
}

M module-db/Database/QueryResult.hpp => module-db/Database/QueryResult.hpp +3 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 27,17 27,15 @@ class QueryResult

    uint32_t getFieldCount() const
    {
        return fieldCount;
        return rows[currentRow].size();
    }

    uint32_t getRowCount() const
    {
        return rowCount;
        return rows.size();
    }

  private:
    uint32_t currentRow;
    std::vector<std::vector<Field>> rows;
    uint32_t fieldCount;
    uint32_t rowCount;
};