summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-09-07 15:48:58 +0800
committerSebastian Rasmussen <sebras@gmail.com>2018-09-07 17:31:07 +0800
commit2b4a96702789a5f59fe468a7be907ccd18071cec (patch)
tree64850a4b8f191d525069e3b1e71de1b69140257f
parentfd23f7d93704d1ba0b690c264a6618311392f3ec (diff)
downloadmupdf-2b4a96702789a5f59fe468a7be907ccd18071cec.tar.xz
Bug 699743: Pop clip upon error when flushing text.
Not popping causes assert to be triggered in fz_draw_end_group().
-rw-r--r--source/pdf/pdf-op-run.c89
1 files changed, 81 insertions, 8 deletions
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index cce39cf7..09fc4e23 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -823,6 +823,14 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
int doinvisible;
softmask_save softmask = { NULL };
int knockout_group = 0;
+ int innerclip = 0;
+ fz_rect tb;
+ char errmess[256] = "";
+ int err = FZ_ERROR_NONE;
+
+ fz_var(innerclip);
+ fz_var(knockout_group);
+ fz_var(tb);
text = pdf_tos_get_text(ctx, &pr->tos);
if (!text)
@@ -844,9 +852,10 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
if (pr->super.hidden)
dostroke = dofill = 0;
+ tb = fz_transform_rect(pr->tos.text_bbox, gstate->ctm);
+
fz_try(ctx)
{
- fz_rect tb = fz_transform_rect(pr->tos.text_bbox, gstate->ctm);
if (dostroke)
tb = fz_adjust_rect_for_stroke(ctx, tb, gstate->stroke_state, gstate->ctm);
@@ -892,17 +901,21 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
if (gstate->fill.pattern)
{
fz_clip_text(ctx, pr->dev, text, gstate->ctm, tb);
+ innerclip = 1;
gstate = pdf_show_pattern(ctx, pr, gstate->fill.pattern, gstate->fill.gstate_num, tb, PDF_FILL);
fz_pop_clip(ctx, pr->dev);
+ innerclip = 0;
}
break;
case PDF_MAT_SHADE:
if (gstate->fill.shade)
{
fz_clip_text(ctx, pr->dev, text, gstate->ctm, tb);
+ innerclip = 1;
/* Page 2 of patterns.pdf shows that fz_fill_shade should NOT be called with gstate->ctm */
fz_fill_shade(ctx, pr->dev, gstate->fill.shade, pr->gstate[gstate->fill.gstate_num].ctm, gstate->fill.alpha, &gstate->fill.color_params);
fz_pop_clip(ctx, pr->dev);
+ innerclip = 0;
}
break;
}
@@ -922,35 +935,91 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
if (gstate->stroke.pattern)
{
fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, gstate->ctm, tb);
+ innerclip = 1;
gstate = pdf_show_pattern(ctx, pr, gstate->stroke.pattern, gstate->stroke.gstate_num, tb, PDF_STROKE);
fz_pop_clip(ctx, pr->dev);
+ innerclip = 0;
}
break;
case PDF_MAT_SHADE:
if (gstate->stroke.shade)
{
fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, gstate->ctm, tb);
+ innerclip = 1;
fz_fill_shade(ctx, pr->dev, gstate->stroke.shade, pr->gstate[gstate->stroke.gstate_num].ctm, gstate->stroke.alpha, &gstate->stroke.color_params);
fz_pop_clip(ctx, pr->dev);
+ innerclip = 0;
}
break;
}
}
+ }
+ fz_always(ctx)
+ {
+ if (innerclip)
+ {
+ fz_try(ctx)
+ {
+ fz_pop_clip(ctx, pr->dev);
+ }
+ fz_catch(ctx)
+ {
+ /* Postpone the problem */
+ err = fz_caught(ctx);
+ strcpy(errmess, fz_caught_message(ctx));
+ }
+ }
+
if (knockout_group)
- fz_end_group(ctx, pr->dev);
+ {
+ fz_try(ctx)
+ {
+ fz_end_group(ctx, pr->dev);
+ }
+ fz_catch(ctx)
+ {
+ /* Postpone the problem */
+ if (err)
+ fz_warn(ctx, "ignoring error: %s", fz_caught_message(ctx));
+ err = fz_caught(ctx);
+ strcpy(errmess, fz_caught_message(ctx));
+ }
+ }
if (dofill || dostroke)
- pdf_end_group(ctx, pr, &softmask);
+ {
+ fz_try(ctx)
+ {
+ pdf_end_group(ctx, pr, &softmask);
+ }
+ fz_catch(ctx)
+ {
+ /* Postpone the problem */
+ if (err)
+ fz_warn(ctx, "ignoring error: %s", fz_caught_message(ctx));
+ err = fz_caught(ctx);
+ strcpy(errmess, fz_caught_message(ctx));
+ }
+ }
if (doclip)
{
- gstate->clip_depth++;
- fz_clip_text(ctx, pr->dev, text, gstate->ctm, tb);
+ fz_try(ctx)
+ {
+ gstate->clip_depth++;
+ fz_clip_text(ctx, pr->dev, text, gstate->ctm, tb);
+ }
+ fz_catch(ctx)
+ {
+ /* Postpone the problem */
+ if (err)
+ fz_warn(ctx, "ignoring error: %s", fz_caught_message(ctx));
+ err = fz_caught(ctx);
+ strcpy(errmess, fz_caught_message(ctx));
+ }
}
- }
- fz_always(ctx)
- {
+
fz_drop_text(ctx, text);
}
fz_catch(ctx)
@@ -958,6 +1027,10 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
fz_rethrow(ctx);
}
+ /* Rethrow postponed errors */
+ if (err)
+ fz_throw(ctx, err, "%s", errmess);
+
return pr->gstate + pr->gtop;
}