[PATCH]: gl: Return surface in error when creating oversized texture surfaces

Martin Robinson <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
From 33d7b642d615d0d5d9b2792b9510a501a6b8a4f6 Mon Sep 17 00:00:00 2001
From: Martin Robinson <[email protected]>
Date: Mon, 29 Jul 2013 11:14:34 -0700
Subject: [PATCH] gl: Return surface in error when creating oversized texture
 surfaces

When creating a texture surface that is larger than the maximum
framebuffer or texture dimensions of the context, return a surface in
error. Previously the code failed an assertion, but this prevents an
application from easily detecting when to fall back.
---
 src/cairo-gl-surface.c      | 14 +++++++-
 test/Makefile.sources       |  1 +
 test/gl-oversized-surface.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 test/gl-oversized-surface.c

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index f6b7928..16f1c4f 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -395,6 +395,16 @@ _cairo_gl_surface_init (cairo_device_t *device,
     _cairo_gl_surface_embedded_operand_init (surface);
 }
 
+static cairo_bool_t valid_size (cairo_gl_context_t *ctx,
+				int width, int height)
+{
+    return width >= 0 && width <= ctx->max_framebuffer_size &&
+	   height >= 0 && height <= ctx->max_framebuffer_size &&
+	   width <= ctx->max_texture_size &&
+	   height <= ctx->max_texture_size;
+}
+
+
 static cairo_surface_t *
 _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
 					      cairo_content_t	    content,
@@ -404,7 +414,9 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
 {
     cairo_gl_surface_t *surface;
 
-    assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
+    if (! valid_size (ctx, width, height))
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+
     surface = calloc (1, sizeof (cairo_gl_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
diff --git a/test/Makefile.sources b/test/Makefile.sources
index d44edb4..509c11c 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -394,6 +394,7 @@ ft_font_test_sources = \
 
 gl_surface_test_sources = \
 	gl-device-release.c \
+	gl-oversized-surface.c \
 	gl-surface-source.c
 
 quartz_surface_test_sources = quartz-surface-source.c
diff --git a/test/gl-oversized-surface.c b/test/gl-oversized-surface.c
new file mode 100644
index 0000000..507f388
--- /dev/null
+++ b/test/gl-oversized-surface.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2012 Igalia S.L.
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * IGALIA S.L. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Martin Robinson <[email protected]>
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+#include <assert.h>
+#include <limits.h>
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *test_ctx)
+{
+    int rgba_attribs[] = {
+	GLX_RGBA,
+	GLX_RED_SIZE, 1,
+	GLX_GREEN_SIZE, 1,
+	GLX_BLUE_SIZE, 1,
+	GLX_ALPHA_SIZE, 1,
+	GLX_DOUBLEBUFFER,
+	None
+    };
+
+    Display *display;
+    XVisualInfo *visual_info;
+    GLXContext glx_context;
+    cairo_device_t *device;
+    cairo_surface_t *oversized_surface;
+
+    display = XOpenDisplay (NULL);
+    if (display == NULL)
+	return CAIRO_TEST_UNTESTED;
+
+    visual_info = glXChooseVisual (display, DefaultScreen (display), rgba_attribs);
+    if (visual_info == NULL) {
+	XCloseDisplay (display);
+	return CAIRO_TEST_UNTESTED;
+    }
+
+    glx_context = glXCreateContext (display, visual_info, NULL, True);
+    if (glx_context == NULL) {
+	XCloseDisplay (display);
+	return CAIRO_TEST_UNTESTED;
+    }
+
+    device = cairo_glx_device_create (display, glx_context);
+
+    oversized_surface = cairo_gl_surface_create (device, CAIRO_CONTENT_COLOR_ALPHA, INT_MAX, INT_MAX);
+    assert (cairo_surface_status (oversized_surface) == CAIRO_STATUS_INVALID_SIZE);
+
+    cairo_device_destroy (device);
+    glXDestroyContext(display, glx_context);
+    XCloseDisplay (display);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gl_oversized_surface,
+	    "Test that creating a surface beyond texture limits results in an error surface",
+	    "gl", /* keywords */
+	    NULL, /* requirements */
+	    0, 0,
+	    preamble, NULL)
-- 
1.8.1.2

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.