From 2c6bec64c0508981cd37800b732000bee3946497 Mon Sep 17 00:00:00 2001 From: Pierre Dejoue Date: Thu, 21 May 2020 16:14:10 +0200 Subject: [PATCH] Throw in Triangle::NeighborAcross in case of null pointer Add an example quad for which the exception is throwni in the tests --- poly2tri/common/shapes.cc | 12 +++++++++--- testbed/data/deadly_quad.dat | 4 ++++ unittest/main.cpp | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 testbed/data/deadly_quad.dat diff --git a/poly2tri/common/shapes.cc b/poly2tri/common/shapes.cc index c044311..6e65dc6 100644 --- a/poly2tri/common/shapes.cc +++ b/poly2tri/common/shapes.cc @@ -352,12 +352,18 @@ void Triangle::SetDelunayEdgeCW(const Point& p, bool e) // The neighbor across to given point Triangle& Triangle::NeighborAcross(const Point& opoint) { + Triangle* neighbor = nullptr; if (&opoint == points_[0]) { - return *neighbors_[0]; + neighbor = neighbors_[0]; } else if (&opoint == points_[1]) { - return *neighbors_[1]; + neighbor = neighbors_[1]; + } else { + neighbor = neighbors_[2]; } - return *neighbors_[2]; + if (neighbor == nullptr) { + throw std::runtime_error("NeighborAcross - null neighbor"); + } + return *neighbor; } void Triangle::DebugPrint() diff --git a/testbed/data/deadly_quad.dat b/testbed/data/deadly_quad.dat new file mode 100644 index 0000000..7e4b217 --- /dev/null +++ b/testbed/data/deadly_quad.dat @@ -0,0 +1,4 @@ +0.0 0.0 +1.0e-05 0.0 +1.1e-04 3.0e-07 +1.0e-04 3.0e-07 diff --git a/unittest/main.cpp b/unittest/main.cpp index 6978b33..671b216 100644 --- a/unittest/main.cpp +++ b/unittest/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include BOOST_AUTO_TEST_CASE(BasicTest) { @@ -40,6 +41,22 @@ BOOST_AUTO_TEST_CASE(QuadTest) } } +BOOST_AUTO_TEST_CASE(QuadTestThrow) +{ + // Very narrow quad that demonstrates a failure case during triangulation + std::vector polyline { + new p2t::Point(0.0, 0.0), + new p2t::Point(1.0e-05, 0.0), + new p2t::Point(1.1e-04, 3.0e-07), + new p2t::Point(1.0e-04, 3.0e-07) + }; + p2t::CDT cdt{ polyline }; + BOOST_CHECK_THROW(cdt.Triangulate(), std::runtime_error); + for (const auto p : polyline) { + delete p; + } +} + BOOST_AUTO_TEST_CASE(TestbedFilesTest) { for (const auto& filename : { "custom.dat", "diamond.dat", "star.dat", "test.dat" }) {