]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Fix tags based selectors
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Jun 2021 13:49:05 +0000 (14:49 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Jun 2021 13:49:05 +0000 (14:49 +0100)
src/libserver/css/css.cxx
src/libserver/css/css_parser.cxx
src/libserver/css/css_selector.cxx
src/libserver/css/css_selector.hxx

index c6814834187cd9eeaf997d79790a784bc781e316..55d77824497101e6f3981cd75e2b574a2683e270 100644 (file)
@@ -72,7 +72,7 @@ css_style_sheet::add_selector_rule(std::unique_ptr<css_selector> &&selector,
        case css_selector::selector_type::SELECTOR_ID:
                target_hash = &pimpl->id_selectors;
                break;
-       case css_selector::selector_type::SELECTOR_ELEMENT:
+       case css_selector::selector_type::SELECTOR_TAG:
                target_hash = &pimpl->tags_selector;
                break;
        }
index 6526ebc57173ded65859afb9d591fdb6a80de79e..6943e1cf62d1d08404c66c7b6d187331e44e00eb 100644 (file)
@@ -774,14 +774,9 @@ auto parse_css(rspamd_mempool_t *pool, const std::string_view &st,
        }
        else {
                /* Lowercase inplace */
-               auto *nspace = reinterpret_cast<char *>(rspamd_mempool_alloc(pool, st.length()));
-               auto *p = nspace;
-
-               for (const auto c : st) {
-                       *p++ = g_ascii_tolower(c);
-               }
-
-               processed_input = std::string_view{nspace, (std::size_t)(p - nspace)};
+               auto *nspace = rspamd_mempool_alloc_buffer(pool, st.size());
+               rspamd_str_copy_lc(st.data(), nspace, st.size());
+               processed_input = std::string_view{nspace, st.size()};
        }
 
        if (parser.consume_input(processed_input)) {
@@ -825,7 +820,7 @@ parse_css_declaration(rspamd_mempool_t *pool, const std::string_view &st)
 TEST_SUITE("css parser") {
        TEST_CASE("parse colors") {
                const std::vector<const char *> cases{
-                       "p { color: rgb(100%, 50%, 0%); opacity: -1; width: 1em; display: none; } /* very transparent solid orange */",
+                       "P { CoLoR: rgb(100%, 50%, 0%); opacity: -1; width: 1em; display: none; } /* very transparent solid orange ั‚ะตัั‚ */",
                        "p { color: rgb(100%, 50%, 0%); opacity: 2; display: inline; } /* very transparent solid orange */",
                        "p { color: rgb(100%, 50%, 0%); opacity: 0.5; } /* very transparent solid orange */\n",
                        "p { color: rgb(100%, 50%, 0%); opacity: 1; width: 99%; } /* very transparent solid orange */\n",
index de7b9afac0b1b9fe3c567c33dc21ea53b190e5a7..a4e1eb566ec1ecc01cb560e2db8f49f4516b1a96 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "css_selector.hxx"
 #include "css.hxx"
+#include "libserver/html/html.hxx"
 #include "fmt/core.h"
 #define DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
 #include "doctest/doctest.h"
@@ -73,12 +74,15 @@ auto process_selector_tokens(rspamd_mempool_t *pool,
                                        }
                                        break;
                                }
-                               case css_parser_token::token_type::ident_token:
-                                       cur_selector = std::make_unique<css_selector>(
-                                                       css_selector::selector_type::SELECTOR_ELEMENT);
-                                       cur_selector->value = parser_tok.get_string_or_default("");
+                               case css_parser_token::token_type::ident_token: {
+                                       auto tag_id = html::html_tag_by_name(parser_tok.get_string_or_default(""));
+
+                                       if (tag_id) {
+                                               cur_selector = std::make_unique<css_selector>(tag_id.value());
+                                       }
                                        state = selector_process_state::selector_ident_consumed;
                                        break;
+                               }
                                case css_parser_token::token_type::hash_token:
                                        cur_selector = std::make_unique<css_selector>(
                                                        css_selector::selector_type::SELECTOR_ID);
@@ -109,7 +113,7 @@ auto process_selector_tokens(rspamd_mempool_t *pool,
                                }
                        }
                        else if (state == selector_process_state::selector_ident_consumed) {
-                               if (parser_tok.type == css_parser_token::token_type::comma_token) {
+                               if (parser_tok.type == css_parser_token::token_type::comma_token && cur_selector) {
                                        /* Got full selector, attach it to the vector and go further */
                                        msg_debug_css("attached selector: %s", cur_selector->debug_str().c_str());
                                        ret.push_back(std::move(cur_selector));
@@ -130,7 +134,7 @@ auto process_selector_tokens(rspamd_mempool_t *pool,
                        }
                        else {
                                /* Ignore state; ignore all till ',' token or eof token */
-                               if (parser_tok.type == css_parser_token::token_type::comma_token) {
+                               if (parser_tok.type == css_parser_token::token_type::comma_token && cur_selector) {
                                        /* Got full selector, attach it to the vector and go further */
                                        ret.push_back(std::move(cur_selector));
                                        state = selector_process_state::selector_parse_start;
@@ -190,11 +194,11 @@ css_selector::debug_str() const -> std::string
 TEST_SUITE("css selectors") {
        TEST_CASE("simple css selectors") {
                const std::vector<std::pair<const char *, std::vector<css_selector::selector_type>>> cases{
-                               {"em", {css_selector::selector_type::SELECTOR_ELEMENT}},
+                               {"em", {css_selector::selector_type::SELECTOR_TAG}},
                                {"*", {css_selector::selector_type::SELECTOR_ALL}},
                                {".class", {css_selector::selector_type::SELECTOR_CLASS}},
                                {"#id", {css_selector::selector_type::SELECTOR_ID}},
-                               {"em,.class,#id", {css_selector::selector_type::SELECTOR_ELEMENT,
+                               {"em,.class,#id", {css_selector::selector_type::SELECTOR_TAG,
                                                                   css_selector::selector_type::SELECTOR_CLASS,
                                                                   css_selector::selector_type::SELECTOR_ID}},
                };
index 1e814573269661476732df82ca779e2083123983..9bab9e61bce20ff6d000e5cb12c9e9071da1aafe 100644 (file)
@@ -38,7 +38,7 @@ namespace rspamd::css {
  */
 struct css_selector {
        enum class selector_type {
-               SELECTOR_ELEMENT, /* e.g. tr, for this value we use tag_id_t */
+               SELECTOR_TAG, /* e.g. tr, for this value we use tag_id_t */
                SELECTOR_CLASS, /* generic class, e.g. .class */
                SELECTOR_ID, /* e.g. #id */
                SELECTOR_ALL /* * selector */
@@ -61,21 +61,21 @@ struct css_selector {
        std::vector<css_selector_dep> dependencies;
 
         auto to_tag(void) const -> std::optional<tag_id_t> {
-               if (type == selector_type::SELECTOR_ELEMENT) {
+               if (type == selector_type::SELECTOR_TAG) {
                        return std::get<tag_id_t>(value);
                }
                return std::nullopt;
        }
 
        auto to_string(void) const -> std::optional<const std::string_view> {
-               if (type != selector_type::SELECTOR_ELEMENT) {
+               if (type != selector_type::SELECTOR_TAG) {
                        return std::string_view(std::get<std::string_view>(value));
                }
                return std::nullopt;
        };
 
        explicit css_selector(selector_type t) : type(t) {}
-       explicit css_selector(tag_id_t t) : type(selector_type::SELECTOR_ELEMENT) {
+       explicit css_selector(tag_id_t t) : type(selector_type::SELECTOR_TAG) {
                value = t;
        }
        explicit css_selector(const std::string_view &st, selector_type t = selector_type::SELECTOR_ID) : type(t) {
@@ -107,7 +107,7 @@ template<>
 class hash<rspamd::css::css_selector> {
 public:
        auto operator() (const rspamd::css::css_selector &sel) const -> auto {
-               if (sel.type == rspamd::css::css_selector::selector_type::SELECTOR_ELEMENT) {
+               if (sel.type == rspamd::css::css_selector::selector_type::SELECTOR_TAG) {
                        return static_cast<std::uint64_t>(std::get<tag_id_t>(sel.value));
                }
                else {