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.
1 Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
2 diff --git a/src/cairo-surface.c b/src/cairo-surface.c
3 index 8278694..12f6242 100644
4 --- a/src/cairo-surface.c
5 +++ b/src/cairo-surface.c
6 @@ -1530,6 +1530,70 @@ _cairo_recording_surface_clone_similar (cairo_surface_t *surface,
7 return CAIRO_STATUS_SUCCESS;
8 }
10 +struct acquire_source_image_data
11 +{
12 + cairo_surface_t *src;
13 + cairo_image_surface_t *image;
14 + void *image_extra;
15 +};
16 +
17 +static void
18 +_wrap_release_source_image (void *data)
19 +{
20 + struct acquire_source_image_data *acquire_data = data;
21 + _cairo_surface_release_source_image (acquire_data->src,
22 + acquire_data->image,
23 + acquire_data->image_extra);
24 + free(data);
25 +}
26 +
27 +static cairo_status_t
28 +_wrap_image (cairo_surface_t *src,
29 + cairo_image_surface_t *image,
30 + void *image_extra,
31 + cairo_image_surface_t **out)
32 +{
33 + static cairo_user_data_key_t wrap_image_key;
34 + cairo_image_surface_t *surface;
35 + cairo_status_t status;
36 +
37 + struct acquire_source_image_data *data = malloc (sizeof (*data));
38 + if (unlikely (data == NULL))
39 + return _cairo_error (CAIRO_STATUS_NO_MEMORY);
40 + data->src = src;
41 + data->image = image;
42 + data->image_extra = image_extra;
43 +
44 + surface = (cairo_image_surface_t *)
45 + _cairo_image_surface_create_with_pixman_format (image->data,
46 + image->pixman_format,
47 + image->width,
48 + image->height,
49 + image->stride);
50 + status = surface->base.status;
51 + if (status) {
52 + free (data);
53 + return status;
54 + }
55 +
56 + status = _cairo_user_data_array_set_data (&surface->base.user_data,
57 + &wrap_image_key,
58 + data,
59 + _wrap_release_source_image);
60 + if (status) {
61 + cairo_surface_destroy (&surface->base);
62 + free (data);
63 + return status;
64 + }
65 +
66 + pixman_image_set_component_alpha (
67 + surface->pixman_image,
68 + pixman_image_get_component_alpha (surface->pixman_image));
69 +
70 + *out = surface;
71 + return CAIRO_STATUS_SUCCESS;
72 +}
73 +
74 /**
75 * _cairo_surface_clone_similar:
76 * @surface: a #cairo_surface_t
77 @@ -1606,15 +1670,19 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
78 /* If we failed, try again with an image surface */
79 status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
80 if (status == CAIRO_STATUS_SUCCESS) {
81 - status =
82 - surface->backend->clone_similar (surface, &image->base,
83 - src_x, src_y,
84 - width, height,
85 - clone_offset_x,
86 - clone_offset_y,
87 - clone_out);
88 -
89 - _cairo_surface_release_source_image (src, image, image_extra);
90 + status = _wrap_image(src, image, image_extra, &image);
91 + if (status != CAIRO_STATUS_SUCCESS) {
92 + _cairo_surface_release_source_image (src, image, image_extra);
93 + } else {
94 + status =
95 + surface->backend->clone_similar (surface, &image->base,
96 + src_x, src_y,
97 + width, height,
98 + clone_offset_x,
99 + clone_offset_y,
100 + clone_out);
101 + cairo_surface_destroy(&image->base);
102 + }
103 }
104 }
105 }