From daa4ca9561c5a06a99b1995793f3511271bf4cc2 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 16 Jun 2021 14:49:05 +0100 Subject: [PATCH] [Minor] Fix tags based selectors --- src/libserver/css/css.cxx | 2 +- src/libserver/css/css_parser.cxx | 13 ++++--------- src/libserver/css/css_selector.cxx | 20 ++++++++++++-------- src/libserver/css/css_selector.hxx | 10 +++++----- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/libserver/css/css.cxx b/src/libserver/css/css.cxx index c68148341..55d778244 100644 --- a/src/libserver/css/css.cxx +++ b/src/libserver/css/css.cxx @@ -72,7 +72,7 @@ css_style_sheet::add_selector_rule(std::unique_ptr &&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; } diff --git a/src/libserver/css/css_parser.cxx b/src/libserver/css/css_parser.cxx index 6526ebc57..6943e1cf6 100644 --- a/src/libserver/css/css_parser.cxx +++ b/src/libserver/css/css_parser.cxx @@ -774,14 +774,9 @@ auto parse_css(rspamd_mempool_t *pool, const std::string_view &st, } else { /* Lowercase inplace */ - auto *nspace = reinterpret_cast(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 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", diff --git a/src/libserver/css/css_selector.cxx b/src/libserver/css/css_selector.cxx index de7b9afac..a4e1eb566 100644 --- a/src/libserver/css/css_selector.cxx +++ b/src/libserver/css/css_selector.cxx @@ -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::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(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::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>> 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}}, }; diff --git a/src/libserver/css/css_selector.hxx b/src/libserver/css/css_selector.hxx index 1e8145732..9bab9e61b 100644 --- a/src/libserver/css/css_selector.hxx +++ b/src/libserver/css/css_selector.hxx @@ -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 dependencies; auto to_tag(void) const -> std::optional { - if (type == selector_type::SELECTOR_ELEMENT) { + if (type == selector_type::SELECTOR_TAG) { return std::get(value); } return std::nullopt; } auto to_string(void) const -> std::optional { - if (type != selector_type::SELECTOR_ELEMENT) { + if (type != selector_type::SELECTOR_TAG) { return std::string_view(std::get(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 { 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::get(sel.value)); } else { -- 2.39.5