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 108b1c7825116ed3f93aa57384bbd3290cdc9181 Mon Sep 17 00:00:00 2001 |
michael@0 | 2 | From: Karl Tomlinson <karlt+@karlt.net> |
michael@0 | 3 | Date: Sat, 17 Jul 2010 01:08:53 +0000 |
michael@0 | 4 | Subject: clip: consider gstate target extents in _cairo_gstate_copy_clip_rectangle_list |
michael@0 | 5 | |
michael@0 | 6 | Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29125 |
michael@0 | 7 | |
michael@0 | 8 | To be consistent with _cairo_gstate_clip_extents, the context's clip |
michael@0 | 9 | should be intersected with the target surface extents (instead of only |
michael@0 | 10 | using them when there is no clip). |
michael@0 | 11 | |
michael@0 | 12 | Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> |
michael@0 | 13 | --- |
michael@0 | 14 | diff --git a/src/cairo-clip.c b/src/cairo-clip.c |
michael@0 | 15 | index 77d8214..d5a2fab 100644 |
michael@0 | 16 | --- a/src/cairo-clip.c |
michael@0 | 17 | +++ b/src/cairo-clip.c |
michael@0 | 18 | @@ -1495,7 +1495,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status) |
michael@0 | 19 | cairo_rectangle_list_t * |
michael@0 | 20 | _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) |
michael@0 | 21 | { |
michael@0 | 22 | -#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S)); |
michael@0 | 23 | +#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S)) |
michael@0 | 24 | |
michael@0 | 25 | cairo_rectangle_list_t *list; |
michael@0 | 26 | cairo_rectangle_t *rectangles = NULL; |
michael@0 | 27 | @@ -1507,57 +1507,37 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) |
michael@0 | 28 | if (clip->all_clipped) |
michael@0 | 29 | goto DONE; |
michael@0 | 30 | |
michael@0 | 31 | - if (clip->path != NULL) { |
michael@0 | 32 | - status = _cairo_clip_get_region (clip, ®ion); |
michael@0 | 33 | - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
michael@0 | 34 | - goto DONE; |
michael@0 | 35 | - } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { |
michael@0 | 36 | - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) |
michael@0 | 37 | - } else if (unlikely (status)) { |
michael@0 | 38 | - return ERROR_LIST (status); |
michael@0 | 39 | - } |
michael@0 | 40 | - } |
michael@0 | 41 | - |
michael@0 | 42 | - if (region != NULL) { |
michael@0 | 43 | - n_rects = cairo_region_num_rectangles (region); |
michael@0 | 44 | - if (n_rects) { |
michael@0 | 45 | - rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); |
michael@0 | 46 | - if (unlikely (rectangles == NULL)) { |
michael@0 | 47 | - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); |
michael@0 | 48 | - } |
michael@0 | 49 | + if (!clip->path) |
michael@0 | 50 | + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); |
michael@0 | 51 | |
michael@0 | 52 | - for (i = 0; i < n_rects; ++i) { |
michael@0 | 53 | - cairo_rectangle_int_t clip_rect; |
michael@0 | 54 | - |
michael@0 | 55 | - cairo_region_get_rectangle (region, i, &clip_rect); |
michael@0 | 56 | + status = _cairo_clip_get_region (clip, ®ion); |
michael@0 | 57 | + if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
michael@0 | 58 | + goto DONE; |
michael@0 | 59 | + } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { |
michael@0 | 60 | + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); |
michael@0 | 61 | + } else if (unlikely (status)) { |
michael@0 | 62 | + return ERROR_LIST (status); |
michael@0 | 63 | + } |
michael@0 | 64 | |
michael@0 | 65 | - if (! _cairo_clip_int_rect_to_user (gstate, |
michael@0 | 66 | - &clip_rect, |
michael@0 | 67 | - &rectangles[i])) |
michael@0 | 68 | - { |
michael@0 | 69 | - free (rectangles); |
michael@0 | 70 | - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); |
michael@0 | 71 | - } |
michael@0 | 72 | - } |
michael@0 | 73 | + n_rects = cairo_region_num_rectangles (region); |
michael@0 | 74 | + if (n_rects) { |
michael@0 | 75 | + rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); |
michael@0 | 76 | + if (unlikely (rectangles == NULL)) { |
michael@0 | 77 | + return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); |
michael@0 | 78 | } |
michael@0 | 79 | - } else { |
michael@0 | 80 | - cairo_rectangle_int_t extents; |
michael@0 | 81 | |
michael@0 | 82 | - if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate), |
michael@0 | 83 | - &extents)) |
michael@0 | 84 | - { |
michael@0 | 85 | - /* unbounded surface -> unclipped */ |
michael@0 | 86 | - goto DONE; |
michael@0 | 87 | - } |
michael@0 | 88 | + for (i = 0; i < n_rects; ++i) { |
michael@0 | 89 | + cairo_rectangle_int_t clip_rect; |
michael@0 | 90 | |
michael@0 | 91 | - n_rects = 1; |
michael@0 | 92 | - rectangles = malloc(sizeof (cairo_rectangle_t)); |
michael@0 | 93 | - if (unlikely (rectangles == NULL)) |
michael@0 | 94 | - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); |
michael@0 | 95 | + cairo_region_get_rectangle (region, i, &clip_rect); |
michael@0 | 96 | |
michael@0 | 97 | - if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) { |
michael@0 | 98 | - free (rectangles); |
michael@0 | 99 | - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); |
michael@0 | 100 | + if (! _cairo_clip_int_rect_to_user (gstate, |
michael@0 | 101 | + &clip_rect, |
michael@0 | 102 | + &rectangles[i])) |
michael@0 | 103 | + { |
michael@0 | 104 | + free (rectangles); |
michael@0 | 105 | + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); |
michael@0 | 106 | + } |
michael@0 | 107 | } |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c |
michael@0 | 111 | index baf6145..7caf624 100644 |
michael@0 | 112 | --- a/src/cairo-gstate.c |
michael@0 | 113 | +++ b/src/cairo-gstate.c |
michael@0 | 114 | @@ -1555,7 +1555,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate, |
michael@0 | 115 | cairo_rectangle_list_t* |
michael@0 | 116 | _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate) |
michael@0 | 117 | { |
michael@0 | 118 | - return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate); |
michael@0 | 119 | + cairo_clip_t clip; |
michael@0 | 120 | + cairo_rectangle_int_t extents; |
michael@0 | 121 | + cairo_rectangle_list_t *list; |
michael@0 | 122 | + |
michael@0 | 123 | + _cairo_clip_init_copy (&clip, &gstate->clip); |
michael@0 | 124 | + |
michael@0 | 125 | + if (_cairo_surface_get_extents (gstate->target, &extents)) |
michael@0 | 126 | + _cairo_clip_rectangle (&clip, &extents); |
michael@0 | 127 | + |
michael@0 | 128 | + list = _cairo_clip_copy_rectangle_list (&clip, gstate); |
michael@0 | 129 | + _cairo_clip_fini (&clip); |
michael@0 | 130 | + |
michael@0 | 131 | + return list; |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | static void |
michael@0 | 135 | diff --git a/test/get-clip.c b/test/get-clip.c |
michael@0 | 136 | index f0477a1..f97db3f 100644 |
michael@0 | 137 | --- a/test/get-clip.c |
michael@0 | 138 | +++ b/test/get-clip.c |
michael@0 | 139 | @@ -120,6 +120,22 @@ preamble (cairo_test_context_t *ctx) |
michael@0 | 140 | } |
michael@0 | 141 | cairo_rectangle_list_destroy (rectangle_list); |
michael@0 | 142 | |
michael@0 | 143 | + /* We should get the same results after applying a clip that contains the |
michael@0 | 144 | + existing clip. */ |
michael@0 | 145 | + phase = "Clip beyond surface extents"; |
michael@0 | 146 | + cairo_save (cr); |
michael@0 | 147 | + cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20); |
michael@0 | 148 | + cairo_clip (cr); |
michael@0 | 149 | + rectangle_list = cairo_copy_clip_rectangle_list (cr); |
michael@0 | 150 | + if (! check_count (ctx, phase, rectangle_list, 1) || |
michael@0 | 151 | + ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) || |
michael@0 | 152 | + ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE)) |
michael@0 | 153 | + { |
michael@0 | 154 | + goto FAIL; |
michael@0 | 155 | + } |
michael@0 | 156 | + cairo_rectangle_list_destroy (rectangle_list); |
michael@0 | 157 | + cairo_restore (cr); |
michael@0 | 158 | + |
michael@0 | 159 | /* Test simple clip rect. */ |
michael@0 | 160 | phase = "Simple clip rect"; |
michael@0 | 161 | cairo_save (cr); |
michael@0 | 162 | -- |
michael@0 | 163 | cgit v0.8.3-6-g21f6 |