diff --git a/src_c/mask.c b/src_c/mask.c index e1b326e1d7..41ed9a6249 100644 --- a/src_c/mask.c +++ b/src_c/mask.c @@ -1443,26 +1443,39 @@ static PyObject * mask_connected_component(PyObject *self, PyObject *args) { bitmask_t *input = pgMask_AsBitmap(self); - bitmask_t *output = bitmask_create(input->w, input->h); - pgMaskObject *maskobj = PyObject_New(pgMaskObject, &pgMask_Type); - int x, y; - - x = -1; + bitmask_t *output = NULL; + pgMaskObject *maskobj = NULL; + int x = -1, y = -1; + Py_ssize_t args_exist = PyTuple_Size(args); + + if (args_exist) { + if (!PyArg_ParseTuple(args, "|(ii)", &x, &y)) { + return NULL; + } - if (!PyArg_ParseTuple(args, "|(ii)", &x, &y)) { - return NULL; + if (x < 0 || x >= input->w || y < 0 || y >= input->h) { + return PyErr_Format(PyExc_IndexError, "%d, %d is out of bounds", x, + y); + } } - /* if a coordinate is specified, make the pixel there is actually set */ - if (x == -1 || bitmask_getbit(input, x, y)) { + output = bitmask_create(input->w, input->h); + + /* If a pixel index is provided and the indexed bit is not set, then the + * returned mask is empty. + */ + if (!args_exist || bitmask_getbit(input, x, y)) { if (largest_connected_comp(input, output, x, y) == -2) { + bitmask_free(output); return RAISE(PyExc_MemoryError, - "Not enough memory to get bounding rects. \n"); + "cannot allocate memory for connected component"); } } - if (maskobj) + maskobj = PyObject_New(pgMaskObject, &pgMask_Type); + if (maskobj) { maskobj->mask = output; + } return (PyObject *)maskobj; } diff --git a/test/mask_test.py b/test/mask_test.py index 9bbd35fd6d..28e50b3f1c 100644 --- a/test/mask_test.py +++ b/test/mask_test.py @@ -892,13 +892,11 @@ def test_connected_component__unset_bit(self): self.assertEqual(original_mask.get_size(), expected_size) self.assertEqual(original_mask.get_at(unset_pos), 0) - # The skip() can be removed when issue #841 is fixed/closed. - @unittest.skip('can cause segmentation fault') def test_connected_component__out_of_bounds(self): """Ensure connected_component() checks bounds.""" width, height = 19, 11 original_size = (width, height) - original_mask = pygame.mask.Mask(expected_size, fill=True) + original_mask = pygame.mask.Mask(original_size, fill=True) original_count = original_mask.count() for pos in ((0, -1), (-1, 0), (0, height + 1), (width + 1, 0)):