From 5f3e0b1fb53b8988b5cbc53ad747a42ac95e5fee Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 4 May 2015 17:07:19 +0200 Subject: epub: Fix 695971: Don't confuse id selectors (#name) with colors in CSS. --- source/html/css-apply.c | 41 ++++++++++++++++-------- source/html/css-parse.c | 84 +++++++++++++------------------------------------ 2 files changed, 49 insertions(+), 76 deletions(-) (limited to 'source') diff --git a/source/html/css-apply.c b/source/html/css-apply.c index 052888db..abd045ec 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -422,7 +422,7 @@ add_shorthand_border(fz_css_match *match, fz_css_value *value, int spec, int T, { while (value) { - if (value->type == CSS_COLOR) + if (value->type == CSS_HASH) { if (T) add_property(match, "border-color-top", value, spec); if (R) add_property(match, "border-color-right", value, spec); @@ -766,10 +766,10 @@ static fz_css_color make_color(int r, int g, int b, int a) { fz_css_color c; - c.r = r; - c.g = g; - c.b = b; - c.a = a; + c.r = r < 0 ? 0 : r > 255 ? 255 : r; + c.g = g < 0 ? 0 : g > 255 ? 255 : g; + c.b = b < 0 ? 0 : b > 255 ? 255 : b; + c.a = a < 0 ? 0 : a > 255 ? 255 : a; return c; } @@ -785,11 +785,26 @@ color_from_value(fz_css_value *value, fz_css_color initial) { if (!value) return initial; - if (value->type == CSS_COLOR) + if (value->type == CSS_HASH) { - int r = tohex(value->data[0]) * 16 + tohex(value->data[1]); - int g = tohex(value->data[2]) * 16 + tohex(value->data[3]); - int b = tohex(value->data[4]) * 16 + tohex(value->data[5]); + int r, g, b, n; + n = strlen(value->data); + if (n == 3) + { + r = tohex(value->data[0]) * 16 + tohex(value->data[0]); + g = tohex(value->data[1]) * 16 + tohex(value->data[1]); + b = tohex(value->data[2]) * 16 + tohex(value->data[2]); + } + else if (n == 6) + { + r = tohex(value->data[0]) * 16 + tohex(value->data[1]); + g = tohex(value->data[2]) * 16 + tohex(value->data[3]); + b = tohex(value->data[4]) * 16 + tohex(value->data[5]); + } + else + { + r = g = b = 0; + } return make_color(r, g, b, 255); } if (value->type == CSS_KEYWORD) @@ -978,10 +993,10 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, style->border_style[2] = border_style_from_property(match, "border-style-bottom"); style->border_style[3] = border_style_from_property(match, "border-style-left"); - style->border_color[0] = color_from_property(match, "border-color-top", transparent); - style->border_color[1] = color_from_property(match, "border-color-right", transparent); - style->border_color[2] = color_from_property(match, "border-color-bottom", transparent); - style->border_color[3] = color_from_property(match, "border-color-left", transparent); + style->border_color[0] = color_from_property(match, "border-color-top", style->color); + style->border_color[1] = color_from_property(match, "border-color-right", style->color); + style->border_color[2] = color_from_property(match, "border-color-bottom", style->color); + style->border_color[3] = color_from_property(match, "border-color-left", style->color); style->border_width[0] = border_width_from_property(match, "border-width-top"); style->border_width[1] = border_width_from_property(match, "border-width-right"); diff --git a/source/html/css-parse.c b/source/html/css-parse.c index d2415676..adcd524b 100644 --- a/source/html/css-parse.c +++ b/source/html/css-parse.c @@ -8,7 +8,6 @@ struct lexbuf int line; int lookahead; int c; - int color; int string_len; char string[1024]; }; @@ -149,7 +148,6 @@ static void css_lex_init(fz_context *ctx, struct lexbuf *buf, const char *s, con buf->line = 1; css_lex_next(buf); - buf->color = 0; buf->string_len = 0; } @@ -193,36 +191,6 @@ static void css_lex_expect(struct lexbuf *buf, int t) fz_css_error(buf, "unexpected character"); } -static int ishex(int c, int *v) -{ - if (c >= '0' && c <= '9') - { - *v = c - '0'; - return 1; - } - if (c >= 'A' && c <= 'F') - { - *v = c - 'A' + 0xA; - return 1; - } - if (c >= 'a' && c <= 'f') - { - *v = c - 'a' + 0xA; - return 1; - } - return 0; -} - -static int css_lex_accept_hex(struct lexbuf *buf, int *v) -{ - if (ishex(buf->c, v)) - { - css_lex_next(buf); - return 1; - } - return 0; -} - static int css_lex_number(struct lexbuf *buf) { while (buf->c >= '0' && buf->c <= '9') @@ -276,6 +244,17 @@ static int css_lex_keyword(struct lexbuf *buf) return CSS_KEYWORD; } +static int css_lex_hash(struct lexbuf *buf) +{ + while (isnmchar(buf->c)) + { + css_push_char(buf, buf->c); + css_lex_next(buf); + } + css_push_char(buf, 0); + return CSS_HASH; +} + static int css_lex_string(struct lexbuf *buf, int q) { while (buf->c && buf->c != q) @@ -431,26 +410,7 @@ restart: } if (css_lex_accept(buf, '#')) - { - int a, b, c, d, e, f; - if (!css_lex_accept_hex(buf, &a)) goto colorerror; - if (!css_lex_accept_hex(buf, &b)) goto colorerror; - if (!css_lex_accept_hex(buf, &c)) goto colorerror; - if (css_lex_accept_hex(buf, &d)) - { - if (!css_lex_accept_hex(buf, &e)) goto colorerror; - if (!css_lex_accept_hex(buf, &f)) goto colorerror; - buf->color = (a << 20) | (b << 16) | (c << 12) | (d << 8) | (e << 4) | f; - } - else - { - buf->color = (a << 20) | (b << 12) | (c << 4); - } - sprintf(buf->string, "%06x", buf->color); - return CSS_COLOR; -colorerror: - fz_css_error(buf, "invalid color"); - } + return css_lex_hash(buf); if (css_lex_accept(buf, '"')) return css_lex_string(buf, '"'); @@ -532,7 +492,7 @@ static void expect(struct lexbuf *buf, int t) static int iscond(int t) { - return t == ':' || t == '.' || t == '#' || t == '['; + return t == ':' || t == '.' || t == '[' || t == CSS_HASH; } static fz_css_value *parse_value_list(struct lexbuf *buf); @@ -558,11 +518,11 @@ static fz_css_value *parse_value(struct lexbuf *buf) switch (buf->lookahead) { + case CSS_HASH: case CSS_NUMBER: case CSS_LENGTH: case CSS_PERCENT: case CSS_STRING: - case CSS_COLOR: case CSS_URI: v = fz_new_css_value(buf->ctx, buf->lookahead, buf->string); next(buf); @@ -672,15 +632,6 @@ static fz_css_condition *parse_condition(struct lexbuf *buf) return c; } - if (accept(buf, '#')) - { - if (buf->lookahead != CSS_KEYWORD) - fz_css_error(buf, "expected keyword after '#'"); - c = fz_new_css_condition(buf->ctx, '#', "id", buf->string); - next(buf); - return c; - } - if (accept(buf, '[')) { if (buf->lookahead != CSS_KEYWORD) @@ -712,6 +663,13 @@ static fz_css_condition *parse_condition(struct lexbuf *buf) return c; } + if (buf->lookahead == CSS_HASH) + { + c = fz_new_css_condition(buf->ctx, '#', "id", buf->string); + next(buf); + return c; + } + fz_css_error(buf, "expected condition"); } -- cgit v1.2.3