[pygobject] cairo: do proper type checking when converting from py to cairo. Fixes #197



commit 2a5946ce67db7933061f3a630a9e59ed193a416d
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Fri Apr 13 20:22:37 2018 +0200

    cairo: do proper type checking when converting from py to cairo. Fixes #197

 gi/pygi-foreign-cairo.c | 75 +++++++++++++++++++++++++++++++++++++++++++++----
 tests/test_cairo.py     | 31 ++++++++++++++++++++
 2 files changed, 101 insertions(+), 5 deletions(-)
---
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 03ee05a5..c398cb72 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -52,6 +52,11 @@ cairo_context_to_arg (PyObject        *value,
 {
     cairo_t *cr;
 
+    if (!PyObject_TypeCheck (value, &PycairoContext_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Context");
+        return NULL;
+    }
+
     cr = PycairoContext_GET (value);
     if (!cr) {
         return NULL;
@@ -89,7 +94,14 @@ cairo_context_release (GIBaseInfo *base_info,
 static int
 cairo_context_to_gvalue (GValue *value, PyObject *obj)
 {
-    cairo_t *cr = PycairoContext_GET (obj);
+    cairo_t *cr;
+
+    if (!PyObject_TypeCheck (obj, &PycairoContext_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Context");
+        return -1;
+    }
+
+    cr = PycairoContext_GET (obj);
     if (!cr) {
         return -1;
     }
@@ -125,6 +137,11 @@ cairo_surface_to_arg (PyObject        *value,
 {
     cairo_surface_t *surface;
 
+    if (!PyObject_TypeCheck (value, &PycairoSurface_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Surface");
+        return NULL;
+    }
+
     surface = ( (PycairoSurface*) value)->surface;
     if (!surface) {
         PyErr_SetString (PyExc_ValueError, "Surface instance wrapping a NULL surface");
@@ -162,7 +179,14 @@ cairo_surface_release (GIBaseInfo *base_info,
 static int
 cairo_surface_to_gvalue (GValue *value, PyObject *obj)
 {
-    cairo_surface_t *surface = ((PycairoSurface*) obj)->surface;
+    cairo_surface_t *surface;
+
+    if (!PyObject_TypeCheck (obj, &PycairoSurface_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Surface");
+        return -1;
+    }
+
+    surface = ((PycairoSurface*) obj)->surface;
     if (!surface) {
         return -1;
     }
@@ -214,6 +238,11 @@ cairo_path_to_arg (PyObject        *value,
 {
     cairo_path_t *path;
 
+    if (!PyObject_TypeCheck (value, &PycairoPath_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Path");
+        return NULL;
+    }
+
     path = ( (PycairoPath*) value)->path;
     if (!path) {
         PyErr_SetString (PyExc_ValueError, "Path instance wrapping a NULL path");
@@ -258,7 +287,14 @@ cairo_path_release (GIBaseInfo *base_info,
 static int
 cairo_font_face_to_gvalue (GValue *value, PyObject *obj)
 {
-    cairo_font_face_t *font_face = ((PycairoFontFace*) obj)->font_face;
+    cairo_font_face_t *font_face;
+
+    if (!PyObject_TypeCheck (obj, &PycairoFontFace_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.FontFace");
+        return -1;
+    }
+
+    font_face = ((PycairoFontFace*) obj)->font_face;
     if (!font_face) {
         return -1;
     }
@@ -291,6 +327,11 @@ cairo_font_options_to_arg (PyObject        *value,
 {
     cairo_font_options_t *font_options;
 
+    if (!PyObject_TypeCheck (value, &PycairoFontOptions_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.FontOptions");
+        return NULL;
+    }
+
     font_options = ( (PycairoFontOptions*) value)->font_options;
     if (!font_options) {
         PyErr_SetString (PyExc_ValueError, "FontOptions instance wrapping a NULL font_options");
@@ -333,7 +374,14 @@ cairo_font_options_release (GIBaseInfo *base_info,
 static int
 cairo_scaled_font_to_gvalue (GValue *value, PyObject *obj)
 {
-    cairo_scaled_font_t *scaled_font = ((PycairoScaledFont*) obj)->scaled_font;
+    cairo_scaled_font_t *scaled_font;
+
+    if (!PyObject_TypeCheck (obj, &PycairoScaledFont_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.ScaledFont");
+        return -1;
+    }
+
+    scaled_font = ((PycairoScaledFont*) obj)->scaled_font;
     if (!scaled_font) {
         return -1;
     }
@@ -364,7 +412,14 @@ cairo_scaled_font_from_gvalue (const GValue *value)
 static int
 cairo_pattern_to_gvalue (GValue *value, PyObject *obj)
 {
-    cairo_pattern_t *pattern = ((PycairoPattern*) obj)->pattern;
+    cairo_pattern_t *pattern;
+
+    if (!PyObject_TypeCheck (obj, &PycairoPattern_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Pattern");
+        return -1;
+    }
+
+    pattern = ((PycairoPattern*) obj)->pattern;
     if (!pattern) {
         return -1;
     }
@@ -395,6 +450,11 @@ cairo_region_to_arg (PyObject        *value,
 {
     cairo_region_t *region;
 
+    if (!PyObject_TypeCheck (value, &PycairoRegion_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Region");
+        return NULL;
+    }
+
     region = ( (PycairoRegion*) value)->region;
     if (!region) {
         PyErr_SetString (PyExc_ValueError, "Region instance wrapping a NULL region");
@@ -458,6 +518,11 @@ cairo_matrix_to_arg (PyObject        *value,
 {
     cairo_matrix_t *matrix;
 
+    if (!PyObject_TypeCheck (value, &PycairoMatrix_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Matrix");
+        return NULL;
+    }
+
     matrix = &(( (PycairoMatrix*) value)->matrix);
 
     arg->v_pointer = matrix;
diff --git a/tests/test_cairo.py b/tests/test_cairo.py
index ea2733b2..a34798ff 100644
--- a/tests/test_cairo.py
+++ b/tests/test_cairo.py
@@ -5,6 +5,7 @@
 from __future__ import absolute_import
 
 import unittest
+import pytest
 
 import gi
 
@@ -42,6 +43,9 @@ class Test(unittest.TestCase):
         context = cairo.Context(surface)
         Regress.test_cairo_context_full_in(context)
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_context_full_in(object())
+
     def test_cairo_context_none_return(self):
         context = Regress.test_cairo_context_none_return()
         self.assertTrue(isinstance(context, cairo.Context))
@@ -57,6 +61,9 @@ class Test(unittest.TestCase):
         Regress.test_cairo_path_none_in(path)
         surface.finish()
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_path_none_in(object())
+
     def test_cairo_path_full_in_full_return(self):
         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
         context = cairo.Context(surface)
@@ -79,6 +86,9 @@ class Test(unittest.TestCase):
         options = cairo.FontOptions()
         Regress.test_cairo_font_options_full_in(options)
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_font_options_full_in(object())
+
     def test_cairo_font_options_none_in(self):
         options = cairo.FontOptions()
         Regress.test_cairo_font_options_none_in(options)
@@ -87,10 +97,16 @@ class Test(unittest.TestCase):
         region = cairo.Region()
         Regress.test_cairo_region_full_in(region)
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_region_full_in(object())
+
     def test_cairo_matrix_none_in(self):
         matrix = cairo.Matrix()
         Regress.test_cairo_matrix_none_in(matrix)
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_matrix_none_in(object())
+
     def test_cairo_matrix_none_return(self):
         matrix = Regress.test_cairo_matrix_none_return()
         assert matrix == cairo.Matrix()
@@ -128,6 +144,9 @@ class Test(unittest.TestCase):
         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
         Regress.test_cairo_surface_full_in(surface)
 
+        with pytest.raises(TypeError):
+            Regress.test_cairo_surface_full_in(object())
+
     def test_require_foreign(self):
         self.assertEqual(gi.require_foreign('cairo'), None)
         self.assertEqual(gi.require_foreign('cairo', 'Context'), None)
@@ -204,6 +223,9 @@ class TestSignalMarshaling(unittest.TestCase):
         result = self.pass_object_through_signal(self.context, self.tester.sig_context)
         self.assertTrue(isinstance(result, cairo.Context))
 
+        with pytest.raises(TypeError):
+            self.pass_object_through_signal(object(), self.tester.sig_context)
+
     def test_surface(self):
         result = self.pass_object_through_signal(self.surface, self.tester.sig_surface)
         self.assertTrue(isinstance(result, cairo.Surface))
@@ -213,6 +235,9 @@ class TestSignalMarshaling(unittest.TestCase):
         result = self.pass_object_through_signal(font_face, self.tester.sig_font_face)
         self.assertTrue(isinstance(result, cairo.FontFace))
 
+        with pytest.raises(TypeError):
+            self.pass_object_through_signal(object(), self.tester.sig_font_face)
+
     def test_scaled_font(self):
         scaled_font = cairo.ScaledFont(self.context.get_font_face(),
                                        cairo.Matrix(),
@@ -221,8 +246,14 @@ class TestSignalMarshaling(unittest.TestCase):
         result = self.pass_object_through_signal(scaled_font, self.tester.sig_scaled_font)
         self.assertTrue(isinstance(result, cairo.ScaledFont))
 
+        with pytest.raises(TypeError):
+            result = self.pass_object_through_signal(object(), self.tester.sig_scaled_font)
+
     def test_pattern(self):
         pattern = cairo.SolidPattern(1, 1, 1, 1)
         result = self.pass_object_through_signal(pattern, self.tester.sig_pattern)
         self.assertTrue(isinstance(result, cairo.Pattern))
         self.assertTrue(isinstance(result, cairo.SolidPattern))
+
+        with pytest.raises(TypeError):
+            result = self.pass_object_through_signal(object(), self.tester.sig_pattern)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]