[postgis-tickets] [SCM] PostGIS branch master updated. 3.3.0rc2-143-gdb9ec5fe3

git at osgeo.org git at osgeo.org
Tue Sep 27 17:40:13 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, master has been updated
       via  db9ec5fe325b417a0013c4c4b73213a1a51666f2 (commit)
      from  22601a15422f00477e74f65db7414afc48e6454f (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 db9ec5fe325b417a0013c4c4b73213a1a51666f2
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.4.0dev

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:
 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 +++
 5 files changed, 110 insertions(+), 74 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list