From 86b142e6201b9cdadccb69782b4f2089d6d1b20a Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 8 Aug 2018 00:57:31 +0000 Subject: [PATCH] Fix backend crash on ST_OffsetCurve failure Closes #4143 git-svn-id: http://svn.osgeo.org/postgis/trunk@16683 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/cunit/cu_geos.c | 15 ++++++++++ liblwgeom/lwgeom_geos.c | 58 ++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index 7fdf5ba1e..1ee60b65f 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ New since PostGIS 2.5.0beta1 multiple dots (Raúl Marín, Paul Ramsey) - #4140, Use user-provided CFLAGS in address standardizer and the topology module (Raúl Marín) + - #4143, Fix backend crash when ST_OffsetCurve fails (Dan Baston) See PostGIS 2.5.0 section for full details diff --git a/liblwgeom/cunit/cu_geos.c b/liblwgeom/cunit/cu_geos.c index 3055cb8d9..ec3cedc0b 100644 --- a/liblwgeom/cunit/cu_geos.c +++ b/liblwgeom/cunit/cu_geos.c @@ -109,6 +109,20 @@ test_geos_offsetcurve(void) lwgeom_free(geom2); } +static void +test_geos_offsetcurve_crash(void) +{ + // Test for Trac #4143. The specific output or lack of output is not important, + // we're just testing that we don't crash. + LWGEOM* in = lwgeom_from_wkt("LINESTRING(362194.505 5649993.044,362197.451 5649994.125,362194.624 5650001.876,362189.684 5650000.114,362192.542 5649992.324,362194.505 5649993.044)", LW_PARSER_CHECK_NONE); + LWGEOM* out = lwgeom_offsetcurve(in, -0.045, 8, 2, 5.0); + + lwgeom_free(in); + if (out) { + lwgeom_free(out); + } +} + static void test_geos_makevalid(void) { @@ -165,5 +179,6 @@ void geos_suite_setup(void) PG_ADD_TEST(suite, test_geos_subdivide); PG_ADD_TEST(suite, test_geos_linemerge); PG_ADD_TEST(suite, test_geos_offsetcurve); + PG_ADD_TEST(suite, test_geos_offsetcurve_crash); PG_ADD_TEST(suite, test_geos_makevalid); } diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index 9d4ac9cb4..ece4c2439 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -1363,6 +1363,7 @@ lwgeom_offsetcurve(const LWGEOM* geom, double size, int quadsegs, int joinStyle, { int32_t srid = RESULT_SRID(geom); LWGEOM *result = NULL; + LWGEOM *noded = NULL; if (srid == SRID_INVALID) return NULL; if (lwgeom_dimension(geom) != 1) @@ -1371,40 +1372,41 @@ lwgeom_offsetcurve(const LWGEOM* geom, double size, int quadsegs, int joinStyle, return NULL; } - switch (geom->type) + while (!result) { - case LINETYPE: - result = lwline_offsetcurve(lwgeom_as_lwline(geom), size, quadsegs, joinStyle, mitreLimit); - break; - case COLLECTIONTYPE: - case MULTILINETYPE: - result = lwcollection_offsetcurve(lwgeom_as_lwcollection(geom), size, quadsegs, joinStyle, mitreLimit); - break; - default: - lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type)); - return NULL; - } - - if (!result) - { - /* Node the input geometry and try again */ - LWGEOM* noded = lwgeom_node(geom); - if (!noded) + switch (geom->type) { - lwerror("%s: cannot node input", __func__); + case LINETYPE: + result = lwline_offsetcurve(lwgeom_as_lwline(geom), size, quadsegs, joinStyle, mitreLimit); + break; + case COLLECTIONTYPE: + case MULTILINETYPE: + result = lwcollection_offsetcurve(lwgeom_as_lwcollection(geom), size, quadsegs, joinStyle, mitreLimit); + break; + default: + lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type)); return NULL; } - result = lwgeom_offsetcurve(noded, size, quadsegs, joinStyle, mitreLimit); - lwfree(noded); - } - - if (!result) - { - lwerror("%s: noded geometry cannot be offset", __func__); - return NULL; + if (result) + return result; + else if (!noded) + { + noded = lwgeom_node(geom); + if (!noded) + { + lwfree(noded); + lwerror("lwgeom_offsetcurve: cannot node input"); + return NULL; + } + geom = noded; + } + else + { + lwerror("lwgeom_offsetcurve: noded geometry cannot be offset"); + return NULL; + } } - return result; } -- 2.40.0