[postgis-tickets] [SCM] PostGIS branch stable-3.2 updated. 3.2.3-10-gef3320708

git at osgeo.org git at osgeo.org
Tue Sep 27 17:59:14 PDT 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, stable-3.2 has been updated
       via  ef33207089b3e06290d76be7fea9406b436423c9 (commit)
      from  c7c59b49d36705a68181e3cc54ccac1a3e9886b2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ef33207089b3e06290d76be7fea9406b436423c9
Author: Regina Obe <lr at pcorp.us>
Date:   Tue Sep 27 20:38:49 2022 -0400

    ST_DumpPoints and ST_DumpSegments crash on multipolygon
    with empty polygon
    References #5240 for PostGIS 3.2.4

diff --git a/NEWS b/NEWS
index 480fd9021..e6e9e982e 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ PostGIS 3.2.4
 * Bug Fixes *
   - #5227, typo in ST_LineLocatePoint error message (Sandro Santilli)
   - #5231, PG15 no longer compiles because SQL/JSON removed PG upstream (Regina Obe)
+  - #5420, ST_DumpPoints and ST_DumpSegments crash with empty polygon (Regina Obe)
 
 PostGIS 3.2.3
 2022/08/18
diff --git a/postgis/lwgeom_dumppoints.c b/postgis/lwgeom_dumppoints.c
index 223a8e354..7bbd95ad6 100644
--- a/postgis/lwgeom_dumppoints.c
+++ b/postgis/lwgeom_dumppoints.c
@@ -151,7 +151,7 @@ Datum LWGEOM_dumppoints(PG_FUNCTION_ARGS) {
 		lwgeom = node->geom;
 
 		/* need to return a point from this geometry */
-		if (!lwgeom_is_collection(lwgeom)) {
+		if (!lwgeom_is_collection(lwgeom) ) {
 			/* either return a point, or pop the stack */
 			/* TODO use a union?  would save a tiny amount of stack space.
 			 * probably not worth the bother
@@ -163,83 +163,85 @@ Datum LWGEOM_dumppoints(PG_FUNCTION_ARGS) {
 			LWPOINT *lwpoint = NULL;
 			POINT4D	pt;
 
-			/*
-			 * net result of switch should be to set lwpoint to the
-			 * next point to return, or leave at NULL if there
-			 * are no more points in the geometry
-			 */
-			switch(lwgeom->type) {
-				case TRIANGLETYPE:
-					tri = lwgeom_as_lwtriangle(lwgeom);
-					if (state->pt == 0) {
-						state->path[state->pathlen++] = Int32GetDatum(state->ring+1);
-					}
-					if (state->pt <= 3) {
-						getPoint4d_p(tri->points, state->pt, &pt);
-						lwpoint = lwpoint_make(tri->srid,
-								lwgeom_has_z(lwgeom),
-								lwgeom_has_m(lwgeom),
-								&pt);
-					}
-					if (state->pt > 3) {
-						state->pathlen--;
-					}
-					break;
-				case POLYGONTYPE:
-					poly = lwgeom_as_lwpoly(lwgeom);
-					if (state->pt == poly->rings[state->ring]->npoints) {
-						state->pt = 0;
-						state->ring++;
-						state->pathlen--;
-					}
-					if (state->pt == 0 && state->ring < poly->nrings) {
-						/* handle new ring */
-						state->path[state->pathlen] = Int32GetDatum(state->ring+1);
-						state->pathlen++;
-					}
-				       	if (state->ring == poly->nrings) {
-					} else {
-					/* TODO should be able to directly get the point
-					 * into the point array of a fixed lwpoint
-					 */
-					/* can't get the point directly from the ptarray because
-					 * it might be aligned wrong, so at least one memcpy
-					 * seems unavoidable
-					 * It might be possible to pass it directly to gserialized
-					 * depending how that works, it might effectively be gserialized
-					 * though a brief look at the code indicates not
-					 */
-						getPoint4d_p(poly->rings[state->ring], state->pt, &pt);
-						lwpoint = lwpoint_make(poly->srid,
-								lwgeom_has_z(lwgeom),
-								lwgeom_has_m(lwgeom),
-								&pt);
-					}
-					break;
-				case POINTTYPE:
-					if (state->pt == 0) lwpoint = lwgeom_as_lwpoint(lwgeom);
-					break;
-				case LINETYPE:
-					line = lwgeom_as_lwline(lwgeom);
-					if (line->points && state->pt <= line->points->npoints) {
-						lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, state->pt);
-					}
-					break;
-				case CIRCSTRINGTYPE:
-					circ = lwgeom_as_lwcircstring(lwgeom);
-					if (circ->points && state->pt <= circ->points->npoints) {
-						lwpoint = lwcircstring_get_lwpoint((LWCIRCSTRING*)lwgeom, state->pt);
-					}
-					break;
-				default:
-					ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
-						errmsg("Invalid Geometry type %d passed to ST_DumpPoints()", lwgeom->type)));
+			if ( !lwgeom_is_empty(lwgeom) ) {
+				/*
+				* net result of switch should be to set lwpoint to the
+				* next point to return, or leave at NULL if there
+				* are no more points in the geometry
+				*/
+				switch(lwgeom->type) {
+					case TRIANGLETYPE:
+						tri = lwgeom_as_lwtriangle(lwgeom);
+						if (state->pt == 0) {
+							state->path[state->pathlen++] = Int32GetDatum(state->ring+1);
+						}
+						if (state->pt <= 3) {
+							getPoint4d_p(tri->points, state->pt, &pt);
+							lwpoint = lwpoint_make(tri->srid,
+									lwgeom_has_z(lwgeom),
+									lwgeom_has_m(lwgeom),
+									&pt);
+						}
+						if (state->pt > 3) {
+							state->pathlen--;
+						}
+						break;
+					case POLYGONTYPE:
+						poly = lwgeom_as_lwpoly(lwgeom);
+						if (state->pt == poly->rings[state->ring]->npoints) {
+							state->pt = 0;
+							state->ring++;
+							state->pathlen--;
+						}
+						if (state->pt == 0 && state->ring < poly->nrings) {
+							/* handle new ring */
+							state->path[state->pathlen] = Int32GetDatum(state->ring+1);
+							state->pathlen++;
+						}
+									if (state->ring == poly->nrings) {
+						} else {
+						/* TODO should be able to directly get the point
+						* into the point array of a fixed lwpoint
+						*/
+						/* can't get the point directly from the ptarray because
+						* it might be aligned wrong, so at least one memcpy
+						* seems unavoidable
+						* It might be possible to pass it directly to gserialized
+						* depending how that works, it might effectively be gserialized
+						* though a brief look at the code indicates not
+						*/
+							getPoint4d_p(poly->rings[state->ring], state->pt, &pt);
+							lwpoint = lwpoint_make(poly->srid,
+									lwgeom_has_z(lwgeom),
+									lwgeom_has_m(lwgeom),
+									&pt);
+						}
+						break;
+					case POINTTYPE:
+						if (state->pt == 0) lwpoint = lwgeom_as_lwpoint(lwgeom);
+						break;
+					case LINETYPE:
+						line = lwgeom_as_lwline(lwgeom);
+						if (line->points && state->pt <= line->points->npoints) {
+							lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, state->pt);
+						}
+						break;
+					case CIRCSTRINGTYPE:
+						circ = lwgeom_as_lwcircstring(lwgeom);
+						if (circ->points && state->pt <= circ->points->npoints) {
+							lwpoint = lwcircstring_get_lwpoint((LWCIRCSTRING*)lwgeom, state->pt);
+						}
+						break;
+					default:
+						ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+							errmsg("Invalid Geometry type %d passed to ST_DumpPoints()", lwgeom->type)));
+				}
 			}
 
 			/*
 			 * At this point, lwpoint is either NULL, in which case
 			 * we need to pop the geometry stack and get the next
-			 * geometry, if amy, or lwpoint is set and we construct
+			 * geometry, if any, or lwpoint is set and we construct
 			 * a record type with the integer array of geometry
 			 * indexes and the point number, and the actual point
 			 * geometry itself
@@ -381,7 +383,7 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
 		node = &state->stack[state->stacklen - 1];
 		lwgeom = node->geom;
 
-		if (lwgeom->type == LINETYPE || lwgeom->type == TRIANGLETYPE || lwgeom->type == POLYGONTYPE)
+		if ( !lwgeom_is_empty(lwgeom) && (lwgeom->type == LINETYPE || lwgeom->type == TRIANGLETYPE || lwgeom->type == POLYGONTYPE) )
 		{
 			if (lwgeom->type == LINETYPE)
 			{
diff --git a/regress/core/dumppoints.sql b/regress/core/dumppoints.sql
index 62e6ea192..7bc2c72ba 100644
--- a/regress/core/dumppoints.sql
+++ b/regress/core/dumppoints.sql
@@ -197,3 +197,9 @@ FROM (
         )'::geometry AS geom
               ) AS g
      ) j;
+
+SELECT '#5240',  dp.path, ST_AsText(dp.geom)
+	FROM ( SELECT ST_GeomFromText('MULTIPOLYGON (((9 9, 9 1, 1 1, 2 4, 7 7, 9 9)), EMPTY)', 4326) As the_geom ) As foo1, ST_DumpPoints(foo1.the_geom) AS dp;
+
+SELECT '#5240',  dp.path, ST_AsText(dp.geom)
+	FROM ( SELECT ST_GeomFromText('MULTIPOLYGON (EMPTY, ((9 9, 9 1, 1 1, 2 4, 7 7, 9 9)) )', 4326) As the_geom ) As foo1, ST_DumpPoints(foo1.the_geom) AS dp;
diff --git a/regress/core/dumppoints_expected b/regress/core/dumppoints_expected
index 824dc9696..dc78683ef 100644
--- a/regress/core/dumppoints_expected
+++ b/regress/core/dumppoints_expected
@@ -104,3 +104,15 @@
 {3,1}|POINT(22 22)
 {5,1}|POINT(33 33)
 {6,1}|POINT(44 44)
+#5240|{1,1,1}|POINT(9 9)
+#5240|{1,1,2}|POINT(9 1)
+#5240|{1,1,3}|POINT(1 1)
+#5240|{1,1,4}|POINT(2 4)
+#5240|{1,1,5}|POINT(7 7)
+#5240|{1,1,6}|POINT(9 9)
+#5240|{2,1,1}|POINT(9 9)
+#5240|{2,1,2}|POINT(9 1)
+#5240|{2,1,3}|POINT(1 1)
+#5240|{2,1,4}|POINT(2 4)
+#5240|{2,1,5}|POINT(7 7)
+#5240|{2,1,6}|POINT(9 9)
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 3991021e7..b36b7948c 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -71,3 +71,9 @@ FROM (
             )'::geometry AS geom
               ) AS g
      ) j;
+
+SELECT '#5240',  dp.path, ST_AsText(dp.geom)
+	FROM ( SELECT ST_GeomFromText('MULTIPOLYGON (((9 9, 9 1, 1 1, 2 4, 7 7, 9 9)), EMPTY)', 4326) As the_geom ) As foo1, ST_DumpSegments(foo1.the_geom) AS dp;
+
+SELECT '#5240',  dp.path, ST_AsText(dp.geom)
+	FROM ( SELECT ST_GeomFromText('MULTIPOLYGON (EMPTY, ((9 9, 9 1, 1 1, 2 4, 7 7, 9 9)) )', 4326) As the_geom ) As foo1, ST_DumpSegments(foo1.the_geom) AS dp;
diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected
index 5d1c8d3d4..895c96c49 100644
--- a/regress/core/dumpsegments_expected
+++ b/regress/core/dumpsegments_expected
@@ -33,3 +33,13 @@ dumpsegments12|{1,1,3}|LINESTRING(0 1 0,0 0 0)
 dumpsegments12|{2,1,1}|LINESTRING(0 0 0,0 1 0)
 dumpsegments12|{2,1,2}|LINESTRING(0 1 0,1 1 0)
 dumpsegments12|{2,1,3}|LINESTRING(1 1 0,0 0 0)
+#5240|{1,1,1}|LINESTRING(9 9,9 1)
+#5240|{1,1,2}|LINESTRING(9 1,1 1)
+#5240|{1,1,3}|LINESTRING(1 1,2 4)
+#5240|{1,1,4}|LINESTRING(2 4,7 7)
+#5240|{1,1,5}|LINESTRING(7 7,9 9)
+#5240|{2,1,1}|LINESTRING(9 9,9 1)
+#5240|{2,1,2}|LINESTRING(9 1,1 1)
+#5240|{2,1,3}|LINESTRING(1 1,2 4)
+#5240|{2,1,4}|LINESTRING(2 4,7 7)
+#5240|{2,1,5}|LINESTRING(7 7,9 9)

-----------------------------------------------------------------------

Summary of changes:
 NEWS                               |   1 +
 postgis/lwgeom_dumppoints.c        | 150 +++++++++++++++++++------------------
 regress/core/dumppoints.sql        |   6 ++
 regress/core/dumppoints_expected   |  12 +++
 regress/core/dumpsegments.sql      |   6 ++
 regress/core/dumpsegments_expected |  10 +++
 6 files changed, 111 insertions(+), 74 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list