From 854bac0269b45a53fb75c6796205f0791236eb49 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 16 Mar 2021 20:40:57 +0000 Subject: [PATCH] [Project] Css: Add parser helpers to simplify debugging --- src/libserver/css/css_parser.cxx | 53 +++++++++++++++++++++++++++++--- src/libserver/css/css_parser.hxx | 5 ++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/libserver/css/css_parser.cxx b/src/libserver/css/css_parser.cxx index 915e04f12..f6029739a 100644 --- a/src/libserver/css/css_parser.cxx +++ b/src/libserver/css/css_parser.cxx @@ -147,6 +147,7 @@ public: css_parser(void) = delete; /* Require mempool to be set for logging */ explicit css_parser(rspamd_mempool_t *pool) : pool (pool) {} + std::unique_ptr consume_css_blocks(const std::string_view &sv); bool consume_input(const std::string_view &sv); auto get_object_maybe(void) -> tl::expected, css_parse_error> { @@ -512,7 +513,8 @@ auto css_parser::component_value_consumer(std::unique_ptr &t return ret; } -bool css_parser::consume_input(const std::string_view &sv) +auto +css_parser::consume_css_blocks(const std::string_view &sv) -> std::unique_ptr { tokeniser = std::make_unique(pool, sv); auto ret = true; @@ -542,8 +544,20 @@ bool css_parser::consume_input(const std::string_view &sv) } + tokeniser.reset(nullptr); /* No longer needed */ + + return consumed_blocks; +} + +bool css_parser::consume_input(const std::string_view &sv) +{ + auto &&consumed_blocks = consume_css_blocks(sv); const auto &rules = consumed_blocks->get_blocks_or_empty(); + if (rules.empty()) { + return false; + } + for (auto &&rule : rules) { /* * For now, we do not need any of the at rules, so we can safely ignore them @@ -610,11 +624,43 @@ bool css_parser::consume_input(const std::string_view &sv) auto debug_str = consumed_blocks->debug_str(); msg_debug_css("consumed css: {%*s}", (int)debug_str.size(), debug_str.data()); - tokeniser.reset(nullptr); /* No longer needed */ + return true; +} - return ret; +auto +get_selectors_parser_functor(rspamd_mempool_t *pool, + const std::string_view &st) -> blocks_gen_functor +{ + css_parser parser(pool); + + /* + * We use shared ptr here to avoid std::function limitation around + * unique_ptr due to copyable of std::function + * Hence, to elongate consumed_blocks lifetime we need to copy them + * inside lambda. + */ + std::shared_ptr consumed_blocks = parser.consume_css_blocks(st); + const auto &rules = consumed_blocks->get_blocks_or_empty(); + + auto rules_it = rules.begin(); + auto &&children = (*rules_it)->get_blocks_or_empty(); + auto cur = children.begin(); + auto last = children.end(); + + return [cur, consumed_blocks, last](void) mutable -> const css_consumed_block & { + if (cur != last) { + const auto &ret = (*cur); + + ++cur; + + return *ret; + } + + return css_parser_eof_block; + }; } + /* * Wrapper for the parser */ @@ -673,5 +719,4 @@ TEST_SUITE("css parser") { rspamd_mempool_delete(pool); } } - } diff --git a/src/libserver/css/css_parser.hxx b/src/libserver/css/css_parser.hxx index f51960b71..4dbcd9f68 100644 --- a/src/libserver/css/css_parser.hxx +++ b/src/libserver/css/css_parser.hxx @@ -184,9 +184,12 @@ extern const css_consumed_block css_parser_eof_block; using blocks_gen_functor = std::function; -auto parse_css (rspamd_mempool_t *pool, const std::string_view &st) -> +auto parse_css(rspamd_mempool_t *pool, const std::string_view &st) -> bool; +auto get_selectors_parser_functor(rspamd_mempool_t *pool, + const std::string_view &st) -> blocks_gen_functor; + } #endif //RSPAMD_CSS_PARSER_HXX -- 2.39.5