[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