diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-02 13:51:03 +0100 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-02 13:51:03 +0100 |
commit | 815ec66a68c01dc4a8f0c5ec6c9193a71e7547e2 (patch) | |
tree | 2a575f53d208ffa7c11856b6805e3e49c1ccdb87 | |
parent | 5a675c5e6833e98b92b55396594bc0d607b98903 (diff) |
fix enemy creation
-rw-r--r-- | frontend/GameData.cpp | 41 |
1 files 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 <memory> -#include <unordered_map> #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<Enemy>{ EnemyFactory::create_enemy(row.col<const char *>(0), row.col<const char *>(1)) }; int object_count = RNG::get().rand_int(Range<int> { row.col<int>(2), row.col<int>(3) }); - vector<string> 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<int>(4)); enemy->set_attack(static_cast<float>(row.col<int>(5)) / 100); enemy->set_damage({ row.col<int>(6), row.col<int>(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<string> 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<string> names = {}; - for (DBQueryRow & row : query.rows()) { - names.push_back(row.col<const char *>(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<string> names = {}; + for (DBQueryRow & row : query.rows()) { + names.push_back(row.col<const char *>(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<string> GameData::random_locations(unsigned count) const { |