commit daa4ca9: [Minor] Fix tags based selectors

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Jun 16 14:28:06 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-06-16 14:49:05 +0100
URL: https://github.com/rspamd/rspamd/commit/daa4ca9561c5a06a99b1995793f3511271bf4cc2

[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<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;
 	}
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<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",
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>(
-							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}},
 		};
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<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 {


More information about the Commits mailing list