commit 7a3c590: [Project] Css: Simplify checks
Vsevolod Stakhov
vsevolod at highsecure.ru
Thu Feb 18 16:56:28 UTC 2021
Author: Vsevolod Stakhov
Date: 2021-02-18 16:52:20 +0000
URL: https://github.com/rspamd/rspamd/commit/7a3c590d65b4b9a4092018002e53614e61c63b50 (HEAD -> master)
[Project] Css: Simplify checks
---
src/libserver/css/css_tokeniser.cxx | 130 ++++++++++++------------------------
src/libserver/css/css_tokeniser.hxx | 8 ++-
2 files changed, 49 insertions(+), 89 deletions(-)
diff --git a/src/libserver/css/css_tokeniser.cxx b/src/libserver/css/css_tokeniser.cxx
index be2b4f802..f3a2767bd 100644
--- a/src/libserver/css/css_tokeniser.cxx
+++ b/src/libserver/css/css_tokeniser.cxx
@@ -17,6 +17,8 @@
#include "css_tokeniser.hxx"
#include "css_util.hxx"
#include "css.hxx"
+#include "frozen/unordered_map.h"
+#include "frozen/string.h"
#include <string>
namespace rspamd::css {
@@ -106,6 +108,40 @@ static constexpr inline auto is_plain_ident(char c) -> bool
return false;
};
+struct css_dimension_data {
+ css_parser_token::dim_type dtype;
+ double mult;
+};
+
+/*
+ * Maps from css dimensions to the multipliers that look reasonable in email
+ */
+constexpr const auto max_dims = static_cast<int>(css_parser_token::dim_type::dim_max);
+constexpr frozen::unordered_map<frozen::string, css_dimension_data, max_dims> dimensions_map{
+ {"px", { css_parser_token::dim_type::dim_px, 1.0}},
+ /* EM/REM are 16 px, so multiply and round */
+ {"em", { css_parser_token::dim_type::dim_em, 16.0}},
+ {"rem", { css_parser_token::dim_type::dim_rem, 16.0}},
+ /*
+ * Represents the x-height of the element's font.
+ * On fonts with the "x" letter, this is generally the height
+ * of lowercase letters in the font; 1ex = 0.5em in many fonts.
+ */
+ {"ex", { css_parser_token::dim_type::dim_ex, 8.0}},
+ {"wv", { css_parser_token::dim_type::dim_wv, 8.0}},
+ {"wh", { css_parser_token::dim_type::dim_wh, 6.0}},
+ {"vmax", { css_parser_token::dim_type::dim_vmax, 8.0}},
+ {"vmin", { css_parser_token::dim_type::dim_vmin, 6.0}},
+ /* One point. 1pt = 1/72nd of 1in */
+ {"pt", { css_parser_token::dim_type::dim_pt, 96.0 / 72.0}},
+ /* 96px/2.54 */
+ {"cm", { css_parser_token::dim_type::dim_cm, 96.0 / 2.54}},
+ {"mm", { css_parser_token::dim_type::dim_mm, 9.60 / 2.54}},
+ {"in", { css_parser_token::dim_type::dim_in, 96.0}},
+ /* 1pc = 12pt = 1/6th of 1in. */
+ {"pc", { css_parser_token::dim_type::dim_pc, 96.0 / 6.0}}
+};
+
auto
css_parser_token::adjust_dim(const css_parser_token &dim_token) -> bool
{
@@ -118,93 +154,13 @@ css_parser_token::adjust_dim(const css_parser_token &dim_token) -> bool
auto num = std::get<double>(value);
auto sv = std::get<std::string_view>(dim_token.value);
- if (sv == "px") {
- dim_type = css_parser_token::dim_type::dim_px;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)num; /* Round to number */
- }
- else if (sv == "em") {
- dim_type = css_parser_token::dim_type::dim_em;
- flags |= css_parser_token::number_dimension;
- /* EM is 16 px, so multiply and round */
- num = (unsigned)(num * 16.0);
- }
- else if (sv == "rem") {
- /* equal to EM in our case */
- dim_type = css_parser_token::dim_type::dim_rem;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 16.0);
- }
- else if (sv == "ex") {
- /*
- * Represents the x-height of the element's font.
- * On fonts with the "x" letter, this is generally the height
- * of lowercase letters in the font; 1ex = 0.5em in many fonts.
- */
- dim_type = css_parser_token::dim_type::dim_ex;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 8.0);
- }
- else if (sv == "wv") {
- /*
- * Vewport width in percentages:
- * we assume 1% of viewport width as 8px
- */
- dim_type = css_parser_token::dim_type::dim_wv;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 8.0);
- }
- else if (sv == "wh") {
- /*
- * Vewport height in percentages
- * we assume 1% of viewport width as 6px
- */
- dim_type = css_parser_token::dim_type::dim_wh;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 6.0);
- }
- else if (sv == "vmax") {
- /*
- * Vewport width in percentages
- * we assume 1% of viewport width as 6px
- */
- dim_type = css_parser_token::dim_type::dim_vmax;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 8.0);
- }
- else if (sv == "vmin") {
- /*
- * Vewport height in percentages
- * we assume 1% of viewport width as 6px
- */
- dim_type = css_parser_token::dim_type::dim_vmin;
- flags |= css_parser_token::number_dimension;
- num = (unsigned)(num * 6.0);
- }
- else if (sv == "pt") {
- dim_type = css_parser_token::dim_type::dim_pt;
- flags |= css_parser_token::number_dimension;
- num = (num * 96.0 / 72.0); /* One point. 1pt = 1/72nd of 1in */
- }
- else if (sv == "cm") {
- dim_type = css_parser_token::dim_type::dim_cm;
- flags |= css_parser_token::number_dimension;
- num = (num * 96.0 / 2.54); /* 96px/2.54 */
- }
- else if (sv == "mm") {
- dim_type = css_parser_token::dim_type::dim_mm;
- flags |= css_parser_token::number_dimension;
- num = (num * 9.6 / 2.54); /* 9.6px/2.54 */
- }
- else if (sv == "in") {
- dim_type = css_parser_token::dim_type::dim_in;
- flags |= css_parser_token::number_dimension;
- num = (num * 96.0); /* 96px */
- }
- else if (sv == "pc") {
- dim_type = css_parser_token::dim_type::dim_pc;
+ auto dim_found = dimensions_map.find(sv);
+
+ if (dim_found != dimensions_map.end()) {
+ auto dim_elt = dim_found->second;
+ dimension_type = dim_elt.dtype;
flags |= css_parser_token::number_dimension;
- num = (num * 96.0 / 6.0); /* 1pc = 12pt = 1/6th of 1in. */
+ num *= dim_elt.mult;
}
else {
flags |= css_parser_token::flag_bad_dimension;
@@ -838,7 +794,7 @@ auto css_parser_token::debug_token_str() -> std::string
}
if (flags & number_dimension) {
- ret += "; dim=" + std::to_string(static_cast<int>(dim_type));
+ ret += "; dim=" + std::to_string(static_cast<int>(dimension_type));
}
return ret; /* Copy elision */
diff --git a/src/libserver/css/css_tokeniser.hxx b/src/libserver/css/css_tokeniser.hxx
index b39e8431c..70128e8c8 100644
--- a/src/libserver/css/css_tokeniser.hxx
+++ b/src/libserver/css/css_tokeniser.hxx
@@ -56,7 +56,7 @@ struct css_parser_token {
};
enum class dim_type : std::uint8_t {
- dim_px,
+ dim_px = 0,
dim_em,
dim_rem,
dim_ex,
@@ -69,6 +69,7 @@ struct css_parser_token {
dim_mm,
dim_in,
dim_pc,
+ dim_max,
};
static const std::uint8_t default_flags = 0;
@@ -85,9 +86,12 @@ struct css_parser_token {
/* Typed storage */
value_type value;
+
+ int lineno;
+
token_type type;
std::uint8_t flags = default_flags;
- dim_type dim_type;
+ dim_type dimension_type;
css_parser_token() = delete;
explicit css_parser_token(token_type type, const value_type &value) :
More information about the Commits
mailing list