Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | From 0238fe2cafea2e1ed19bb222117bd73ee6898d4d Mon Sep 17 00:00:00 2001 |
michael@0 | 2 | From: Karl Tomlinson <karlt+@karlt.net> |
michael@0 | 3 | Date: Thu, 14 May 2009 10:46:29 +0000 |
michael@0 | 4 | Subject: [ft] Resolve mutual referencing problems with zombie faces |
michael@0 | 5 | |
michael@0 | 6 | Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual |
michael@0 | 7 | referencing problems |
michael@0 | 8 | [http://bugs.freedesktop.org/show_bug.cgi?id=21706] |
michael@0 | 9 | |
michael@0 | 10 | There can be more than one zombie font_face belonging to an unscaled_font, |
michael@0 | 11 | but only the first is destroyed. This leaks the client's FT_Face |
michael@0 | 12 | (and associated font data) as release of the FT_Face depends on release |
michael@0 | 13 | of the font_face. |
michael@0 | 14 | |
michael@0 | 15 | (The reason why Firefox ends up with two different font_faces for one |
michael@0 | 16 | unscaled_font is that load_flags for faces with artificial oblique have |
michael@0 | 17 | FT_LOAD_NO_BITMAP set. |
michael@0 | 18 | https://bugzilla.mozilla.org/show_bug.cgi?id=486974) |
michael@0 | 19 | |
michael@0 | 20 | Also it's possible for _cairo_ft_font_face_create to pull out a zombie |
michael@0 | 21 | font_face from the unscaled_font, which would crash |
michael@0 | 22 | _cairo_ft_font_face_scaled_font_create, as that expects non-null |
michael@0 | 23 | font_face->unscaled (if !font-face->pattern). |
michael@0 | 24 | --- |
michael@0 | 25 | diff --git a/AUTHORS b/AUTHORS |
michael@0 | 26 | index 289fecb..8c06174 100644 |
michael@0 | 27 | --- a/AUTHORS |
michael@0 | 28 | +++ b/AUTHORS |
michael@0 | 29 | @@ -86,7 +86,7 @@ Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix |
michael@0 | 30 | Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc |
michael@0 | 31 | Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option |
michael@0 | 32 | Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend |
michael@0 | 33 | -Karl Tomlinson <karlt+@karlt.net> |
michael@0 | 34 | +Karl Tomlinson <karlt+@karlt.net> Optimisation and obscure bug fixes (mozilla) |
michael@0 | 35 | Alp Toker <alp@atoker.com> Fix several code/comment typos |
michael@0 | 36 | Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes |
michael@0 | 37 | David Turner <david@freetype.org> Optimize gradient calculations |
michael@0 | 38 | diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c |
michael@0 | 39 | index 1e2a18e..f9ff0b1 100644 |
michael@0 | 40 | --- a/src/cairo-ft-font.c |
michael@0 | 41 | +++ b/src/cairo-ft-font.c |
michael@0 | 42 | @@ -543,8 +543,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font) |
michael@0 | 43 | /* See comments in _ft_font_face_destroy about the "zombie" state |
michael@0 | 44 | * for a _ft_font_face. |
michael@0 | 45 | */ |
michael@0 | 46 | - if (unscaled->faces && !unscaled->faces->unscaled) |
michael@0 | 47 | + if (unscaled->faces && unscaled->faces->unscaled == NULL) { |
michael@0 | 48 | + assert (unscaled->faces->next == NULL); |
michael@0 | 49 | cairo_font_face_destroy (&unscaled->faces->base); |
michael@0 | 50 | + } |
michael@0 | 51 | } else { |
michael@0 | 52 | _font_map_release_face_lock_held (font_map, unscaled); |
michael@0 | 53 | } |
michael@0 | 54 | @@ -2233,9 +2235,10 @@ _cairo_ft_font_face_destroy (void *abstract_face) |
michael@0 | 55 | if (font_face == NULL) |
michael@0 | 56 | return; |
michael@0 | 57 | |
michael@0 | 58 | - /* When destroying the face created by cairo_ft_font_face_create_for_ft_face, |
michael@0 | 59 | + /* When destroying a face created by cairo_ft_font_face_create_for_ft_face, |
michael@0 | 60 | * we have a special "zombie" state for the face when the unscaled font |
michael@0 | 61 | - * is still alive but there are no public references to the font face. |
michael@0 | 62 | + * is still alive but there are no other references to a font face with |
michael@0 | 63 | + * the same FT_Face. |
michael@0 | 64 | * |
michael@0 | 65 | * We go from: |
michael@0 | 66 | * |
michael@0 | 67 | @@ -2249,6 +2252,8 @@ _cairo_ft_font_face_destroy (void *abstract_face) |
michael@0 | 68 | |
michael@0 | 69 | if (font_face->unscaled && |
michael@0 | 70 | font_face->unscaled->from_face && |
michael@0 | 71 | + font_face->next == NULL && |
michael@0 | 72 | + font_face->unscaled->faces == font_face && |
michael@0 | 73 | CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) |
michael@0 | 74 | { |
michael@0 | 75 | cairo_font_face_reference (&font_face->base); |
michael@0 | 76 | @@ -2394,12 +2399,21 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, |
michael@0 | 77 | font_face->ft_options.extra_flags == ft_options->extra_flags && |
michael@0 | 78 | cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base)) |
michael@0 | 79 | { |
michael@0 | 80 | - if (font_face->base.status == CAIRO_STATUS_SUCCESS) |
michael@0 | 81 | - return cairo_font_face_reference (&font_face->base); |
michael@0 | 82 | + if (font_face->base.status) { |
michael@0 | 83 | + /* The font_face has been left in an error state, abandon it. */ |
michael@0 | 84 | + *prev_font_face = font_face->next; |
michael@0 | 85 | + break; |
michael@0 | 86 | + } |
michael@0 | 87 | |
michael@0 | 88 | - /* The font_face has been left in an error state, abandon it. */ |
michael@0 | 89 | - *prev_font_face = font_face->next; |
michael@0 | 90 | - break; |
michael@0 | 91 | + if (font_face->unscaled == NULL) { |
michael@0 | 92 | + /* Resurrect this "zombie" font_face (from |
michael@0 | 93 | + * _cairo_ft_font_face_destroy), switching its unscaled_font |
michael@0 | 94 | + * from owner to ownee. */ |
michael@0 | 95 | + font_face->unscaled = unscaled; |
michael@0 | 96 | + _cairo_unscaled_font_reference (&unscaled->base); |
michael@0 | 97 | + return &font_face->base; |
michael@0 | 98 | + } else |
michael@0 | 99 | + return cairo_font_face_reference (&font_face->base); |
michael@0 | 100 | } |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | @@ -2415,6 +2429,14 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, |
michael@0 | 104 | |
michael@0 | 105 | font_face->ft_options = *ft_options; |
michael@0 | 106 | |
michael@0 | 107 | + if (unscaled->faces && unscaled->faces->unscaled == NULL) { |
michael@0 | 108 | + /* This "zombie" font_face (from _cairo_ft_font_face_destroy) |
michael@0 | 109 | + * is no longer needed. */ |
michael@0 | 110 | + assert (unscaled->from_face && unscaled->faces->next == NULL); |
michael@0 | 111 | + cairo_font_face_destroy (&unscaled->faces->base); |
michael@0 | 112 | + unscaled->faces = NULL; |
michael@0 | 113 | + } |
michael@0 | 114 | + |
michael@0 | 115 | font_face->next = unscaled->faces; |
michael@0 | 116 | unscaled->faces = font_face; |
michael@0 | 117 | |
michael@0 | 118 | -- |
michael@0 | 119 | cgit v0.8.2 |