diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-12-18 19:37:50 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-12-19 15:20:26 +0000 |
commit | d4d3b774f21f3a8a238a4f67bc01132119c97a94 (patch) | |
tree | 9de55d45d277129228febcfedcc620805822d2a9 /pdf/pdf_font.c | |
parent | 956945485624f0df0ffdfbd471a4ec095bd145c9 (diff) | |
download | mupdf-d4d3b774f21f3a8a238a4f67bc01132119c97a94.tar.xz |
Bug 693503: 'Flatten' display list for all type3 glyphs.
It is perfectly allowable to have type3 glyphs that refer to
other type3 glyphs in the same font (and in theory it's probably
even possible to have type3 glyphs that refer back and forth
between 2 or more type3 fonts).
The old code used to cope with this just fine, but with the change
to 'early loading' of the glyphs to display lists at interpret time
a problem has crept in. When we load the type 3 font, we load
each glyph in turn. If glyph 1 tries to use glyph 2, then we look
up the font, only to find that that the font has not been installed
yet, so we reload the entire font. This gets us into an infinite
loop.
As a fix for this, we split the loading of the type3 font into 2; we
load the font as normal, then allow the font to be inserted into
the list of current fonts. Then we run through the glyphs in the
font 'preparing' them (turning them into display lists).
This solves the infinite loop issue, but causes another problem;
recursive references (such as a font holding a display list that
contains a text node that contains a reference to the original font)
result in us never being able to free the structures.
To avoid this, we insist on never allowing type3 glyphs to be referenced
within a type3 display list. The display lists for all type3 glyphs
are therefore 'flat'. We achieve this by adding a 'nested' flag to
the pdf command stream interpreter structure, and setting this in the
case where we are running a glyph stream. We check for that flag in the
type3 glyph render function, and if present, we force the 'render_direct'
path to be used.
Finally, we ensure that fz_text groups are not needlessly created with
no contents.
Problem found in 2923.pdf.asan.22.2139, a test file supplied by
Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google Security
Team using Address Sanitizer. Many thanks!
Diffstat (limited to 'pdf/pdf_font.c')
-rw-r--r-- | pdf/pdf_font.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c index 34199e06..ebb157b5 100644 --- a/pdf/pdf_font.c +++ b/pdf/pdf_font.c @@ -1098,13 +1098,14 @@ pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc) } pdf_font_desc * -pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) +pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, int nested_depth) { char *subtype; pdf_obj *dfonts; pdf_obj *charprocs; fz_context *ctx = xref->ctx; pdf_font_desc *fontdesc; + int type3 = 0; if ((fontdesc = pdf_find_item(ctx, pdf_free_font_imp, dict))) { @@ -1124,11 +1125,15 @@ pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) else if (subtype && !strcmp(subtype, "TrueType")) fontdesc = pdf_load_simple_font(xref, dict); else if (subtype && !strcmp(subtype, "Type3")) + { fontdesc = pdf_load_type3_font(xref, rdb, dict); + type3 = 1; + } else if (charprocs) { fz_warn(ctx, "unknown font format, guessing type3."); fontdesc = pdf_load_type3_font(xref, rdb, dict); + type3 = 1; } else if (dfonts) { @@ -1147,6 +1152,9 @@ pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) pdf_store_item(ctx, dict, fontdesc, fontdesc->size); + if (type3) + pdf_load_type3_glyphs(xref, fontdesc, nested_depth); + return fontdesc; } |