Bug 41409

Summary: Assertion when marking as dirty a surface on which no Cairo operations have been made
Product: cairo Reporter: ogg.k.ogg.k
Component: generalAssignee: Carl Worth <cworth>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: major    
Priority: medium CC: psychon
Version: 1.10.3   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description ogg.k.ogg.k 2011-10-02 17:40:54 UTC
As shown by the test case below.
In my actual code, I modify the surface after loading (I swap R and B values), the sequence of calls being:
- _create_from_png
- _flush
- _get_data/width/height
- swap R/B values
- _dirty


#include <stdio.h>
#include <cairo.h>

int main()
{
  cairo_surface_t *surface = cairo_image_surface_create_from_png ("/tmp/test.png");
  printf("%d %d\n",cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
  cairo_surface_flush (surface);
  cairo_surface_mark_dirty (surface);
  return 0;
}
Comment 1 ogg.k.ogg.k 2011-10-08 03:41:30 UTC
I don't have all the prerequisites to build Cairo atm, but I think this might do it - untested since I cannot build right now:

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 8488380..26aa72e 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1312,6 +1312,8 @@ cairo_surface_flush (cairo_surface_t *surface)
     if (surface->finished)
        return;
 
+    _cairo_surface_begin_modification (surface);
+
     /* update the current snapshots *before* the user updates the surface */
     _cairo_surface_detach_snapshots (surface);
 



By the way, if this usage is not a valid one, please say so. The docs seem to say this should be done that way, but it's a corner case.

And since it actually "crashes" the user program, I'm setting it as major for now.
Comment 2 Uli Schlachter 2011-10-08 04:24:56 UTC
Because it wasn't already mentioned here:

This fails the following assert in cairo_surface_mark_dirty_rectangle():
  assert (! _cairo_surface_has_mime_data (surface));

This is because create_from_png() attaches the PNG data as mime data to the surface and cairo_surface_flush() doesn't detach the mime data again.

For the proposed fix:
_cairo_surface_begin_modification() checks the surface's status and finished flag. This is already done by cairo_surface_flush() earlier and thus pointless. Then it checks that the surface isn't a snapshot. I don't know if it makes sense to flush a snapshot, but we allowed that previously. Should this change? I don't think anything should have a reason to cairo_surface_flush a snapshot.

This also calls detach_snapshots() again, so  the detach_snapshots() in mark_dirty() should be removed:

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 3be6d42..cf85b72 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1312,8 +1312,8 @@ cairo_surface_flush (cairo_surface_t *surface)
     if (surface->finished)
        return;
 
-    /* update the current snapshots *before* the user updates the surface */
-    _cairo_surface_detach_snapshots (surface);
+    /* Detach snapshots and mime data */
+    _cairo_surface_begin_modification (surface);
 
     if (surface->backend->flush) {
        status = surface->backend->flush (surface);

According to the test suite, this patch breaks the ps backend for rgb24 data (and some more):

ps2 (argb32): 75 crashed! - alpha-similar clear-source clip-group-shapes-aligned-rectangles clip-group-shapes-circles clip-push-group clip-unbounded clipped-group device-offset device-offset-positive extend-reflect-similar extend-repeat-similar extended-blend extended-blend-alpha extended-blend-mask extended-blend-alpha-mask fill-and-stroke-alpha-add get-group-target group-clip group-paint group-unaligned mask operator-alpha-alpha operator-source path-append pixman-rotate push-group-color push-group-path-offset record-paint record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-fill-alpha record-select-font-face record-self-intersecting record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect record-extend-none-similar record-extend-pad-similar record-extend-repeat-similar record-extend-reflect-similar record-mesh recording-surface-over recording-surface-source recording-surface-extend-none recording-surface-extend-repeat recording-surface-extend-reflect scale-offset-similar self-copy self-copy-overlap source-clip source-clip-scale subsurface subsurface-image-repeat subsurface-repeat subsurface-reflect subsurface-modify-child subsurface-modify-parent subsurface-outside-target subsurface-similar-repeat surface-pattern-operator surface-pattern-scale-down-extend-repeat surface-pattern-scale-down-extend-none surface-pattern-scale-down-extend-reflect xcb-huge-image-shm xlib-expose-event pthread-same-source pthread-show-text pthread-similar pdf-surface-source ps-surface-source svg-surface-source
ps2 (rgb24): 369 crashed! - a1-mask a8-clear a8-mask alpha-similar arc-infinite-loop arc-looping-dash api-special-cases big-line big-empty-box big-empty-triangle big-little-box big-little-triangle big-trap bilevel-image bug-bo-rectangular bug-bo-ricotz bug-extents caps checkerboard caps-joins caps-joins-alpha caps-joins-curve caps-tails-curve caps-sub-paths clear clear-source clip-all clip-contexts clip-complex-shape-eo-mono clip-complex-shape-eo-aa clip-disjoint clip-device-offset clip-stroke-unbounded clip-fill-nz-unbounded clip-fill-eo-unbounded clip-empty clip-empty-group clip-empty-save clip-fill clip-fill-no-op clip-fill-rule clip-fill-rule-pixel-aligned clip-group-shapes-aligned-rectangles clip-group-shapes-circles clip-image clip-intersect clip-nesting clip-operator clip-push-group clip-rectilinear clip-shape clip-stroke clip-stroke-no-op clip-text clip-twice clip-twice-rectangle clip-unbounded clipped-group clipped-surface close-path close-path-current-point composite-integer-translate-source composite-integer-translate-over composite-integer-translate-over-repeat copy-path create-from-png create-from-png-stream culled-glyphs curve-to-as-line-to dash-caps-joins dash-curve dash-infinite-loop dash-no-dash dash-offset dash-offset-negative dash-scale dash-state dash-zero-length degenerate-arc degenerate-arcs degenerate-curve-to degenerate-dash degenerate-linear-gradient degenerate-path degenerate-pen degenerate-radial-gradient degenerate-rel-curve-to drunkard-tails device-offset device-offset-fractional device-offset-positive device-offset-scale extend-pad extend-pad-border extend-pad-similar extend-reflect extend-reflect-similar extend-repeat extend-repeat-similar extended-blend extended-blend-alpha extended-blend-mask extended-blend-alpha-mask extended-blend-solid extended-blend-solid-alpha fill-alpha fill-alpha-pattern fill-and-stroke fill-and-stroke-alpha fill-and-stroke-alpha-add fill-degenerate-sort-order fill-empty fill-image fill-missed-stop fill-rule filter-bilinear-extents filter-nearest-offset filter-nearest-transformed finer-grained-fallbacks font-matrix-translation glyph-cache-pressure get-group-target gradient-alpha gradient-constant-alpha gradient-zero-stops gradient-zero-stops-mask group-clip group-paint group-unaligned halo halo-transform horizontal-clip huge-linear huge-radial image-surface-source image-bug-710072-aligned image-bug-710072-unaligned implicit-close infinite-join inverse-text joins joins-loop joins-star joins-retrace large-clip large-font large-source large-source-roi leaky-dash leaky-dashed-rectangle leaky-dashed-stroke leaky-polygon line-width a1-line-width line-width-large-overlap line-width-large-overlap-offset line-width-large-overlap-rotated line-width-large-overlap-flipped line-width-large-overlap-flopped line-width-large-overlap-dashed line-width-overlap line-width-overlap-offset line-width-overlap-rotated line-width-overlap-flipped line-width-overlap-flopped line-width-overlap-dashed line-width-scale line-width-tolerance linear-gradient linear-gradient-extend linear-gradient-large linear-gradient-one-stop linear-gradient-reflect linear-gradient-subset linear-step-function linear-uniform long-dashed-lines long-lines mask mask-alpha mask-ctm mask-surface-ctm mask-transformed-image mask-transformed-similar mesh-pattern mesh-pattern-accuracy mesh-pattern-conical mesh-pattern-control-points mesh-pattern-fold mesh-pattern-overlap mesh-pattern-transformed mime-data mime-surface miter-precision move-to-show-surface new-sub-path nil-surface operator operator-alpha operator-alpha-alpha operator-clear operator-source over-above-source over-around-source over-below-source over-between-source overlapping-boxes overlapping-glyphs overlapping-dash-caps paint paint-clip-fill-mono paint-clip-fill-aa paint-repeat paint-source-alpha paint-with-alpha paint-with-alpha-solid-clip paint-with-alpha-clip paint-with-alpha-clip-mask partial-clip-text-top partial-clip-text-bottom partial-clip-text-left partial-clip-text-right path-append path-stroke-twice pattern-getters pixman-rotate push-group push-group-color push-group-path-offset radial-gradient radial-gradient-mask radial-gradient-source radial-gradient-mask-source radial-gradient-one-stop radial-gradient-extend radial-outer-focus random-clip random-intersections-eo random-intersections-nonzero random-intersections-curves-eo random-intersections-curves-nz record-paint record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-fill-alpha record-select-font-face record-self-intersecting record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect record-extend-none-similar record-extend-pad-similar record-extend-repeat-similar record-extend-reflect-similar record-mesh recording-surface-over recording-surface-source recording-surface-extend-none recording-surface-extend-repeat recording-surface-extend-reflect recording-surface-extend-pad rectilinear-fill rectilinear-grid rectilinear-miter-limit rectilinear-dash rectilinear-stroke reflected-stroke rel-path rgb24-ignore-alpha rotate-image-surface-paint clip-rotate-image-surface-paint rotate-clip-image-surface-paint rotated-clip rounded-rectangle-fill rounded-rectangle-stroke scale-down-source-surface-paint scale-offset-image scale-offset-similar scale-source-surface-paint stroke-ctm-caps stroke-image stroke-open-box select-font-face self-copy self-copy-overlap self-intersecting set-source show-glyphs-advance show-glyphs-many show-text-current-point shape-general-convex shape-sierpinski skew-extreme smask smask-fill smask-image-mask smask-mask smask-paint smask-stroke smask-text solid-pattern-cache-stress source-clip source-clip-scale source-surface-scale-paint spline-decomposition stroke-pattern subsurface subsurface-image-repeat subsurface-repeat subsurface-reflect subsurface-pad subsurface-modify-child subsurface-modify-parent subsurface-outside-target subsurface-scale subsurface-similar-repeat surface-pattern surface-pattern-big-scale-down surface-pattern-operator surface-pattern-scale-down surface-pattern-scale-down-extend-repeat surface-pattern-scale-down-extend-none surface-pattern-scale-down-extend-reflect surface-pattern-scale-down-extend-pad surface-pattern-scale-up text-glyph-range text-pattern text-rotate text-transform tighten-bounds tiger transforms translate-show-surface trap-clip twin unaligned-box unbounded-operator unclosed-strokes user-font user-font-mask user-font-proxy user-font-rescale world-map world-map-stroke world-map-fill white-in-noop xcb-huge-image-shm xcb-stress-cache xcb-snapshot-assert xlib-expose-event zero-alpha zero-mask pthread-same-source pthread-show-text pthread-similar bitmap-font ft-show-glyphs-positioning ft-show-glyphs-table ft-text-vertical-layout-type1 ft-text-vertical-layout-type3 pdf-surface-source ps-surface-source svg-surface-source xcb-surface-source xlib-surface-source
ps3 (argb32): 75 crashed! - alpha-similar clear-source clip-group-shapes-aligned-rectangles clip-group-shapes-circles clip-push-group clip-unbounded clipped-group device-offset device-offset-positive extend-reflect-similar extend-repeat-similar extended-blend extended-blend-alpha extended-blend-mask extended-blend-alpha-mask fill-and-stroke-alpha-add get-group-target group-clip group-paint group-unaligned mask operator-alpha-alpha operator-source path-append pixman-rotate push-group-color push-group-path-offset record-paint record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-fill-alpha record-select-font-face record-self-intersecting record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect record-extend-none-similar record-extend-pad-similar record-extend-repeat-similar record-extend-reflect-similar record-mesh recording-surface-over recording-surface-source recording-surface-extend-none recording-surface-extend-repeat recording-surface-extend-reflect scale-offset-similar self-copy self-copy-overlap source-clip source-clip-scale subsurface subsurface-image-repeat subsurface-repeat subsurface-reflect subsurface-modify-child subsurface-modify-parent subsurface-outside-target subsurface-similar-repeat surface-pattern-operator surface-pattern-scale-down-extend-repeat surface-pattern-scale-down-extend-none surface-pattern-scale-down-extend-reflect xcb-huge-image-shm xlib-expose-event pthread-same-source pthread-show-text pthread-similar pdf-surface-source ps-surface-source svg-surface-source
ps3 (rgb24): 369 crashed! - a1-mask a8-clear a8-mask alpha-similar arc-infinite-loop arc-looping-dash api-special-cases big-line big-empty-box big-empty-triangle big-little-box big-little-triangle big-trap bilevel-image bug-bo-rectangular bug-bo-ricotz bug-extents caps checkerboard caps-joins caps-joins-alpha caps-joins-curve caps-tails-curve caps-sub-paths clear clear-source clip-all clip-contexts clip-complex-shape-eo-mono clip-complex-shape-eo-aa clip-disjoint clip-device-offset clip-stroke-unbounded clip-fill-nz-unbounded clip-fill-eo-unbounded clip-empty clip-empty-group clip-empty-save clip-fill clip-fill-no-op clip-fill-rule clip-fill-rule-pixel-aligned clip-group-shapes-aligned-rectangles clip-group-shapes-circles clip-image clip-intersect clip-nesting clip-operator clip-push-group clip-rectilinear clip-shape clip-stroke clip-stroke-no-op clip-text clip-twice clip-twice-rectangle clip-unbounded clipped-group clipped-surface close-path close-path-current-point composite-integer-translate-source composite-integer-translate-over composite-integer-translate-over-repeat copy-path create-from-png create-from-png-stream culled-glyphs curve-to-as-line-to dash-caps-joins dash-curve dash-infinite-loop dash-no-dash dash-offset dash-offset-negative dash-scale dash-state dash-zero-length degenerate-arc degenerate-arcs degenerate-curve-to degenerate-dash degenerate-linear-gradient degenerate-path degenerate-pen degenerate-radial-gradient degenerate-rel-curve-to drunkard-tails device-offset device-offset-fractional device-offset-positive device-offset-scale extend-pad extend-pad-border extend-pad-similar extend-reflect extend-reflect-similar extend-repeat extend-repeat-similar extended-blend extended-blend-alpha extended-blend-mask extended-blend-alpha-mask extended-blend-solid extended-blend-solid-alpha fill-alpha fill-alpha-pattern fill-and-stroke fill-and-stroke-alpha fill-and-stroke-alpha-add fill-degenerate-sort-order fill-empty fill-image fill-missed-stop fill-rule filter-bilinear-extents filter-nearest-offset filter-nearest-transformed finer-grained-fallbacks font-matrix-translation glyph-cache-pressure get-group-target gradient-alpha gradient-constant-alpha gradient-zero-stops gradient-zero-stops-mask group-clip group-paint group-unaligned halo halo-transform horizontal-clip huge-linear huge-radial image-surface-source image-bug-710072-aligned image-bug-710072-unaligned implicit-close infinite-join inverse-text joins joins-loop joins-star joins-retrace large-clip large-font large-source large-source-roi leaky-dash leaky-dashed-rectangle leaky-dashed-stroke leaky-polygon line-width a1-line-width line-width-large-overlap line-width-large-overlap-offset line-width-large-overlap-rotated line-width-large-overlap-flipped line-width-large-overlap-flopped line-width-large-overlap-dashed line-width-overlap line-width-overlap-offset line-width-overlap-rotated line-width-overlap-flipped line-width-overlap-flopped line-width-overlap-dashed line-width-scale line-width-tolerance linear-gradient linear-gradient-extend linear-gradient-large linear-gradient-one-stop linear-gradient-reflect linear-gradient-subset linear-step-function linear-uniform long-dashed-lines long-lines mask mask-alpha mask-ctm mask-surface-ctm mask-transformed-image mask-transformed-similar mesh-pattern mesh-pattern-accuracy mesh-pattern-conical mesh-pattern-control-points mesh-pattern-fold mesh-pattern-overlap mesh-pattern-transformed mime-data mime-surface miter-precision move-to-show-surface new-sub-path nil-surface operator operator-alpha operator-alpha-alpha operator-clear operator-source over-above-source over-around-source over-below-source over-between-source overlapping-boxes overlapping-glyphs overlapping-dash-caps paint paint-clip-fill-mono paint-clip-fill-aa paint-repeat paint-source-alpha paint-with-alpha paint-with-alpha-solid-clip paint-with-alpha-clip paint-with-alpha-clip-mask partial-clip-text-top partial-clip-text-bottom partial-clip-text-left partial-clip-text-right path-append path-stroke-twice pattern-getters pixman-rotate push-group push-group-color push-group-path-offset radial-gradient radial-gradient-mask radial-gradient-source radial-gradient-mask-source radial-gradient-one-stop radial-gradient-extend radial-outer-focus random-clip random-intersections-eo random-intersections-nonzero random-intersections-curves-eo random-intersections-curves-nz record-paint record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-fill-alpha record-select-font-face record-self-intersecting record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect record-extend-none-similar record-extend-pad-similar record-extend-repeat-similar record-extend-reflect-similar record-mesh recording-surface-over recording-surface-source recording-surface-extend-none recording-surface-extend-repeat recording-surface-extend-reflect recording-surface-extend-pad rectilinear-fill rectilinear-grid rectilinear-miter-limit rectilinear-dash rectilinear-stroke reflected-stroke rel-path rgb24-ignore-alpha rotate-image-surface-paint clip-rotate-image-surface-paint rotate-clip-image-surface-paint rotated-clip rounded-rectangle-fill rounded-rectangle-stroke scale-down-source-surface-paint scale-offset-image scale-offset-similar scale-source-surface-paint stroke-ctm-caps stroke-image stroke-open-box select-font-face self-copy self-copy-overlap self-intersecting set-source show-glyphs-advance show-glyphs-many show-text-current-point shape-general-convex shape-sierpinski skew-extreme smask smask-fill smask-image-mask smask-mask smask-paint smask-stroke smask-text solid-pattern-cache-stress source-clip source-clip-scale source-surface-scale-paint spline-decomposition stroke-pattern subsurface subsurface-image-repeat subsurface-repeat subsurface-reflect subsurface-pad subsurface-modify-child subsurface-modify-parent subsurface-outside-target subsurface-scale subsurface-similar-repeat surface-pattern surface-pattern-big-scale-down surface-pattern-operator surface-pattern-scale-down surface-pattern-scale-down-extend-repeat surface-pattern-scale-down-extend-none surface-pattern-scale-down-extend-reflect surface-pattern-scale-down-extend-pad surface-pattern-scale-up text-glyph-range text-pattern text-rotate text-transform tighten-bounds tiger transforms translate-show-surface trap-clip twin unaligned-box unbounded-operator unclosed-strokes user-font user-font-mask user-font-proxy user-font-rescale world-map world-map-stroke world-map-fill white-in-noop xcb-huge-image-shm xcb-stress-cache xcb-snapshot-assert xlib-expose-event zero-alpha zero-mask pthread-same-source pthread-show-text pthread-similar bitmap-font ft-show-glyphs-positioning ft-show-glyphs-table ft-text-vertical-layout-type1 ft-text-vertical-layout-type3 pdf-surface-source ps-surface-source svg-surface-source xcb-surface-source xlib-surface-source
xcb (argb32): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xcb (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xcb-window (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xcb-window& (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xcb-render-0.0 (argb32): 10 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-extend-none record-extend-repeat xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xcb-render-0.0 (rgb24): 10 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-extend-none record-extend-repeat xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xlib (argb32): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xlib (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xlib-window (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
xlib-fallback (rgb24): 13 crashed! - record-paint-alpha record-paint-alpha-solid-clip record-paint-alpha-clip record-paint-alpha-clip-mask record-text-transform record-extend-none record-extend-pad record-extend-repeat record-extend-reflect xcb-snapshot-assert pdf-surface-source ps-surface-source svg-surface-source
Comment 3 Uli Schlachter 2011-10-08 04:30:37 UTC
"I don't know if it makes
sense to flush a snapshot, but we allowed that previously. Should this change?"
I just noticed that this comment is wrong. When a surface is finished/destroyed, cairo_surface_finish() calls cairo_surface_flush(), thus this change can't work.

That leaves us with:

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 3be6d42..0810f18 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1314,6 +1314,7 @@ cairo_surface_flush (cairo_surface_t *surface)
 
     /* update the current snapshots *before* the user updates the surface */
     _cairo_surface_detach_snapshots (surface);
+    _cairo_surface_detach_mime_data (surface);
 
     if (surface->backend->flush) {
        status = surface->backend->flush (surface);
Comment 4 Uli Schlachter 2011-10-09 00:45:42 UTC
Fixed in a419d00fbecf18736f5566e1c4e3786cc7b4586c. Sorry for the spam earlier.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.