Validate _server.pbl files on upload against the schema (#7239)
This commit is contained in:
parent
77baa1efc7
commit
9fcfb04bde
6 changed files with 36 additions and 16 deletions
|
@ -274,7 +274,8 @@ bool addons_client::delete_remote_addon(const std::string& id, std::string& resp
|
|||
{
|
||||
response_message.clear();
|
||||
|
||||
config cfg = get_addon_pbl_info(id);
|
||||
// No point in validating when we're deleting it.
|
||||
config cfg = get_addon_pbl_info(id, false);
|
||||
|
||||
utils::string_map i18n_symbols;
|
||||
i18n_symbols["addon_title"] = font::escape_text(cfg["title"]);
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "filesystem.hpp"
|
||||
#include "log.hpp"
|
||||
#include "serialization/parser.hpp"
|
||||
#include "serialization/schema_validator.hpp"
|
||||
#include "game_version.hpp"
|
||||
#include "wml_exception.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
@ -65,15 +67,26 @@ bool have_addon_pbl_info(const std::string& addon_name)
|
|||
return filesystem::file_exists(get_pbl_file_path(addon_name));
|
||||
}
|
||||
|
||||
config get_addon_pbl_info(const std::string& addon_name)
|
||||
config get_addon_pbl_info(const std::string& addon_name, bool do_validate)
|
||||
{
|
||||
config cfg;
|
||||
const std::string& pbl_path = get_pbl_file_path(addon_name);
|
||||
try {
|
||||
filesystem::scoped_istream stream = filesystem::istream_file(pbl_path);
|
||||
read(cfg, *stream);
|
||||
std::unique_ptr<schema_validation::schema_validator> validator;
|
||||
if(do_validate) {
|
||||
validator = std::make_unique<schema_validation::schema_validator>(filesystem::get_wml_location("schema/pbl.cfg"));
|
||||
validator->set_create_exceptions(true);
|
||||
}
|
||||
read(cfg, *stream, validator.get());
|
||||
} catch(const config::error& e) {
|
||||
throw invalid_pbl_exception(pbl_path, e.message);
|
||||
} catch(wml_exception& e) {
|
||||
auto msg = e.user_message;
|
||||
e.user_message += " in " + addon_name;
|
||||
boost::replace_all(e.dev_message, "<unknown>", filesystem::sanitize_path(pbl_path));
|
||||
e.show();
|
||||
throw invalid_pbl_exception(pbl_path, msg);
|
||||
}
|
||||
|
||||
return cfg;
|
||||
|
@ -187,7 +200,8 @@ std::map<std::string, std::string> installed_addons_and_versions()
|
|||
for(const std::string& addon_id : installed_addons()) {
|
||||
if(have_addon_pbl_info(addon_id)) {
|
||||
try {
|
||||
addons[addon_id] = get_addon_pbl_info(addon_id)["version"].str();
|
||||
// Just grabbing the version, so don't bother validating the pbl
|
||||
addons[addon_id] = get_addon_pbl_info(addon_id, false)["version"].str();
|
||||
} catch(const invalid_pbl_exception&) {
|
||||
addons[addon_id] = "Invalid pbl file, version unknown";
|
||||
}
|
||||
|
|
|
@ -100,11 +100,12 @@ bool have_addon_in_vcs_tree(const std::string& addon_name);
|
|||
* Gets the publish information for an add-on.
|
||||
*
|
||||
* @param addon_name The add-on's main directory/file name.
|
||||
* @param do_validate Whether we want to run validation on the .pbl file.
|
||||
*
|
||||
* @exception invalid_pbl_exception If it is not possible to read the .pbl file
|
||||
* (often due to invalid WML).
|
||||
*/
|
||||
config get_addon_pbl_info(const std::string& addon_name);
|
||||
config get_addon_pbl_info(const std::string& addon_name, bool do_validate);
|
||||
|
||||
/**
|
||||
* Sets the publish information for an add-on.
|
||||
|
|
|
@ -40,7 +40,8 @@ addon_tracking_info get_addon_tracking_info(const addon_info& addon)
|
|||
t.remote_version = *addon.versions.begin();
|
||||
|
||||
// Try to obtain the version number from the .pbl first.
|
||||
config pbl = get_addon_pbl_info(id);
|
||||
// Just grabbing the version, no need to validate.
|
||||
config pbl = get_addon_pbl_info(id, false);
|
||||
|
||||
if(pbl.has_attribute("version")) {
|
||||
t.installed_version = pbl["version"].str();
|
||||
|
|
|
@ -456,7 +456,7 @@ void game_config_manager::load_addons_cfg()
|
|||
if(have_addon_pbl_info(addon_id)) {
|
||||
// Publishing info needs to be read from disk.
|
||||
try {
|
||||
metadata = get_addon_pbl_info(addon_id);
|
||||
metadata = get_addon_pbl_info(addon_id, false);
|
||||
} catch(const invalid_pbl_exception& e) {
|
||||
const std::string log_msg = formatter()
|
||||
<< "The provided addon has an invalid pbl file"
|
||||
|
|
|
@ -568,16 +568,18 @@ void addon_manager::load_addon_list()
|
|||
// to match add-ons in the config list. It also fills in addon_info's id field. It's also
|
||||
// neccessay to set local_only here so that flag can be properly set after addons_ is cleared
|
||||
// and recreated by read_addons_list.
|
||||
config pbl_cfg = get_addon_pbl_info(id);
|
||||
pbl_cfg["name"] = id;
|
||||
pbl_cfg["local_only"] = true;
|
||||
try {
|
||||
config pbl_cfg = get_addon_pbl_info(id, false);
|
||||
pbl_cfg["name"] = id;
|
||||
pbl_cfg["local_only"] = true;
|
||||
|
||||
// Add the add-on to the list.
|
||||
addon_info addon(pbl_cfg);
|
||||
addons_[id] = addon;
|
||||
// Add the add-on to the list.
|
||||
addon_info addon(pbl_cfg);
|
||||
addons_[id] = addon;
|
||||
|
||||
// Add the addon to the config entry
|
||||
cfg_.add_child("campaign", std::move(pbl_cfg));
|
||||
// Add the addon to the config entry
|
||||
cfg_.add_child("campaign", std::move(pbl_cfg));
|
||||
} catch(invalid_pbl_exception&) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,7 +909,8 @@ void addon_manager::publish_addon(const addon_info& addon)
|
|||
std::string server_msg;
|
||||
|
||||
const std::string addon_id = addon.id;
|
||||
config cfg = get_addon_pbl_info(addon_id);
|
||||
// Since the user is planning to upload an addon, this is the right time to validate the .pbl.
|
||||
config cfg = get_addon_pbl_info(addon_id, true);
|
||||
|
||||
const version_info& version_to_publish = cfg["version"].str();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue