1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/zombie-face.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,119 @@ 1.4 +From 0238fe2cafea2e1ed19bb222117bd73ee6898d4d Mon Sep 17 00:00:00 2001 1.5 +From: Karl Tomlinson <karlt+@karlt.net> 1.6 +Date: Thu, 14 May 2009 10:46:29 +0000 1.7 +Subject: [ft] Resolve mutual referencing problems with zombie faces 1.8 + 1.9 +Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual 1.10 + referencing problems 1.11 +[http://bugs.freedesktop.org/show_bug.cgi?id=21706] 1.12 + 1.13 +There can be more than one zombie font_face belonging to an unscaled_font, 1.14 +but only the first is destroyed. This leaks the client's FT_Face 1.15 +(and associated font data) as release of the FT_Face depends on release 1.16 +of the font_face. 1.17 + 1.18 +(The reason why Firefox ends up with two different font_faces for one 1.19 +unscaled_font is that load_flags for faces with artificial oblique have 1.20 +FT_LOAD_NO_BITMAP set. 1.21 +https://bugzilla.mozilla.org/show_bug.cgi?id=486974) 1.22 + 1.23 +Also it's possible for _cairo_ft_font_face_create to pull out a zombie 1.24 +font_face from the unscaled_font, which would crash 1.25 +_cairo_ft_font_face_scaled_font_create, as that expects non-null 1.26 +font_face->unscaled (if !font-face->pattern). 1.27 +--- 1.28 +diff --git a/AUTHORS b/AUTHORS 1.29 +index 289fecb..8c06174 100644 1.30 +--- a/AUTHORS 1.31 ++++ b/AUTHORS 1.32 +@@ -86,7 +86,7 @@ Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix 1.33 + Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc 1.34 + Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option 1.35 + Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend 1.36 +-Karl Tomlinson <karlt+@karlt.net> 1.37 ++Karl Tomlinson <karlt+@karlt.net> Optimisation and obscure bug fixes (mozilla) 1.38 + Alp Toker <alp@atoker.com> Fix several code/comment typos 1.39 + Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes 1.40 + David Turner <david@freetype.org> Optimize gradient calculations 1.41 +diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c 1.42 +index 1e2a18e..f9ff0b1 100644 1.43 +--- a/src/cairo-ft-font.c 1.44 ++++ b/src/cairo-ft-font.c 1.45 +@@ -543,8 +543,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font) 1.46 + /* See comments in _ft_font_face_destroy about the "zombie" state 1.47 + * for a _ft_font_face. 1.48 + */ 1.49 +- if (unscaled->faces && !unscaled->faces->unscaled) 1.50 ++ if (unscaled->faces && unscaled->faces->unscaled == NULL) { 1.51 ++ assert (unscaled->faces->next == NULL); 1.52 + cairo_font_face_destroy (&unscaled->faces->base); 1.53 ++ } 1.54 + } else { 1.55 + _font_map_release_face_lock_held (font_map, unscaled); 1.56 + } 1.57 +@@ -2233,9 +2235,10 @@ _cairo_ft_font_face_destroy (void *abstract_face) 1.58 + if (font_face == NULL) 1.59 + return; 1.60 + 1.61 +- /* When destroying the face created by cairo_ft_font_face_create_for_ft_face, 1.62 ++ /* When destroying a face created by cairo_ft_font_face_create_for_ft_face, 1.63 + * we have a special "zombie" state for the face when the unscaled font 1.64 +- * is still alive but there are no public references to the font face. 1.65 ++ * is still alive but there are no other references to a font face with 1.66 ++ * the same FT_Face. 1.67 + * 1.68 + * We go from: 1.69 + * 1.70 +@@ -2249,6 +2252,8 @@ _cairo_ft_font_face_destroy (void *abstract_face) 1.71 + 1.72 + if (font_face->unscaled && 1.73 + font_face->unscaled->from_face && 1.74 ++ font_face->next == NULL && 1.75 ++ font_face->unscaled->faces == font_face && 1.76 + CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) 1.77 + { 1.78 + cairo_font_face_reference (&font_face->base); 1.79 +@@ -2394,12 +2399,21 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, 1.80 + font_face->ft_options.extra_flags == ft_options->extra_flags && 1.81 + cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base)) 1.82 + { 1.83 +- if (font_face->base.status == CAIRO_STATUS_SUCCESS) 1.84 +- return cairo_font_face_reference (&font_face->base); 1.85 ++ if (font_face->base.status) { 1.86 ++ /* The font_face has been left in an error state, abandon it. */ 1.87 ++ *prev_font_face = font_face->next; 1.88 ++ break; 1.89 ++ } 1.90 + 1.91 +- /* The font_face has been left in an error state, abandon it. */ 1.92 +- *prev_font_face = font_face->next; 1.93 +- break; 1.94 ++ if (font_face->unscaled == NULL) { 1.95 ++ /* Resurrect this "zombie" font_face (from 1.96 ++ * _cairo_ft_font_face_destroy), switching its unscaled_font 1.97 ++ * from owner to ownee. */ 1.98 ++ font_face->unscaled = unscaled; 1.99 ++ _cairo_unscaled_font_reference (&unscaled->base); 1.100 ++ return &font_face->base; 1.101 ++ } else 1.102 ++ return cairo_font_face_reference (&font_face->base); 1.103 + } 1.104 + } 1.105 + 1.106 +@@ -2415,6 +2429,14 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, 1.107 + 1.108 + font_face->ft_options = *ft_options; 1.109 + 1.110 ++ if (unscaled->faces && unscaled->faces->unscaled == NULL) { 1.111 ++ /* This "zombie" font_face (from _cairo_ft_font_face_destroy) 1.112 ++ * is no longer needed. */ 1.113 ++ assert (unscaled->from_face && unscaled->faces->next == NULL); 1.114 ++ cairo_font_face_destroy (&unscaled->faces->base); 1.115 ++ unscaled->faces = NULL; 1.116 ++ } 1.117 ++ 1.118 + font_face->next = unscaled->faces; 1.119 + unscaled->faces = font_face; 1.120 + 1.121 +-- 1.122 +cgit v0.8.2