Commit 168a0875 authored by Martin Pitt's avatar Martin Pitt
Browse files

_pygi_argument_from_object(): Check for compatible data type

Verify that the passed PyObject actually matches the expected type of the
argument. With this, trying to assign a wrong type to a property will now raise
a proper TypeError.
parent 5948b62b
......@@ -728,6 +728,12 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *int_;
if (!PyObject_TypeCheck (object, &PyInt_Type) &&
!PyObject_TypeCheck (object, &PyLong_Type)) {
PyErr_SetString (PyExc_TypeError, "expected int or long argument");
break;
}
int_ = PYGLIB_PyNumber_Long (object);
if (int_ == NULL) {
break;
......@@ -752,6 +758,12 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
guint64 value;
if (!PyObject_TypeCheck (object, &PyInt_Type) &&
!PyObject_TypeCheck (object, &PyLong_Type)) {
PyErr_SetString (PyExc_TypeError, "expected int or long argument");
break;
}
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
......@@ -782,6 +794,12 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
gint64 value;
if (!PyObject_TypeCheck (object, &PyInt_Type) &&
!PyObject_TypeCheck (object, &PyLong_Type)) {
PyErr_SetString (PyExc_TypeError, "expected int or long argument");
break;
}
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
......@@ -804,6 +822,13 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *float_;
if (!PyObject_TypeCheck (object, &PyFloat_Type) &&
!PyObject_TypeCheck (object, &PyInt_Type) &&
!PyObject_TypeCheck (object, &PyLong_Type)) {
PyErr_SetString (PyExc_TypeError, "expected float or int argument");
break;
}
float_ = PyNumber_Float (object);
if (float_ == NULL) {
break;
......@@ -818,6 +843,13 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *float_;
if (!PyObject_TypeCheck (object, &PyFloat_Type) &&
!PyObject_TypeCheck (object, &PyInt_Type) &&
!PyObject_TypeCheck (object, &PyLong_Type)) {
PyErr_SetString (PyExc_TypeError, "expected float or int argument");
break;
}
float_ = PyNumber_Float (object);
if (float_ == NULL) {
break;
......@@ -951,6 +983,13 @@ _pygi_argument_from_object (PyObject *object,
break;
}
/* Note, strings are sequences, but we cannot accept them here */
if (!PySequence_Check (object) ||
PyString_Check (object) || PyUnicode_Check (object)) {
PyErr_SetString (PyExc_TypeError, "expected sequence");
break;
}
length = PySequence_Length (object);
if (length < 0) {
break;
......
......@@ -287,6 +287,9 @@ pygi_set_property_value_real (PyGObject *instance,
transfer = g_property_info_get_ownership_transfer (property_info);
arg = _pygi_argument_from_object (py_value, type_info, transfer);
if (PyErr_Occurred())
goto out;
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
// FIXME: Lots of types still unhandled
......
......@@ -2021,6 +2021,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_int=-42)
self.assertEqual(obj.props.some_int, -42)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', None)
self.assertEqual(obj.props.some_int, -42)
def test_uint(self):
self.assertEqual(self.obj.props.some_uint, 0)
self.obj.props.some_uint = GObject.G_MAXUINT
......@@ -2029,6 +2034,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_uint=42)
self.assertEqual(obj.props.some_uint, 42)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', None)
self.assertEqual(obj.props.some_uint, 42)
def test_long(self):
self.assertEqual(self.obj.props.some_long, 0)
self.obj.props.some_long = GObject.G_MAXLONG
......@@ -2037,6 +2047,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_long=-42)
self.assertEqual(obj.props.some_long, -42)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', None)
self.assertEqual(obj.props.some_long, -42)
def test_ulong(self):
self.assertEqual(self.obj.props.some_ulong, 0)
self.obj.props.some_ulong = GObject.G_MAXULONG
......@@ -2045,6 +2060,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
self.assertEqual(obj.props.some_ulong, 42)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', None)
self.assertEqual(obj.props.some_ulong, 42)
def test_int64(self):
self.assertEqual(self.obj.props.some_int64, 0)
self.obj.props.some_int64 = GObject.G_MAXINT64
......@@ -2069,6 +2089,14 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
self.assertAlmostEqual(obj.props.some_float, 42.42, 4)
obj = GIMarshallingTests.PropertiesObject(some_float=42)
self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', None)
self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
def test_double(self):
self.assertEqual(self.obj.props.some_double, 0)
self.obj.props.some_double = GObject.G_MAXDOUBLE
......@@ -2077,13 +2105,25 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
self.assertAlmostEqual(obj.props.some_double, 42.42)
obj = GIMarshallingTests.PropertiesObject(some_double=42)
self.assertAlmostEqual(obj.props.some_double, 42.0)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', None)
self.assertAlmostEqual(obj.props.some_double, 42.0)
def test_strv(self):
self.assertEqual(self.obj.props.some_strv, [])
self.obj.props.some_strv = ['hello', 'world']
self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 1)
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', [1, 2])
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', ['foo', 1])
self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
self.assertEqual(obj.props.some_strv, ['hello', 'world'])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment