]> granicus.if.org Git - postgis/commitdiff
Fix backend crash on ST_OffsetCurve failure
authorDaniel Baston <dbaston@gmail.com>
Wed, 8 Aug 2018 00:57:31 +0000 (00:57 +0000)
committerDaniel Baston <dbaston@gmail.com>
Wed, 8 Aug 2018 00:57:31 +0000 (00:57 +0000)
Closes #4143

git-svn-id: http://svn.osgeo.org/postgis/trunk@16683 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
liblwgeom/cunit/cu_geos.c
liblwgeom/lwgeom_geos.c

diff --git a/NEWS b/NEWS
index 7fdf5ba1e211ee9446bdbc2715aeae2e5d8754e4..1ee60b65f4beb8b17bb7e11000a1a3911c384939 100644 (file)
--- 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
 
index 3055cb8d997d7a86ce6a909c06a47b7fa61b1331..ec3cedc0b16457546288e78cde1f4319b5161535 100644 (file)
@@ -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);
 }
index 9d4ac9cb46aeaec84c134a2438cd71077200a260..ece4c2439d0268ee402cbea74903e7d6acb0a799 100644 (file)
@@ -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;
 }