don't allow strange characters in unit type ids.
Using characters like " or ' in unit type ids has a high change of breaking code, in particular the statistics code assumes that the unit type ids can be used as wml varaible keys.
This commit is contained in:
parent
bbc32856f1
commit
69fb6aa9e7
3 changed files with 42 additions and 5 deletions
|
@ -157,6 +157,8 @@ unit_type::unit_type(const config &cfg, const std::string & parent_id) :
|
|||
animations_(),
|
||||
build_status_(NOT_BUILT)
|
||||
{
|
||||
check_id(id_);
|
||||
check_id(base_id_);
|
||||
gender_types_[0] = nullptr;
|
||||
gender_types_[1] = nullptr;
|
||||
}
|
||||
|
@ -1287,6 +1289,28 @@ const unit_race *unit_type_data::find_race(const std::string &key) const
|
|||
return i != races_.end() ? &i->second : nullptr;
|
||||
}
|
||||
|
||||
void unit_type::check_id(std::string& id)
|
||||
{
|
||||
assert(!id.empty());
|
||||
//we don't allow leading whitepaces
|
||||
if (id[0] == ' ') {
|
||||
throw error("Found unit type id with a leading whitespace \"" + id + "\"");
|
||||
}
|
||||
bool gave_wanrning = false;
|
||||
for (size_t pos = 0; pos < id.size(); ++pos) {
|
||||
const char c = id[pos];
|
||||
const bool valid = c == '_' || c == ' ' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
|
||||
if (!valid) {
|
||||
if (!gave_wanrning) {
|
||||
ERR_UT << "Found unit type id with invalid chracters: \"" << id << "\"\n";
|
||||
gave_wanrning = true;
|
||||
}
|
||||
id[pos] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unit_type_data unit_types;
|
||||
|
||||
|
||||
|
@ -1316,3 +1340,4 @@ void adjust_profile(std::string& profile)
|
|||
profile = temp;
|
||||
}
|
||||
}
|
||||
static void check_id(std::string& id);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "units/race.hpp"
|
||||
#include "units/attack_type.hpp"
|
||||
#include "util.hpp"
|
||||
#include "game_errors.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <map>
|
||||
|
@ -38,6 +39,14 @@ typedef std::map<std::string, movetype> movement_type_map;
|
|||
class unit_type
|
||||
{
|
||||
public:
|
||||
class error : public game::game_error
|
||||
{
|
||||
public:
|
||||
error(const std::string& msg)
|
||||
: game::game_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a unit type for the given config, but delays its build
|
||||
* till later.
|
||||
|
@ -53,6 +62,7 @@ public:
|
|||
/// These are in order of increasing levels of being built.
|
||||
/// HELP_INDEX is already defined in a windows header under some conditions.
|
||||
enum BUILD_STATUS {NOT_BUILT, CREATED, VARIATIONS, HELP_INDEXED, FULL};
|
||||
static void check_id(std::string& id);
|
||||
private: // These will be called by build().
|
||||
/// Load data into an empty unit_type (build to FULL).
|
||||
void build_full(const movement_type_map &movement_types,
|
||||
|
|
|
@ -195,11 +195,13 @@ void intrusive_ptr_release(const unit * u)
|
|||
*/
|
||||
static const unit_type &get_unit_type(const std::string &type_id)
|
||||
{
|
||||
if ( type_id.empty() )
|
||||
throw game::game_error("creating unit with an empty type field");
|
||||
|
||||
const unit_type *i = unit_types.find(type_id);
|
||||
if (!i) throw game::game_error("unknown unit type: " + type_id);
|
||||
if (type_id.empty()) {
|
||||
throw unit_type::error("creating unit with an empty type field");
|
||||
}
|
||||
std::string new_id = type_id;
|
||||
unit_type::check_id(new_id);
|
||||
const unit_type *i = unit_types.find(new_id);
|
||||
if (!i) throw unit_type::error("unknown unit type: " + type_id);
|
||||
return *i;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue