From 3055ee89fcdef37bb1dcce16a6a378f2f29228af Mon Sep 17 00:00:00 2001 From: Paul Harris Date: Thu, 17 Oct 2024 01:51:21 +0800 Subject: [PATCH] Check start tags were matched to an end tag --- include/crow/mustache.h | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/include/crow/mustache.h b/include/crow/mustache.h index 50ffda20a..efc3b7fdf 100644 --- a/include/crow/mustache.h +++ b/include/crow/mustache.h @@ -118,8 +118,12 @@ namespace crow // NOTE: Already documented in "crow/app.h" int end; int pos; ActionType t; - Action(ActionType t_, size_t start_, size_t end_, size_t pos_ = 0): - start(static_cast(start_)), end(static_cast(end_)), pos(static_cast(pos_)), t(t_) + bool was_matched() const { return pos >= 0; } + + // note: pos is only needed for start/end tags. for regular tags, set pos=0, + // so we can check if any start tags were not matched to an end tag. + Action(ActionType t_, size_t start_, size_t end_, int pos_ = -1): + start(static_cast(start_)), end(static_cast(end_)), pos(pos_), t(t_) { } }; @@ -483,7 +487,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" if (idx == body_.npos) { fragments_.emplace_back(static_cast(current), static_cast(body_.size())); - actions_.emplace_back(ActionType::Ignore, 0, 0); + actions_.emplace_back(ActionType::Ignore, 0, 0, 0); break; } fragments_.emplace_back(static_cast(current), static_cast(idx)); @@ -565,7 +569,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" idx++; while (body_[endIdx - 1] == ' ') endIdx--; - actions_.emplace_back(ActionType::UnescapeTag, idx, endIdx); + actions_.emplace_back(ActionType::UnescapeTag, idx, endIdx, 0); current++; break; case '&': @@ -620,11 +624,21 @@ namespace crow // NOTE: Already documented in "crow/app.h" idx++; while (body_[endIdx - 1] == ' ') endIdx--; - actions_.emplace_back(ActionType::Tag, idx, endIdx); + actions_.emplace_back(ActionType::Tag, idx, endIdx, 0); break; } } + // ensure no unmatched tags + for (int i = 0; i < actions_.size(); i++) + { + if (!actions_[i].was_matched()) + { + throw invalid_template_exception("not matched {{# {{/ pair: " + + body_.substr(actions_[i].start, actions_[i].end - actions_[i].start)); + } + } + // removing standalones for (int i = actions_.size() - 2; i >= 0; i--) {