Schema: Some infinite loop avoidance
- Detect obvious cases of inheritance loops - Don't try to keep track of tags with a super tag that exist within a conditional tag - When searching for a tag path, don't append the leaf to the full path
This commit is contained in:
parent
6c30ef4b20
commit
b57b1188c0
2 changed files with 30 additions and 4 deletions
|
@ -158,6 +158,19 @@ static void duplicate_key_error(const std::string& file,
|
|||
print_output(ss.str(), flag_exception);
|
||||
}
|
||||
|
||||
static void inheritance_loop_error(const std::string& file,
|
||||
int line,
|
||||
const std::string& tag,
|
||||
const std::string& key,
|
||||
const std::string& value,
|
||||
int index,
|
||||
bool flag_exception)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Inheritance loop " << key << "=" << value << " found (at offset " << index << ") in tag [" << tag << "]\n" << at(file, line) << "\n";
|
||||
print_output(ss.str(), flag_exception);
|
||||
}
|
||||
|
||||
static void wrong_type_error(const std::string & file, int line,
|
||||
const std::string & tag,
|
||||
const std::string & key,
|
||||
|
@ -464,11 +477,14 @@ bool schema_self_validator::tag_path_exists(const config& cfg, const reference&
|
|||
suffix = path.back();
|
||||
//suffix = link->second + "/" + suffix;
|
||||
} else {
|
||||
auto supers = derivations_.equal_range(prefix);
|
||||
const auto supers = derivations_.equal_range(prefix);
|
||||
if(supers.first != supers.second) {
|
||||
reference super_ref = ref;
|
||||
for( ; supers.first != supers.second; ++supers.first) {
|
||||
super_ref.value_ = supers.first->second + "/" + suffix;
|
||||
for(auto cur = supers.first ; cur != supers.second; ++cur) {
|
||||
super_ref.value_ = cur->second + "/" + suffix;
|
||||
if(super_ref.value_.find(ref.value_) == 0) {
|
||||
continue;
|
||||
}
|
||||
if(tag_path_exists(cfg, super_ref)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -588,6 +604,13 @@ void schema_self_validator::validate_key(const config& cfg, const std::string& n
|
|||
} else if(tag_name == "tag" && name == "super") {
|
||||
for(auto super : utils::split(cfg["super"])) {
|
||||
referenced_tag_paths_.emplace_back(super, file, start_line, tag_name);
|
||||
if(condition_nesting_ > 0) {
|
||||
continue;
|
||||
}
|
||||
if(current_path() == super) {
|
||||
queue_message(cfg, SUPER_LOOP, file, start_line, cfg["super"].str().find(super), tag_name, "super", super);
|
||||
continue;
|
||||
}
|
||||
derivations_.emplace(current_path(), super);
|
||||
}
|
||||
} else if(condition_nesting_ == 0 && tag_name == "tag" && name == "name") {
|
||||
|
@ -643,6 +666,9 @@ void schema_self_validator::print(message_info& el)
|
|||
case DUPLICATE_KEY:
|
||||
duplicate_key_error(el.file, el.line, el.tag, el.key, el.value, create_exceptions_);
|
||||
break;
|
||||
case SUPER_LOOP:
|
||||
inheritance_loop_error(el.file, el.line, el.tag, el.key, el.value, el.n, create_exceptions_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ private:
|
|||
static bool name_matches(const std::string& pattern, const std::string& name);
|
||||
|
||||
void print(message_info& message) override;
|
||||
enum { WRONG_TYPE = NEXT_ERROR, WRONG_PATH, DUPLICATE_TAG, DUPLICATE_KEY, NEXT_ERROR };
|
||||
enum { WRONG_TYPE = NEXT_ERROR, WRONG_PATH, DUPLICATE_TAG, DUPLICATE_KEY, SUPER_LOOP, NEXT_ERROR };
|
||||
};
|
||||
|
||||
} // namespace schema_validation{
|
||||
|
|
Loading…
Add table
Reference in a new issue