summaryrefslogtreecommitdiff
path: root/pdf/pdf_font.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-12-18 19:37:50 +0000
committerRobin Watts <robin.watts@artifex.com>2012-12-19 15:20:26 +0000
commitd4d3b774f21f3a8a238a4f67bc01132119c97a94 (patch)
tree9de55d45d277129228febcfedcc620805822d2a9 /pdf/pdf_font.c
parent956945485624f0df0ffdfbd471a4ec095bd145c9 (diff)
downloadmupdf-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.c10
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;
}