[cairo-commit] 2 commits - src/cairo-recording-surface.c src/cairo-surface-snapshot.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 11 19:43:55 UTC 2021


 src/cairo-recording-surface.c |    5 +++++
 src/cairo-surface-snapshot.c  |    4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

New commits:
commit e45875142fc5d0bb7968b150f379172130415342
Merge: 891468f19 66c991185
Author: Heiko Lewin <hlewin at gmx.de>
Date:   Mon Jan 11 19:43:54 2021 +0000

    Merge branch 'snapshot-error-fixes' into 'master'
    
    Slightly improve dealing with error snapshots
    
    See merge request cairo/cairo!92

commit 66c9911850257b2d42a6abf756baed16fe1ae9d5
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Dec 26 16:09:16 2020 +0100

    Slightly improve dealing with error snapshots
    
    An error in _cairo_surface_snapshot_copy_on_write() results in a
    snapshot in an error state and the snapshot's ->target could now point
    to a surface from _cairo_surface_create_in_error(). These surfaces e.g.
    have ->backend == NULL. Thus, anything looking at ->backend->type now
    explodes. This commit deals with two places which caused segfaults in
    this situation.
    
    There is no test case for this, because
    _cairo_surface_snapshot_copy_on_write() really is not supposed to fail.
    
    Found-while-investigating: https://gitlab.freedesktop.org/cairo/cairo/-/issues/448
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 6df8b0821..3e8b8e780 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -1764,6 +1764,11 @@ _cairo_recording_surface_merge_source_attributes (cairo_recording_surface_t  *su
 	if (_cairo_surface_is_snapshot (surf))
 	    free_me = surf = _cairo_surface_snapshot_get_target (surf);
 
+	if (unlikely (surf->status))
+	    // There was some kind of error and the surface could be a nil error
+	    // surface with various "problems" (e.g. ->backend == NULL).
+	    return;
+
 	if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	    cairo_recording_surface_t *rec_surf = (cairo_recording_surface_t *) surf;
 
diff --git a/src/cairo-surface-snapshot.c b/src/cairo-surface-snapshot.c
index a8b8c0e45..b2908f6bc 100644
--- a/src/cairo-surface-snapshot.c
+++ b/src/cairo-surface-snapshot.c
@@ -71,7 +71,9 @@ _cairo_surface_snapshot_flush (void *abstract_surface, unsigned flags)
     cairo_status_t status;
 
     target = _cairo_surface_snapshot_get_target (&surface->base);
-    status = _cairo_surface_flush (target, flags);
+    status = target->status;
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = _cairo_surface_flush (target, flags);
     cairo_surface_destroy (target);
 
     return status;


More information about the cairo-commit mailing list