From 841da2b3f88b47737cf43f7c98d7689ff86d86fe Mon Sep 17 00:00:00 2001 From: Gustav Larsson Date: Mon, 20 Apr 2015 09:39:38 -0500 Subject: [PATCH 1/2] Fixed crashing bug in slic. The enforce connectivity step of slic runs a BFS and puts the results in coord_list. This coord_list has room for max_size elements, which is easily overrun if there is a large connected element. This change limits the BFS to max_size, so that if a connected area is bigger than max_size, it will be split up instead of the program crashing. --- skimage/segmentation/_slic.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/skimage/segmentation/_slic.pyx b/skimage/segmentation/_slic.pyx index 1418e902..0935550c 100644 --- a/skimage/segmentation/_slic.pyx +++ b/skimage/segmentation/_slic.pyx @@ -255,7 +255,7 @@ def _enforce_label_connectivity_cython(Py_ssize_t[:, :, ::1] segments, #perform a breadth first search to find # the size of the connected component - while bfs_visited != current_segment_size: + while bfs_visited < current_segment_size < max_size: for i in range(6): zz = coord_list[bfs_visited, 0] + ddz[i] yy = coord_list[bfs_visited, 1] + ddy[i] @@ -271,6 +271,8 @@ def _enforce_label_connectivity_cython(Py_ssize_t[:, :, ::1] segments, coord_list[current_segment_size, 1] = yy coord_list[current_segment_size, 2] = xx current_segment_size += 1 + if current_segment_size >= max_size: + break elif (connected_segments[zz, yy, xx] >= 0 and connected_segments[zz, yy, xx] != current_new_label): adjacent = connected_segments[zz, yy, xx] From 9de5a4557c9d32a62eac8c7d19028abad8b710b0 Mon Sep 17 00:00:00 2001 From: Gustav Larsson Date: Mon, 20 Apr 2015 14:35:57 -0500 Subject: [PATCH 2/2] Added test for buffer overflow in slic. As with all buffer overflows, it is hard to make a test that consistently triggers tests the behavior. This test does not work for me through the test_slic.py file, but it works in isolation. --- skimage/segmentation/tests/test_slic.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/skimage/segmentation/tests/test_slic.py b/skimage/segmentation/tests/test_slic.py index 239413d4..2dd4cde7 100644 --- a/skimage/segmentation/tests/test_slic.py +++ b/skimage/segmentation/tests/test_slic.py @@ -153,6 +153,12 @@ def test_enforce_connectivity(): enforce_connectivity=False, convert2lab=False) + # Make sure nothing fatal occurs (e.g. buffer overflow) at low values of + # max_size_factor + segments_connected_low_max = slic(img, 2, compactness=0.0001, + enforce_connectivity=True, + convert2lab=False, max_size_factor=0.8) + result_connected = np.array([[0, 0, 0, 1, 1, 1], [0, 0, 0, 1, 1, 1], [0, 0, 0, 1, 1, 1]], np.float) @@ -163,6 +169,7 @@ def test_enforce_connectivity(): assert_equal(segments_connected, result_connected) assert_equal(segments_disconnected, result_disconnected) + assert_equal(segments_connected_low_max, result_connected) def test_slic_zero():