aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/css
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2021-03-04 17:35:51 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2021-03-04 17:35:51 +0000
commitffc6fac92c4b8d10a05e35e59ee17b4f7b642406 (patch)
tree20759dc8444acb4a7d9b75032d931be6d8984dfb /src/libserver/css
parent8be8cf9bcd4047c17cf9f8b95b0831ecbf22d8ae (diff)
downloadrspamd-ffc6fac92c4b8d10a05e35e59ee17b4f7b642406.tar.gz
rspamd-ffc6fac92c4b8d10a05e35e59ee17b4f7b642406.zip
[Project] Css: Properties attachment logic
Diffstat (limited to 'src/libserver/css')
-rw-r--r--src/libserver/css/css_parser.hxx29
-rw-r--r--src/libserver/css/css_property.cxx6
-rw-r--r--src/libserver/css/css_property.hxx15
-rw-r--r--src/libserver/css/css_rule.cxx42
-rw-r--r--src/libserver/css/css_rule.hxx8
-rw-r--r--src/libserver/css/css_tokeniser.hxx3
-rw-r--r--src/libserver/css/css_value.cxx67
-rw-r--r--src/libserver/css/css_value.hxx5
8 files changed, 139 insertions, 36 deletions
diff --git a/src/libserver/css/css_parser.hxx b/src/libserver/css/css_parser.hxx
index 7530730e7..5b2d93ae5 100644
--- a/src/libserver/css/css_parser.hxx
+++ b/src/libserver/css/css_parser.hxx
@@ -56,7 +56,18 @@ public:
std::vector<consumed_block_ptr> args;
css_function_block(css_parser_token &&tok) :
- function(std::forward<css_parser_token>(tok)) {}
+ function(std::forward<css_parser_token>(tok)) {}
+
+ auto as_string() const -> const std::string_view & {
+ return function.get_string_or_default("");
+ }
+
+ static auto empty_function() -> const css_function_block & {
+ static const css_function_block invalid(
+ css_parser_token(css_parser_token::token_type::eof_token,
+ css_parser_token_placeholder()));
+ return invalid;
+ }
};
css_consumed_block() : tag(parser_tag_type::css_eof_block) {}
@@ -94,7 +105,7 @@ public:
const inline static std::vector<consumed_block_ptr> empty_block_vec{};
auto is_blocks_vec() const -> bool {
- return (content.index() == 1);
+ return (std::holds_alternative<std::vector<consumed_block_ptr>>(content));
}
auto get_blocks_or_empty() const -> const std::vector<consumed_block_ptr>& {
@@ -106,7 +117,7 @@ public:
}
auto is_token() const -> bool {
- return (content.index() == 2);
+ return (std::holds_alternative<css_parser_token>(content));
}
auto get_token_or_empty() const -> const css_parser_token& {
@@ -117,6 +128,18 @@ public:
return css_parser_eof_token();
}
+ auto is_function() const -> bool {
+ return (std::holds_alternative<css_function_block>(content));
+ }
+
+ auto get_function_or_invalid() const -> const css_function_block& {
+ if (is_token()) {
+ return std::get<css_function_block>(content);
+ }
+
+ return css_function_block::empty_function();
+ }
+
auto size() const -> std::size_t {
auto ret = 0;
diff --git a/src/libserver/css/css_property.cxx b/src/libserver/css/css_property.cxx
index 77927d724..1ef1ae009 100644
--- a/src/libserver/css/css_property.cxx
+++ b/src/libserver/css/css_property.cxx
@@ -20,9 +20,9 @@
namespace rspamd::css {
-constexpr const auto max_type = static_cast<int>(css_property_type::PROPERTY_NYI);
-constexpr frozen::unordered_map<frozen::string, css_property_type, max_type> type_map{
+constexpr const auto type_map = frozen::make_unordered_map<frozen::string, css_property_type>({
{"font", css_property_type::PROPERTY_FONT},
+ {"font-color", css_property_type::PROPERTY_FONT_COLOR},
{"color", css_property_type::PROPERTY_COLOR},
{"bgcolor", css_property_type::PROPERTY_BGCOLOR},
{"background", css_property_type::PROPERTY_BACKGROUND},
@@ -30,7 +30,7 @@ constexpr frozen::unordered_map<frozen::string, css_property_type, max_type> typ
{"width", css_property_type::PROPERTY_WIDTH},
{"display", css_property_type::PROPERTY_DISPLAY},
{"visibility", css_property_type::PROPERTY_VISIBILITY},
-};
+});
auto token_string_to_property(const std::string_view &inp) -> css_property_type {
diff --git a/src/libserver/css/css_property.hxx b/src/libserver/css/css_property.hxx
index 3d51bf99f..e529a8974 100644
--- a/src/libserver/css/css_property.hxx
+++ b/src/libserver/css/css_property.hxx
@@ -31,6 +31,7 @@ namespace rspamd::css {
*/
enum class css_property_type {
PROPERTY_FONT = 0,
+ PROPERTY_FONT_COLOR,
PROPERTY_COLOR,
PROPERTY_BGCOLOR,
PROPERTY_BACKGROUND,
@@ -53,6 +54,9 @@ struct css_property {
case css_property_type::PROPERTY_FONT:
ret = "font";
break;
+ case css_property_type::PROPERTY_FONT_COLOR:
+ ret = "font-color";
+ break;
case css_property_type::PROPERTY_COLOR:
ret = "color";
break;
@@ -80,6 +84,17 @@ struct css_property {
return ret;
}
+
+ constexpr auto is_color(void) const -> bool {
+ return type == css_property_type::PROPERTY_COLOR ||
+ type == css_property_type::PROPERTY_BACKGROUND ||
+ type == css_property_type::PROPERTY_BGCOLOR ||
+ type == css_property_type::PROPERTY_FONT_COLOR;
+ }
+ constexpr auto is_dimension(void) const -> bool {
+ return type == css_property_type::PROPERTY_HEIGHT ||
+ type == css_property_type::PROPERTY_WIDTH;
+ }
};
diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx
index 572033e1f..ce35dc6b0 100644
--- a/src/libserver/css/css_rule.cxx
+++ b/src/libserver/css/css_rule.cxx
@@ -18,6 +18,32 @@
namespace rspamd::css {
+static auto
+allowed_property_value(const css_property &prop, const css_consumed_block &parser_block)
+ -> std::optional<css_value>
+{
+ if (prop.is_color()) {
+ if (parser_block.is_token()) {
+ /* A single token */
+ const auto &tok = parser_block.get_token_or_empty();
+
+ if (tok.type == css_parser_token::token_type::hash_token) {
+ return css_value::maybe_color_from_hex(tok.get_string_or_default(""));
+ }
+ else if (tok.type == css_parser_token::token_type::string_token) {
+ return css_value::maybe_color_from_string(tok.get_string_or_default(""));
+ }
+ }
+ else if (parser_block.is_function()) {
+ const auto &func = parser_block.get_function_or_invalid();
+
+ return css_value::maybe_color_from_function(func);
+ }
+ }
+
+ return std::nullopt;
+}
+
auto process_declaration_tokens(rspamd_mempool_t *pool,
const blocks_gen_functor &next_block_functor)
-> declarations_vec
@@ -83,9 +109,12 @@ auto process_declaration_tokens(rspamd_mempool_t *pool,
}
}
- auto maybe_value = css_value::from_css_block(next_tok);
+ auto maybe_value = allowed_property_value(cur_property, next_tok);
if (maybe_value) {
+ msg_debug_css("added value %s to the property %s",
+ maybe_value.value().debug_str().c_str(),
+ cur_property.to_string());
cur_rule->add_value(maybe_value.value());
}
}
@@ -119,4 +148,15 @@ auto process_declaration_tokens(rspamd_mempool_t *pool,
return ret; /* copy elision */
}
+
+void css_rule::add_value(std::unique_ptr<css_value> &&value)
+{
+ values.emplace_back(std::forward<std::unique_ptr<css_value>>(value));
+}
+
+void css_rule::add_value(const css_value &value)
+{
+ values.emplace_back(std::make_unique<css_value>(css_value{value}));
+}
+
} \ No newline at end of file
diff --git a/src/libserver/css/css_rule.hxx b/src/libserver/css/css_rule.hxx
index 929c5b263..41a6ef3be 100644
--- a/src/libserver/css/css_rule.hxx
+++ b/src/libserver/css/css_rule.hxx
@@ -40,12 +40,8 @@ public:
prop(prop), values(std::forward<css_values_vec>(values)) {}
explicit css_rule(const css_property &prop) : prop(prop), values{} {}
/* Methods */
- void add_value(std::unique_ptr<css_value> &&value) {
- values.emplace_back(std::forward<std::unique_ptr<css_value>>(value));
- }
- void add_value(const css_value &value) {
- values.emplace_back(std::make_unique<css_value>(css_value{value}));
- }
+ void add_value(std::unique_ptr<css_value> &&value);
+ void add_value(const css_value &value);
constexpr const css_values_vec& get_values(void) const { return values; }
constexpr const css_property& get_prop(void) const { return prop; }
};
diff --git a/src/libserver/css/css_tokeniser.hxx b/src/libserver/css/css_tokeniser.hxx
index 70128e8c8..7f5505f15 100644
--- a/src/libserver/css/css_tokeniser.hxx
+++ b/src/libserver/css/css_tokeniser.hxx
@@ -99,7 +99,8 @@ struct css_parser_token {
css_parser_token(css_parser_token &&other) = default;
auto operator=(css_parser_token &&other) -> css_parser_token& = default;
auto adjust_dim(const css_parser_token &dim_token) -> bool;
- auto get_string_or_default(const std::string_view &def) const -> std::string_view {
+
+ auto get_string_or_default(const std::string_view &def) const -> const std::string_view & {
if (value.index() == 0) {
return std::get<std::string_view>(value);
}
diff --git a/src/libserver/css/css_value.cxx b/src/libserver/css/css_value.cxx
index ac65c7422..f00543615 100644
--- a/src/libserver/css/css_value.cxx
+++ b/src/libserver/css/css_value.cxx
@@ -240,41 +240,41 @@ static inline auto hsl_to_rgb(double h, double s, double l)
return ret;
}
-auto css_value::maybe_color_from_function(const std::string_view &func,
- const std::vector<css_parser_token> &args)
+auto css_value::maybe_color_from_function(const css_consumed_block::css_function_block &func)
-> std::optional<css_value>
{
- if (func == "rgb" && args.size() == 3) {
- css_color col{rgb_color_component_convert(args[0]),
- rgb_color_component_convert(args[1]),
- rgb_color_component_convert(args[2])};
+
+ if (func.as_string() == "rgb" && func.args.size() == 3) {
+ css_color col{rgb_color_component_convert(func.args[0]->get_token_or_empty()),
+ rgb_color_component_convert(func.args[1]->get_token_or_empty()),
+ rgb_color_component_convert(func.args[2]->get_token_or_empty())};
return css_value(col);
}
- else if (func == "rgba" && args.size() == 4) {
- css_color col{rgb_color_component_convert(args[0]),
- rgb_color_component_convert(args[1]),
- rgb_color_component_convert(args[2]),
- alpha_component_convert(args[3])};
+ else if (func.as_string() == "rgba" && func.args.size() == 4) {
+ css_color col{rgb_color_component_convert(func.args[0]->get_token_or_empty()),
+ rgb_color_component_convert(func.args[1]->get_token_or_empty()),
+ rgb_color_component_convert(func.args[2]->get_token_or_empty()),
+ alpha_component_convert(func.args[3]->get_token_or_empty())};
return css_value(col);
}
- else if (func == "hsl" && args.size() == 3) {
- auto h = h_component_convert(args[0]);
- auto s = sl_component_convert(args[1]);
- auto l = sl_component_convert(args[2]);
+ else if (func.as_string() == "hsl" && func.args.size() == 3) {
+ auto h = h_component_convert(func.args[0]->get_token_or_empty());
+ auto s = sl_component_convert(func.args[1]->get_token_or_empty());
+ auto l = sl_component_convert(func.args[2]->get_token_or_empty());
auto col = hsl_to_rgb(h, s, l);
return css_value(col);
}
- else if (func == "hsla" && args.size() == 4) {
- auto h = h_component_convert(args[0]);
- auto s = sl_component_convert(args[1]);
- auto l = sl_component_convert(args[2]);
+ else if (func.as_string() == "hsla" && func.args.size() == 4) {
+ auto h = h_component_convert(func.args[0]->get_token_or_empty());
+ auto s = sl_component_convert(func.args[1]->get_token_or_empty());
+ auto l = sl_component_convert(func.args[2]->get_token_or_empty());
auto col = hsl_to_rgb(h, s, l);
- col.alpha = alpha_component_convert(args[3]);
+ col.alpha = alpha_component_convert(func.args[3]->get_token_or_empty());
return css_value(col);
}
@@ -282,4 +282,31 @@ auto css_value::maybe_color_from_function(const std::string_view &func,
return std::nullopt;
}
+auto css_value::debug_str() const -> std::string
+{
+ std::string ret;
+
+ std::visit([&](auto& arg) {
+ using T = std::decay_t<decltype(arg)>;
+
+ if constexpr (std::is_same_v<T, css_color>) {
+ ret += "color: r=" + std::to_string(arg.r) +
+ "; g=" + std::to_string(arg.g) +
+ "; b=" + std::to_string(arg.b) +
+ "; a=" + std::to_string(arg.alpha);
+ }
+ else if constexpr (std::is_same_v<T, double>) {
+ ret += "size: " + std::to_string(arg);
+ }
+ else if constexpr (std::is_integral_v<T>) {
+ ret += "integral: " + std::to_string(static_cast<int>(arg));
+ }
+ else {
+ ret += "nyi";
+ }
+ }, value);
+
+ return ret;
+}
+
}
diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx
index 90ee4533d..a8152ed10 100644
--- a/src/libserver/css/css_value.hxx
+++ b/src/libserver/css/css_value.hxx
@@ -118,14 +118,15 @@ struct css_value {
return (type != css_value_type::CSS_VALUE_NYI);
}
+ auto debug_str() const -> std::string;
+
static auto from_css_block(const css_consumed_block &bl) -> tl::expected<css_value, css_parse_error>;
static auto maybe_color_from_string(const std::string_view &input)
-> std::optional<css_value>;
static auto maybe_color_from_hex(const std::string_view &input)
-> std::optional<css_value>;
- static auto maybe_color_from_function(const std::string_view &func,
- const std::vector<css_parser_token> &args)
+ static auto maybe_color_from_function(const css_consumed_block::css_function_block &func)
-> std::optional<css_value>;
};