From 815ec66a68c01dc4a8f0c5ec6c9193a71e7547e2 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sat, 2 Nov 2024 13:51:03 +0100 Subject: fix enemy creation --- frontend/GameData.cpp | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp index 1b7c548..6d22f8e 100644 --- a/frontend/GameData.cpp +++ b/frontend/GameData.cpp @@ -1,8 +1,8 @@ #include -#include #include "backend/Enemy.h" #include "backend/EnemyFactory.h" +#include "backend/Exception.h" #include "backend/LocationFactory.h" #include "backend/Object.h" #include "backend/ObjectFactory.h" @@ -42,14 +42,14 @@ Enemy * GameData::create_enemy(const string & name) const { auto row = query.row(); auto enemy = unique_ptr{ EnemyFactory::create_enemy(row.col(0), row.col(1)) }; int object_count = RNG::get().rand_int(Range { row.col(2), row.col(3) }); - vector object_names = this->random_objects(object_count); - for (const string & name : object_names) + for (const string & name : this->random_objects(object_count)) enemy->add_hidden_object(this->create_object(name)); enemy->set_health(row.col(4)); enemy->set_attack(static_cast(row.col(5)) / 100); enemy->set_damage({ row.col(6), row.col(7) }); return enemy.release(); - } catch (...) { + } catch (Exception & e) { + printf("Fout bij aanmaken van vijand: %s\n", e.what()); return EnemyFactory::create_enemy(name.c_str()); } } @@ -136,22 +136,25 @@ void GameData::leaderbord_print() const { } vector GameData::random_names(const string & table, unsigned count) const { - static DBStatement query = this->db.prepare(R"( - select naam - from ? - order by random() - limit ? - )"); - query.reset() - .bind(table.c_str()) - .bind(count) - ; - - vector names = {}; - for (DBQueryRow & row : query.rows()) { - names.push_back(row.col(0)); + if (count == 0) return {}; + try { + // NOTE: Parameter placeholders cannot be used for database identifiers + // (i.e. the table name in this case), which makes this function vulnerable + // to SQL injection if the table argument contains user-controllable data. + String query_str = String::fmt("select naam from %s order by random() limit ?", table.c_str()); + static DBStatement query = this->db.prepare(query_str.c_str()); + query.reset() + .bind(count) + ; + + vector names = {}; + for (DBQueryRow & row : query.rows()) { + names.push_back(row.col(0)); + } + return names; + } catch (Exception & e) { + throw Exception("genereren van %d willekeurige namen uit tabel %s: %s", count, table.c_str(), e.what()); } - return names; } vector GameData::random_locations(unsigned count) const { -- cgit v1.2.3