[postgis-tickets] [SCM] PostGIS branch stable-2.5 updated. 2.5.8-5-g612a7e542

git at osgeo.org git at osgeo.org
Sat Nov 5 00:15:25 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-2.5 has been updated
       via  612a7e5423b4f5e1a10da1ccd78c949e56df6900 (commit)
      from  7f75bde03efc80c9f7677a4bfe4dcf2fab1fc180 (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 612a7e5423b4f5e1a10da1ccd78c949e56df6900
Author: Regina Obe <lr at pcorp.us>
Date:   Sat Nov 5 03:13:58 2022 -0400

    ST_DumpPoints crash with empty polygon
    Closes #5240 for PostGIS 2.5.9

diff --git a/NEWS b/NEWS
index 64d24115c..8997e2a4b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,11 @@
 PostGIS 2.5.9
-xxxx/xx/xx
+2022/11/xx
  * Bug fixes *
 
   - #5241, Crash on ST_SnapToGrid with empty multis (Regina Obe)
   - #5280, shp2pgsql: Handle load of dbase character fields with no width
            specified (Regina Obe)
+  - #5240, ST_DumpPoints crash with empty polygon (Regina Obe)
 
 PostGIS 2.5.8
 2022/08/17
diff --git a/postgis/lwgeom_dumppoints.c b/postgis/lwgeom_dumppoints.c
index 458428889..b31d49f31 100644
--- a/postgis/lwgeom_dumppoints.c
+++ b/postgis/lwgeom_dumppoints.c
@@ -162,83 +162,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,
-								FLAGS_GET_Z(tri->points->flags),
-								FLAGS_GET_M(tri->points->flags),
-								&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,
-								FLAGS_GET_Z(poly->rings[state->ring]->flags),
-								FLAGS_GET_M(poly->rings[state->ring]->flags),
-								&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,
+									FLAGS_GET_Z(tri->points->flags),
+									FLAGS_GET_M(tri->points->flags),
+									&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,
+									FLAGS_GET_Z(poly->rings[state->ring]->flags),
+									FLAGS_GET_M(poly->rings[state->ring]->flags),
+									&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
diff --git a/regress/dumppoints.sql b/regress/dumppoints.sql
index a6ecff640..7b5347ab2 100644
--- a/regress/dumppoints.sql
+++ b/regress/dumppoints.sql
@@ -183,3 +183,9 @@ SELECT '#2704', ST_DumpPoints('MULTIPOLYGON EMPTY'::geometry);
 SELECT '#2704', ST_DumpPoints('MULTILINESTRING EMPTY'::geometry);
 SELECT '#2704', ST_DumpPoints('LINESTRING EMPTY'::geometry);
 SELECT '#2704', ST_DumpPoints('GEOMETRYCOLLECTION EMPTY'::geometry);
+
+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/dumppoints_expected b/regress/dumppoints_expected
index a1e9fc2a8..37f2d6753 100644
--- a/regress/dumppoints_expected
+++ b/regress/dumppoints_expected
@@ -100,3 +100,15 @@
 {2,2}|POINT(3 3)
 {2,3}|POINT(3 1)
 {2,4}|POINT(1 1)
+#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)

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

Summary of changes:
 NEWS                        |   3 +-
 postgis/lwgeom_dumppoints.c | 146 ++++++++++++++++++++++----------------------
 regress/dumppoints.sql      |   6 ++
 regress/dumppoints_expected |  12 ++++
 4 files changed, 94 insertions(+), 73 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list