This commit is contained in:
yhirose 2022-06-16 21:34:21 -04:00
parent af43f1f18a
commit f6b1a7380d

View File

@ -1950,8 +1950,9 @@ private:
};
struct HasEmptyElement : public Ope::Visitor {
HasEmptyElement(std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {}
HasEmptyElement(std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {}
void visit(Sequence &ope) override;
void visit(PrioritizedChoice &ope) override {
@ -1993,17 +1994,20 @@ private:
tie(error_s, error_name) = refs_.back();
}
std::vector<std::pair<const char *, std::string>> &refs_;
std::unordered_map<std::string, bool> &has_error_cache_;
};
struct DetectInfiniteLoop : public Ope::Visitor {
DetectInfiniteLoop(const char *s, const std::string &name,
std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {
std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {
refs_.emplace_back(s, name);
}
DetectInfiniteLoop(std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {}
DetectInfiniteLoop(std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {}
void visit(Sequence &ope) override {
for (auto op : ope.opes_) {
@ -2019,7 +2023,7 @@ struct DetectInfiniteLoop : public Ope::Visitor {
}
void visit(Repetition &ope) override {
if (ope.max_ == std::numeric_limits<size_t>::max()) {
HasEmptyElement vis(refs_);
HasEmptyElement vis(refs_, has_error_cache_);
ope.ope_->accept(vis);
if (vis.is_empty) {
has_error = true;
@ -2049,7 +2053,7 @@ struct DetectInfiniteLoop : public Ope::Visitor {
private:
std::vector<std::pair<const char *, std::string>> &refs_;
std::unordered_map<std::string, bool> has_error_cache_;
std::unordered_map<std::string, bool> &has_error_cache_;
};
struct ReferenceChecker : public Ope::Visitor {
@ -3041,7 +3045,7 @@ inline void HasEmptyElement::visit(Sequence &ope) {
if (!is_empty) {
++it;
while (it != ope.opes_.end()) {
DetectInfiniteLoop vis(refs_);
DetectInfiniteLoop vis(refs_, has_error_cache_);
(*it)->accept(vis);
if (vis.has_error) {
is_empty = true;
@ -4048,7 +4052,8 @@ private:
bool detect_infiniteLoop(const Data &data, Definition &rule, const Log &log,
const char *s) const {
std::vector<std::pair<const char *, std::string>> refs;
DetectInfiniteLoop vis(data.start_pos, rule.name, refs);
std::unordered_map<std::string, bool> has_error_cache;
DetectInfiniteLoop vis(data.start_pos, rule.name, refs, has_error_cache);
rule.accept(vis);
if (vis.has_error) {
if (log) {