aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2021-03-05 21:11:48 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2021-03-05 21:11:48 +0000
commitfdb004b9ce1a64552421ce5dcf1a0da4796f08c5 (patch)
tree730f41d2460154ab75b8f59c1dc3b37c319b4c4b
parent53851cbe0f11aac01b3dae769b3ea0755b28788a (diff)
downloadrspamd-fdb004b9ce1a64552421ce5dcf1a0da4796f08c5.tar.gz
rspamd-fdb004b9ce1a64552421ce5dcf1a0da4796f08c5.zip
[Project] Css: Rework flags of css properties
-rw-r--r--src/libserver/css/css_parser.hxx2
-rw-r--r--src/libserver/css/css_property.cxx9
-rw-r--r--src/libserver/css/css_property.hxx12
-rw-r--r--src/libserver/css/css_rule.cxx36
-rw-r--r--src/libserver/css/css_tokeniser.hxx7
-rw-r--r--src/libserver/css/css_value.hxx18
-rw-r--r--test/lua/unit/css.lua4
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 */