diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-03-05 21:11:48 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-03-05 21:11:48 +0000 |
commit | fdb004b9ce1a64552421ce5dcf1a0da4796f08c5 (patch) | |
tree | 730f41d2460154ab75b8f59c1dc3b37c319b4c4b | |
parent | 53851cbe0f11aac01b3dae769b3ea0755b28788a (diff) | |
download | rspamd-fdb004b9ce1a64552421ce5dcf1a0da4796f08c5.tar.gz rspamd-fdb004b9ce1a64552421ce5dcf1a0da4796f08c5.zip |
[Project] Css: Rework flags of css properties
-rw-r--r-- | src/libserver/css/css_parser.hxx | 2 | ||||
-rw-r--r-- | src/libserver/css/css_property.cxx | 9 | ||||
-rw-r--r-- | src/libserver/css/css_property.hxx | 12 | ||||
-rw-r--r-- | src/libserver/css/css_rule.cxx | 36 | ||||
-rw-r--r-- | src/libserver/css/css_tokeniser.hxx | 7 | ||||
-rw-r--r-- | src/libserver/css/css_value.hxx | 18 | ||||
-rw-r--r-- | test/lua/unit/css.lua | 4 |
7 files changed, 58 insertions, 30 deletions
diff --git a/src/libserver/css/css_parser.hxx b/src/libserver/css/css_parser.hxx index 887d846ad..d0c378b0f 100644 --- a/src/libserver/css/css_parser.hxx +++ b/src/libserver/css/css_parser.hxx @@ -58,7 +58,7 @@ public: css_function_block(css_parser_token &&tok) : function(std::forward<css_parser_token>(tok)) {} - auto as_string() const -> const std::string_view & { + auto as_string() const -> std::string_view { return function.get_string_or_default(""); } diff --git a/src/libserver/css/css_property.cxx b/src/libserver/css/css_property.cxx index 1ef1ae009..b2578a367 100644 --- a/src/libserver/css/css_property.cxx +++ b/src/libserver/css/css_property.cxx @@ -32,7 +32,9 @@ constexpr const auto type_map = frozen::make_unordered_map<frozen::string, css_p {"visibility", css_property_type::PROPERTY_VISIBILITY}, }); -auto token_string_to_property(const std::string_view &inp) -> css_property_type { +auto token_string_to_property(const std::string_view &inp) + -> css_property_type +{ css_property_type ret = css_property_type::PROPERTY_NYI; @@ -45,12 +47,13 @@ auto token_string_to_property(const std::string_view &inp) -> css_property_type return ret; } -auto css_property::from_token(const css_parser_token &tok) -> tl::expected<css_property,css_parse_error> +auto css_property::from_token(const css_parser_token &tok) + -> tl::expected<css_property,css_parse_error> { if (tok.type == css_parser_token::token_type::ident_token) { auto sv = tok.get_string_or_default(""); - return css_property{token_string_to_property(sv)}; + return css_property{token_string_to_property(sv), css_property_flag::FLAG_NORMAL}; } return tl::unexpected{css_parse_error(css_parse_error_type::PARSE_ERROR_NYI)}; diff --git a/src/libserver/css/css_property.hxx b/src/libserver/css/css_property.hxx index e529a8974..670dfaddb 100644 --- a/src/libserver/css/css_property.hxx +++ b/src/libserver/css/css_property.hxx @@ -29,7 +29,7 @@ namespace rspamd::css { * To be extended with properties that are interesting from the email * point of view */ -enum class css_property_type { +enum class css_property_type : std::uint16_t { PROPERTY_FONT = 0, PROPERTY_FONT_COLOR, PROPERTY_COLOR, @@ -42,8 +42,16 @@ enum class css_property_type { PROPERTY_NYI, }; -struct css_property { +enum class css_property_flag : std::uint16_t { + FLAG_NORMAL, + FLAG_IMPORTANT, + FLAG_NOT_IMPORTANT +}; + +struct alignas(int) css_property { css_property_type type; + css_property_flag flag; + static tl::expected<css_property,css_parse_error> from_token( const css_parser_token &tok); diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx index 0e9924029..5bd99bd0e 100644 --- a/src/libserver/css/css_rule.cxx +++ b/src/libserver/css/css_rule.cxx @@ -50,8 +50,10 @@ auto process_declaration_tokens(rspamd_mempool_t *pool, { declarations_vec ret; bool can_continue = true; - css_property cur_property{css_property_type::PROPERTY_NYI}; - static const css_property bad_property{css_property_type::PROPERTY_NYI}; + css_property cur_property{css_property_type::PROPERTY_NYI, + css_property_flag::FLAG_NORMAL}; + static const css_property bad_property{css_property_type::PROPERTY_NYI, + css_property_flag::FLAG_NORMAL}; std::unique_ptr<css_rule> cur_rule; enum { @@ -60,6 +62,8 @@ auto process_declaration_tokens(rspamd_mempool_t *pool, ignore_value, /* For unknown properties */ } state = parse_property; + auto seen_not = false; + while (can_continue) { const auto &next_tok = next_block_functor(); @@ -105,8 +109,36 @@ auto process_declaration_tokens(rspamd_mempool_t *pool, if (parser_tok.type == css_parser_token::token_type::semicolon_token) { ret.push_back(std::move(cur_rule)); state = parse_property; + seen_not = false; continue; } + else if (parser_tok.type == css_parser_token::token_type::delim_token) { + if (parser_tok.get_string_or_default("") == "!") { + /* Probably something like !important */ + seen_not = true; + } + } + else if (parser_tok.type == css_parser_token::token_type::ident_token) { + if (parser_tok.get_string_or_default("") == "important") { + if (seen_not) { + msg_debug_css("add !important flag to property %s", + cur_property.to_string()); + cur_property.flag = css_property_flag::FLAG_NOT_IMPORTANT; + } + else { + msg_debug_css("add important flag to property %s", + cur_property.to_string()); + cur_property.flag = css_property_flag::FLAG_IMPORTANT; + } + + seen_not = false; + + continue; + } + else { + seen_not = false; + } + } } auto maybe_value = allowed_property_value(cur_property, next_tok); diff --git a/src/libserver/css/css_tokeniser.hxx b/src/libserver/css/css_tokeniser.hxx index 7f5505f15..3776b36e5 100644 --- a/src/libserver/css/css_tokeniser.hxx +++ b/src/libserver/css/css_tokeniser.hxx @@ -100,10 +100,13 @@ struct css_parser_token { 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 -> const std::string_view & { - if (value.index() == 0) { + auto get_string_or_default(const std::string_view &def) const -> std::string_view { + if (std::holds_alternative<std::string_view>(value)) { return std::get<std::string_view>(value); } + else if (std::holds_alternative<char>(value)) { + return std::string_view(&std::get<char>(value), 1); + } return def; } diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx index 5f9fa0cee..0e675e0ca 100644 --- a/src/libserver/css/css_value.hxx +++ b/src/libserver/css/css_value.hxx @@ -50,15 +50,6 @@ enum class css_display_value { }; /* - * CSS flags - */ -enum class css_flag_value { - FLAG_INHERIT, - FLAG_IMPORTANT, - FLAG_NOTIMPORTANT -}; - -/* * Value handler, uses std::variant instead of polymorphic classes for now * for simplicity */ @@ -74,7 +65,6 @@ struct css_value { std::variant<css_color, double, css_display_value, - css_flag_value, std::monostate> value; css_value(const css_color &color) : @@ -106,14 +96,6 @@ struct css_value { return std::nullopt; } - constexpr std::optional<css_flag_value> to_flag(void) const { - if (type == css_value_type::CSS_VALUE_FLAG) { - return std::get<css_flag_value>(value); - } - - return std::nullopt; - } - constexpr bool is_valid(void) const { return (type != css_value_type::CSS_VALUE_NYI); } diff --git a/test/lua/unit/css.lua b/test/lua/unit/css.lua index 4bd78b244..86119641e 100644 --- a/test/lua/unit/css.lua +++ b/test/lua/unit/css.lua @@ -100,8 +100,8 @@ body { ]], [[ /* Colors */ -* { color: hsl(0, 100%, 50%) } /* red */ -* { color: hsl(120, 100%, 50%) } /* lime */ +* { color: hsl(0, 100%, 50%) !important } /* red */ +* { color: hsl(120, 100%, 50%) important } /* lime */ * { color: hsl(120, 100%, 25%) } /* dark green */ * { color: hsl(120, 100%, 75%) } /* light green */ * { color: hsl(120, 75%, 75%) } /* pastel green, and so on */ |