diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-06-22 11:28:02 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-06-22 11:28:02 +0100 |
commit | 3311477ebbd8e5457cbb2b75dec67cf58727acf6 (patch) | |
tree | 9b4ce029b332017d790d717045befc748677f1bf /src | |
parent | 1c5687a9d62982be546cf1a3179a08fdf8db3209 (diff) | |
download | rspamd-3311477ebbd8e5457cbb2b75dec67cf58727acf6.tar.gz rspamd-3311477ebbd8e5457cbb2b75dec67cf58727acf6.zip |
[Feature] Support more size suffixes when parsing HTML styles
Diffstat (limited to 'src')
-rw-r--r-- | src/libserver/html.c | 165 |
1 files changed, 114 insertions, 51 deletions
diff --git a/src/libserver/html.c b/src/libserver/html.c index c80be1dad..d41ae78d9 100644 --- a/src/libserver/html.c +++ b/src/libserver/html.c @@ -1963,6 +1963,106 @@ rspamd_html_process_color (const gchar *line, guint len, struct html_color *cl) } } +/* + * Target is used for in and out if this function returns TRUE + */ +static gboolean +rspamd_html_process_css_size (const gchar *suffix, gsize len, + gdouble *tgt) +{ + gdouble sz = *tgt; + gboolean ret = FALSE; + + if (len >= 2) { + if (memcmp (suffix, "px", 2) == 0) { + sz = (guint) sz; /* Round to number */ + ret = TRUE; + } + else if (memcmp (suffix, "em", 2) == 0) { + /* EM is 16 px, so multiply and round */ + sz = (guint) (sz * 16.0); + ret = TRUE; + } + else if (len >= 3 && memcmp (suffix, "rem", 3) == 0) { + /* equal to EM in our case */ + sz = (guint) (sz * 16.0); + ret = TRUE; + } + else if (memcmp (suffix, "ex", 2) == 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. + */ + sz = (guint) (sz * 8.0); + ret = TRUE; + } + else if (memcmp (suffix, "vw", 2) == 0) { + /* + * Vewport width in percentages: + * we assume 1% of viewport width as 8px + */ + sz = (guint) (sz * 8.0); + ret = TRUE; + } + else if (memcmp (suffix, "vh", 2) == 0) { + /* + * Vewport height in percentages + * we assume 1% of viewport width as 6px + */ + sz = (guint) (sz * 6.0); + ret = TRUE; + } + else if (len >= 4 && memcmp (suffix, "vmax", 4) == 0) { + /* + * Vewport width in percentages + * we assume 1% of viewport width as 6px + */ + sz = (guint) (sz * 8.0); + ret = TRUE; + } + else if (len >= 4 && memcmp (suffix, "vmin", 4) == 0) { + /* + * Vewport height in percentages + * we assume 1% of viewport width as 6px + */ + sz = (guint) (sz * 6.0); + ret = TRUE; + } + else if (memcmp (suffix, "pt", 2) == 0) { + sz = (guint) (sz * 96.0 / 72.0); /* One point. 1pt = 1/72nd of 1in */ + ret = TRUE; + } + else if (memcmp (suffix, "cm", 2) == 0) { + sz = (guint) (sz * 96.0 / 2.54); /* 96px/2.54 */ + ret = TRUE; + } + else if (memcmp (suffix, "mm", 2) == 0) { + sz = (guint) (sz * 9.6 / 2.54); /* 9.6px/2.54 */ + ret = TRUE; + } + else if (memcmp (suffix, "in", 2) == 0) { + sz = (guint) (sz * 96.0); /* 96px */ + ret = TRUE; + } + else if (memcmp (suffix, "pc", 2) == 0) { + sz = (guint) (sz * 96.0 / 6.0); /* 1pc = 12pt = 1/6th of 1in. */ + ret = TRUE; + } + } + else if (suffix[0] == '%') { + /* Percentages from 16 px */ + sz = (guint)(sz / 100.0 * 16.0); + ret = TRUE; + } + + if (ret) { + *tgt = sz; + } + + return ret; +} + static void rspamd_html_process_font_size (const gchar *line, guint len, guint *fs, gboolean is_css) @@ -1970,6 +2070,7 @@ rspamd_html_process_font_size (const gchar *line, guint len, guint *fs, const gchar *p = line, *end = line + len; gchar *err = NULL, numbuf[64]; gdouble sz = 0; + gboolean failsafe = FALSE; while (p < end && g_ascii_isspace (*p)) { p ++; @@ -1986,6 +2087,7 @@ rspamd_html_process_font_size (const gchar *line, guint len, guint *fs, if (err && *err != '\0') { const gchar *e = err; + gsize slen; /* Skip spaces */ while (*e && g_ascii_isspace (*e)) { @@ -1993,56 +2095,19 @@ rspamd_html_process_font_size (const gchar *line, guint len, guint *fs, } /* Lowercase */ - rspamd_str_lc ((gchar *)e, strlen (e)); - - if (memcmp (e, "px", 2) == 0) { - sz = (guint)sz; /* Round to number */ - } - else if (memcmp (e, "em", 2) == 0) { - /* EM is 16 px, so multiply and round */ - sz = (guint)(sz * 16.0); - } - else if (*e == '%') { - /* Percentages from 16 px */ - sz = (guint)(sz / 100.0 * 16.0); - } + slen = strlen (e); + rspamd_str_lc ((gchar *)e, slen); - else if (memcmp (e, "vw", 2) == 0) { - /* - * Vewport width in percentages: - * we assume 1% of viewport width as 8px - */ - sz = (guint)(sz * 8.0); - } - else if (memcmp (e, "vh", 2) == 0) { - /* - * Vewport height in percentages - * we assume 1% of viewport width as 6px - */ - sz = (guint)(sz * 6.0); - } - else { - /* Failsafe - garbadge */ - if (is_css) { - /* - * In css mode we usually ignore sizes, but let's treat - * small sizes specially - */ - if (sz < 1) { - sz = 0; - } - else { - sz = 1; /* Ignore */ - } - } - else { - /* In non-css mode we have to check legacy size */ - sz = sz * 16; - } + if (!rspamd_html_process_css_size (e, slen, &sz)) { + failsafe = TRUE; } } else { /* Failsafe naked number */ + failsafe = TRUE; + } + + if (failsafe) { if (is_css) { /* * In css mode we usually ignore sizes, but let's treat @@ -2050,14 +2115,12 @@ rspamd_html_process_font_size (const gchar *line, guint len, guint *fs, */ if (sz < 1) { sz = 0; + } else { + sz = 16; /* Ignore */ } - else { - sz = 1; /* Ignore */ - } - } - else { + } else { /* In non-css mode we have to check legacy size */ - sz = sz * 16; + sz = sz >= 1 ? sz * 16 : 16; } } |