[poppler] [PATCH] Poppler Crash Fix: Do not call FT_Done_Freetype in CairoOutputDev

Michael Vrable mvrable at cs.ucsd.edu
Fri Jun 20 22:27:25 PDT 2008

I came across a rather interesting crash in Evince recently, which I 
think was due to FT_Done_FreeType being called in CairoOutputDev before 
all font faces loaded by that instance of FreeType were done being used 
by Cairo.  The bug was non-deterministic, but usually showed up as a 
segmentation fault after reloading a document in Evince some number of 
times (sometimes one reload, sometimes many were needed).

The sequence of events I think went something like this:
 1. Poppler rendered a page, in the process calling on FreeType to load
    a font.
 2. After rendering was done, the CairoOutputDev object was deleted.
    Cairo still maintains a reference to some of the loaded fonts, but,
    the FT_Library object associated with the CairoOutputDev is deleted.
    My guess is that doing so causes the FT_Face objects to be freed.
 3. In a later page render, poppler loads calls on FreeType to load
    another font.  By chance, this ends up being allocated at the same
    address in memory as one of the fonts from step 1 (since the memory
    has been freed).
 4. When asked to create a Cairo font for this FreeType font, Cairo
    believes that the font face is already in its cache--Cairo still has
    a reference to the font from step 1, and the underlying FreeType
    font is at the same address in memory as the font in the new
    request.  Cairo returns a copy of its old font face.
 5. CairoFont::create registers a destructor with the font face returned
    by Cairo (using cairo_font_face_set_user_data).  However, since
    cairo has returned an already-created font, there is already a
    destructor, using the same key, so before replacing it, cairo calls
    the old destructor.  This in turn calls FT_Done_Face on the new font
    which we were just loading.
 6. Havoc ensues.

The simple fix is to never call FT_Done_FreeType; cairo might hold on to 
a reference to the fonts until the application exits in any case.  To 
avoid unbounded resource leaks, however, I switched to using a single 
static FT_Library instance instead of one per CairoOutputDev.  A patch 
is attached.

A downside to this approach is that it may not be thread-safe.  It's not 
clear to me that the poppler library as a whole is--can anyone comment 
on what the goals for poppler are here, and on the status of the 
libraries it uses?  An alternate approach is to keep the one FT_Library 
per CairoOutputDev approach, but do some reference counting on it so as 
to avoid calling FT_Done_FreeType until FT_Done_Face has been called for 
each font face loaded with it.  This is a bit more complex to implement, 
but if it would be the preferred approach I can work on a patch to do 

--Michael Vrable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo-use-global-ft_library.patch
Type: text/x-diff
Size: 3104 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/poppler/attachments/20080620/7f060965/attachment.patch 

More information about the poppler mailing list