diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2015-04-14 20:44:17 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2015-04-15 17:48:45 +0200 |
commit | 1e0b6a6c60c6cb76245cb659458868f92ed0cda0 (patch) | |
tree | a0d367c2b23771cce1386893769ff11e323dff5c | |
parent | d940388d7747fd3d816fbd7813567a843d30d969 (diff) | |
download | mupdf-1e0b6a6c60c6cb76245cb659458868f92ed0cda0.tar.xz |
epub: Be resilient in the face of broken CSS.
Try to recover from syntax errors in CSS rules by skipping to the
end of the declaration block.
Don't abort HTML parsing on CSS errors.
-rw-r--r-- | include/mupdf/fitz/context.h | 5 | ||||
-rw-r--r-- | source/html/css-parse.c | 38 | ||||
-rw-r--r-- | source/html/html-layout.c | 10 |
3 files changed, 40 insertions, 13 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h index e58e5f61..10e28e0c 100644 --- a/include/mupdf/fitz/context.h +++ b/include/mupdf/fitz/context.h @@ -79,8 +79,9 @@ enum { FZ_ERROR_NONE = 0, FZ_ERROR_GENERIC = 1, - FZ_ERROR_TRYLATER = 2, - FZ_ERROR_ABORT = 3, + FZ_ERROR_SYNTAX = 2, + FZ_ERROR_TRYLATER = 3, + FZ_ERROR_ABORT = 4, FZ_ERROR_COUNT }; diff --git a/source/html/css-parse.c b/source/html/css-parse.c index 93916344..d2415676 100644 --- a/source/html/css-parse.c +++ b/source/html/css-parse.c @@ -15,7 +15,7 @@ struct lexbuf FZ_NORETURN static void fz_css_error(struct lexbuf *buf, const char *msg) { - fz_throw(buf->ctx, FZ_ERROR_GENERIC, "css syntax error: %s (%s:%d)", msg, buf->file, buf->line); + fz_throw(buf->ctx, FZ_ERROR_SYNTAX, "css syntax error: %s (%s:%d)", msg, buf->file, buf->line); } static fz_css_rule *fz_new_css_rule(fz_context *ctx, fz_css_selector *selector, fz_css_property *declaration) @@ -821,13 +821,29 @@ static fz_css_selector *parse_selector_list(struct lexbuf *buf) static fz_css_rule *parse_rule(struct lexbuf *buf) { - fz_css_selector *s; - fz_css_property *p; + fz_css_selector *s = NULL; + fz_css_property *p = NULL; + + fz_try(buf->ctx) + { + s = parse_selector_list(buf); + expect(buf, '{'); + p = parse_declaration_list(buf); + expect(buf, '}'); + } + fz_catch(buf->ctx) + { + if (fz_caught(buf->ctx) != FZ_ERROR_SYNTAX) + fz_rethrow(buf->ctx); + while (buf->lookahead != EOF) + { + if (accept(buf, '}')) + break; + next(buf); + } + return NULL; + } - s = parse_selector_list(buf); - expect(buf, '{'); - p = parse_declaration_list(buf); - expect(buf, '}'); return fz_new_css_rule(buf->ctx, s, p); } @@ -882,8 +898,12 @@ static fz_css_rule *parse_stylesheet(struct lexbuf *buf, fz_css_rule *chain) } else { - rule = *nextp = parse_rule(buf); - nextp = &rule->next; + fz_css_rule *x = parse_rule(buf); + if (x) + { + rule = *nextp = x; + nextp = &rule->next; + } } } diff --git a/source/html/html-layout.c b/source/html/html-layout.c index cc536cce..75ee3c35 100644 --- a/source/html/html-layout.c +++ b/source/html/html-layout.c @@ -848,7 +848,10 @@ html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rul buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); - css = fz_parse_css(ctx, css, (char*)buf->data, path); + fz_try(ctx) + css = fz_parse_css(ctx, css, (char*)buf->data, path); + fz_catch(ctx) + fz_warn(ctx, "ignoring stylesheet %s", path); fz_drop_buffer(ctx, buf); } } @@ -857,7 +860,10 @@ html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rul if (tag && !strcmp(tag, "style")) { char *s = concat_text(ctx, node); - css = fz_parse_css(ctx, css, s, "<style>"); + fz_try(ctx) + css = fz_parse_css(ctx, css, s, "<style>"); + fz_catch(ctx) + fz_warn(ctx, "ignoring inline stylesheet"); fz_free(ctx, s); } if (fz_xml_down(node)) |