commit 7e99c50: [Project] Css: Add dimensions handling

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Mar 9 13:00:07 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-03-09 12:49:11 +0000
URL: https://github.com/rspamd/rspamd/commit/7e99c501c808a2338017246203b76761cb271fe7

[Project] Css: Add dimensions handling

---
 src/libserver/css/css_property.cxx |  9 ++++++---
 src/libserver/css/css_property.hxx |  7 +++++--
 src/libserver/css/css_rule.cxx     | 14 +++++++++-----
 src/libserver/css/css_value.cxx    | 29 +++++++++++++++++++++++++++++
 src/libserver/css/css_value.hxx    | 28 +++++++++++++++++++++++-----
 test/lua/unit/css.lua              |  5 ++++-
 6 files changed, 76 insertions(+), 16 deletions(-)

diff --git a/src/libserver/css/css_property.cxx b/src/libserver/css/css_property.cxx
index 54e927057..2a463f8da 100644
--- a/src/libserver/css/css_property.cxx
+++ b/src/libserver/css/css_property.cxx
@@ -20,7 +20,7 @@
 
 namespace rspamd::css {
 
-constexpr const auto type_map = frozen::make_unordered_map<frozen::string, css_property_type>({
+constexpr const auto prop_names_map = frozen::make_unordered_map<frozen::string, css_property_type>({
 		{"font", css_property_type::PROPERTY_FONT},
 		{"font-color", css_property_type::PROPERTY_FONT_COLOR},
 		{"font-size", css_property_type::PROPERTY_FONT_SIZE},
@@ -34,15 +34,18 @@ constexpr const auto type_map = frozen::make_unordered_map<frozen::string, css_p
 		{"opacity", css_property_type::PROPERTY_OPACITY},
 });
 
+/* Ensure that we have all cases listed */
+static_assert(prop_names_map.size() == static_cast<int>(css_property_type::PROPERTY_NYI));
+
 auto token_string_to_property(const std::string_view &inp)
 	-> css_property_type
 {
 
 	css_property_type ret = css_property_type::PROPERTY_NYI;
 
-	auto known_type = type_map.find(inp);
+	auto known_type = prop_names_map.find(inp);
 
-	if (known_type != type_map.end()) {
+	if (known_type != prop_names_map.end()) {
 		ret = known_type->second;
 	}
 
diff --git a/src/libserver/css/css_property.hxx b/src/libserver/css/css_property.hxx
index 3908c6d16..597fc20c5 100644
--- a/src/libserver/css/css_property.hxx
+++ b/src/libserver/css/css_property.hxx
@@ -106,11 +106,14 @@ struct alignas(int) css_property {
 		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;
+				type == css_property_type::PROPERTY_FONT_COLOR ||
+				type == css_property_type::PROPERTY_FONT;
 	}
 	constexpr auto is_dimension(void) const -> bool {
 		return type == css_property_type::PROPERTY_HEIGHT ||
-				type == css_property_type::PROPERTY_WIDTH;
+				type == css_property_type::PROPERTY_WIDTH ||
+				type == css_property_type::PROPERTY_FONT_SIZE ||
+				type == css_property_type::PROPERTY_FONT;
 	}
 	constexpr auto is_normal_number(void) const -> bool {
 		return type == css_property_type::PROPERTY_OPACITY;
diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx
index 511c226d2..a29577fe9 100644
--- a/src/libserver/css/css_rule.cxx
+++ b/src/libserver/css/css_rule.cxx
@@ -31,26 +31,30 @@ allowed_property_value(const css_property &prop, const css_consumed_block &parse
 				return css_value::maybe_color_from_hex(tok.get_string_or_default(""));
 			}
 			else if (tok.type == css_parser_token::token_type::ident_token) {
-				return css_value::maybe_color_from_string(tok.get_string_or_default(""));
+				auto &&ret = css_value::maybe_color_from_string(tok.get_string_or_default(""));
+
+				return ret;
 			}
 		}
 		else if (parser_block.is_function()) {
 			const auto &func = parser_block.get_function_or_invalid();
 
-			return css_value::maybe_color_from_function(func);
+			auto &&ret = css_value::maybe_color_from_function(func);
+			return ret;
 		}
 	}
-	else if (prop.is_dimension()) {
+
+	if (prop.is_dimension()) {
 		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::number_token) {
-				return css_value{tok.get_number_or_default(0)};
+				return css_value::maybe_dimension_from_number(tok);
 			}
 		}
 	}
-	else if (prop.is_normal_number()) {
+	if (prop.is_normal_number()) {
 		if (parser_block.is_token()) {
 			/* A single token */
 			const auto &tok = parser_block.get_token_or_empty();
diff --git a/src/libserver/css/css_value.cxx b/src/libserver/css/css_value.cxx
index 719633e68..94c340ac5 100644
--- a/src/libserver/css/css_value.cxx
+++ b/src/libserver/css/css_value.cxx
@@ -273,6 +273,29 @@ auto css_value::maybe_color_from_function(const css_consumed_block::css_function
 	return std::nullopt;
 }
 
+auto css_value::maybe_dimension_from_number(const css_parser_token &tok)
+-> std::optional<css_value>
+{
+	if (std::holds_alternative<double>(tok.value)) {
+		auto dbl = std::get<double>(tok.value);
+		css_dimension dim;
+
+		dim.dim = dbl;
+
+		if (tok.flags & css_parser_token::number_percent) {
+			dim.is_percent = true;
+		}
+		else {
+			dim.is_percent = false;
+		}
+
+		return css_value{dim};
+	}
+
+	return std::nullopt;
+}
+
+
 auto css_value::debug_str() const -> std::string
 {
 	std::string ret;
@@ -289,6 +312,12 @@ auto css_value::debug_str() const -> std::string
 		else if constexpr (std::is_same_v<T, double>) {
 			ret += "size: " + std::to_string(arg);
 		}
+		else if constexpr (std::is_same_v<T, css_dimension>) {
+			ret += "dimension: " + std::to_string(arg.dim);
+			if (arg.is_percent) {
+				ret += "%";
+			}
+		}
 		else if constexpr (std::is_integral_v<T>) {
 			ret += "integral: " + std::to_string(static_cast<int>(arg));
 		}
diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx
index 8fa450e73..64109c5f0 100644
--- a/src/libserver/css/css_value.hxx
+++ b/src/libserver/css/css_value.hxx
@@ -41,6 +41,11 @@ struct alignas(int) css_color {
 	css_color() = default;
 };
 
+struct css_dimension {
+	float dim;
+	bool is_percent;
+};
+
 /*
  * Simple enum class for display stuff
  */
@@ -58,21 +63,24 @@ struct css_value {
 		CSS_VALUE_COLOR,
 		CSS_VALUE_NUMBER,
 		CSS_VALUE_DISPLAY,
-		CSS_VALUE_OPACITY,
+		CSS_VALUE_DIMENSION,
 		CSS_VALUE_NYI,
 	} type;
 
 	std::variant<css_color,
 			double,
 			css_display_value,
+			css_dimension,
 			std::monostate> value;
 
 	css_value(const css_color &color) :
 			type(css_value_type::CSS_VALUE_COLOR), value(color) {}
 	css_value(double num) :
 			type(css_value_type::CSS_VALUE_NUMBER), value(num) {}
+	css_value(css_dimension dim) :
+			type(css_value_type::CSS_VALUE_DIMENSION), value(dim) {}
 
-	constexpr std::optional<css_color> to_color(void) const {
+	auto to_color(void) const -> std::optional<css_color> {
 		if (type == css_value_type::CSS_VALUE_COLOR) {
 			return std::get<css_color>(value);
 		}
@@ -80,7 +88,7 @@ struct css_value {
 		return std::nullopt;
 	}
 
-	constexpr std::optional<double> to_number(void) const {
+	auto to_number(void) const -> std::optional<double> {
 		if (type == css_value_type::CSS_VALUE_NUMBER) {
 			return std::get<double>(value);
 		}
@@ -88,7 +96,15 @@ struct css_value {
 		return std::nullopt;
 	}
 
-	constexpr std::optional<css_display_value> to_display(void) const {
+	auto to_dimension(void) const -> std::optional<css_dimension> {
+		if (type == css_value_type::CSS_VALUE_DIMENSION) {
+			return std::get<css_dimension>(value);
+		}
+
+		return std::nullopt;
+	}
+
+	auto to_display(void) const -> std::optional<css_display_value> {
 		if (type == css_value_type::CSS_VALUE_DISPLAY) {
 			return std::get<css_display_value>(value);
 		}
@@ -96,7 +112,7 @@ struct css_value {
 		return std::nullopt;
 	}
 
-	constexpr bool is_valid(void) const {
+	auto is_valid(void) const -> bool {
 		return (type != css_value_type::CSS_VALUE_NYI);
 	}
 
@@ -110,6 +126,8 @@ struct css_value {
 		-> std::optional<css_value>;
 	static auto maybe_color_from_function(const css_consumed_block::css_function_block &func)
 		-> std::optional<css_value>;
+	static auto maybe_dimension_from_number(const css_parser_token &tok)
+		-> std::optional<css_value>;
 };
 
 }
diff --git a/test/lua/unit/css.lua b/test/lua/unit/css.lua
index 9f9201191..5bb197bf2 100644
--- a/test/lua/unit/css.lua
+++ b/test/lua/unit/css.lua
@@ -100,11 +100,14 @@ body {
 ]],
 [[
 /* Colors */
-p { color: rgb(100%, 50%, 0%); opacity: -1; } /* very transparent solid orange */
+p { color: rgb(100%, 50%, 0%); opacity: -1; width: 1em; } /* very transparent solid orange */
 p { color: rgb(100%, 50%, 0%); opacity: 2; } /* very transparent solid orange */
 p { color: rgb(100%, 50%, 0%); opacity: 0.5; } /* very transparent solid orange */
 p { color: rgb(100%, 50%, 0%); opacity: 1; width: 99%; } /* very transparent solid orange */
 p { color: rgb(100%, 50%, 0%); opacity: 10%; width: 99%; } /* very transparent solid orange */
+p { color: rgb(100%, 50%, 0%); opacity: 10%; width: 100px; } /* very transparent solid orange */
+p { color: rgb(100%, 50%, 0%); opacity: 10% } /* very transparent solid orange */
+
 * { color: hsl(0, 100%, 50%) !important }   /* red */
 * { color: hsl(120, 100%, 50%) important } /* lime */
 * { color: hsl(120, 100%, 25%) } /* dark green */


More information about the Commits mailing list