]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Css: Rework flags of css properties
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Mar 2021 21:11:48 +0000 (21:11 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Mar 2021 21:11:48 +0000 (21:11 +0000)
src/libserver/css/css_parser.hxx
src/libserver/css/css_property.cxx
src/libserver/css/css_property.hxx
src/libserver/css/css_rule.cxx
src/libserver/css/css_tokeniser.hxx
src/libserver/css/css_value.hxx
test/lua/unit/css.lua

index 887d846ad35e7d58e88a2586ff0d650812bb1aeb..d0c378b0f1477fad5ca893bf4081687b78cd5e96 100644 (file)
@@ -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("");
                }
 
index 1ef1ae00929030dddb5b51078a0022656cbe73ce..b2578a367aa147a39a7ebc1cffec35e1ce35cc67 100644 (file)
@@ -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)};
index e529a897420bf6c1af1a66de3d536e5a336111c1..670dfaddb771961906e41d2449cb74a6927e5901 100644 (file)
@@ -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);
 
index 0e99240299ccbc429176a19f9d8ea8e2de3c5484..5bd99bd0edf70b2bc24db979a08e62e8ae35685a 100644 (file)
@@ -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);
index 7f5505f15c057b54c4b1868448efe1281604279f..3776b36e52c5e82599541cce5e63680aa0f4e8bf 100644 (file)
@@ -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;
        }
index 5f9fa0cee958faea9bc13d38022b830fee59ffa4..0e675e0ca1f6af1db28b20515fd0c265b14507b6 100644 (file)
@@ -49,15 +49,6 @@ enum class css_display_value {
        DISPLAY_HIDDEN
 };
 
-/*
- * 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);
        }
index 4bd78b244031549efb130c3627b15771d61f2c62..86119641eba7058324a852e652490e684618f706 100644 (file)
@@ -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 */