]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Css: Add parser helpers to simplify debugging
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 16 Mar 2021 20:40:57 +0000 (20:40 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 16 Mar 2021 20:40:57 +0000 (20:40 +0000)
src/libserver/css/css_parser.cxx
src/libserver/css/css_parser.hxx

index 915e04f123a3f35e4fb0507c359a1764c744b25d..f6029739a3ecdcb2873d893e6e199222521c3d6e 100644 (file)
@@ -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<css_consumed_block> consume_css_blocks(const std::string_view &sv);
        bool consume_input(const std::string_view &sv);
 
        auto get_object_maybe(void) -> tl::expected<std::unique_ptr<css_style_sheet>, css_parse_error> {
@@ -512,7 +513,8 @@ auto css_parser::component_value_consumer(std::unique_ptr<css_consumed_block> &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<css_consumed_block>
 {
        tokeniser = std::make_unique<css_tokeniser>(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<css_consumed_block> 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);
        }
 }
-
 }
index f51960b71d874c12a659ab19ac4426bf71ecf0b0..4dbcd9f682882b656827f0d18191a1d297890ddc 100644 (file)
@@ -184,9 +184,12 @@ extern const css_consumed_block css_parser_eof_block;
 
 using blocks_gen_functor = std::function<const css_consumed_block &(void)>;
 
-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