From ec53f3d879df0d3e447aea19231da45201bb49c7 Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Wed, 17 Jan 2018 09:53:45 +0000 Subject: [PATCH] Fix crash in case of empty ring --- .../geometry/polygon_vertex_processor.hpp | 6 +- .../geometry/polygon_vertex_processor.cpp | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/unit/geometry/polygon_vertex_processor.cpp diff --git a/include/mapnik/geometry/polygon_vertex_processor.hpp b/include/mapnik/geometry/polygon_vertex_processor.hpp index 5c95aed14..b632c800f 100644 --- a/include/mapnik/geometry/polygon_vertex_processor.hpp +++ b/include/mapnik/geometry/polygon_vertex_processor.hpp @@ -24,6 +24,7 @@ #define MAPNIK_GEOMETRY_POLYGON_VERTEX_PROCESSOR_HPP // geometry +#include #include namespace mapnik { namespace geometry { @@ -46,7 +47,10 @@ struct polygon_vertex_processor ring.emplace_back(p); break; case SEG_CLOSE: - ring.emplace_back(ring.front()); + if (!ring.empty()) + { + ring.emplace_back(ring.front()); + } polygon_.emplace_back(std::move(ring)); ring = linear_ring(); break; diff --git a/test/unit/geometry/polygon_vertex_processor.cpp b/test/unit/geometry/polygon_vertex_processor.cpp new file mode 100644 index 000000000..c40c26900 --- /dev/null +++ b/test/unit/geometry/polygon_vertex_processor.cpp @@ -0,0 +1,62 @@ +#include "catch.hpp" +#include "unit/vertex_adapter/fake_path.hpp" + +#include + +TEST_CASE("polygon_vertex_processor") { + +SECTION("empty polygon") { + + fake_path path = {}; + mapnik::geometry::polygon_vertex_processor proc; + proc.add_path(path); + CHECK(proc.polygon_.size() == 0); +} + +SECTION("empty outer ring") { + + fake_path path = {}; + path.vertices_.emplace_back(0, 0, mapnik::SEG_CLOSE); + path.rewind(0); + + mapnik::geometry::polygon_vertex_processor proc; + proc.add_path(path); + REQUIRE(proc.polygon_.size() == 1); + REQUIRE(proc.polygon_.front().size() == 0); +} + +SECTION("empty inner ring") { + + fake_path path = {}; + path.vertices_.emplace_back(-1, -1, mapnik::SEG_MOVETO); + path.vertices_.emplace_back( 1, -1, mapnik::SEG_LINETO); + path.vertices_.emplace_back( 1, 1, mapnik::SEG_LINETO); + path.vertices_.emplace_back(-1, 1, mapnik::SEG_LINETO); + path.vertices_.emplace_back( 0, 0, mapnik::SEG_CLOSE); + path.vertices_.emplace_back( 0, 0, mapnik::SEG_CLOSE); + path.rewind(0); + + mapnik::geometry::polygon_vertex_processor proc; + proc.add_path(path); + + REQUIRE(proc.polygon_.size() == 2); + auto outer_ring = proc.polygon_.front(); + REQUIRE(outer_ring.size() == 5); + + CHECK(outer_ring[0].x == Approx(-1)); + CHECK(outer_ring[0].y == Approx(-1)); + + CHECK(outer_ring[1].x == Approx( 1)); + CHECK(outer_ring[1].y == Approx(-1)); + + CHECK(outer_ring[2].x == Approx( 1)); + CHECK(outer_ring[2].y == Approx( 1)); + + CHECK(outer_ring[3].x == Approx(-1)); + CHECK(outer_ring[3].y == Approx( 1)); + + CHECK(outer_ring[4].x == Approx(-1)); + CHECK(outer_ring[4].y == Approx(-1)); +} + +}