[SCM] PostGIS branch master updated. 3.7.0beta1-41-gf402e3b5a

git at osgeo.org git at osgeo.org
Sat Jul 25 22:07:40 PDT 2026


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  f402e3b5af3d6e42367b8ddc455fe8590ba73d22 (commit)
       via  8d143e4b549567d362edd0e80349bd5de29a4c1e (commit)
      from  65808b2e13cdf37baa7302a5d8e1d6f00c1863de (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 f402e3b5af3d6e42367b8ddc455fe8590ba73d22
Merge: 65808b2e1 8d143e4b5
Author: Darafei Praliaskouski <komzpa at gmail.com>
Date:   Sat Jul 25 22:07:34 2026 -0700

    Merge pull request 'Guard ST_LargestEmptyCircle against degenerate boundaries' (!519) from Komzpa/postgis:codex/largest-empty-circle-invalid-20260726 into master
    
    Reviewed-on: https://gitea.osgeo.org/postgis/postgis/pulls/519


commit 8d143e4b549567d362edd0e80349bd5de29a4c1e
Author: Darafei Praliaskouski <me at komzpa.net>
Date:   Sun Jul 26 04:15:53 2026 +0400

    Guard largest empty circle boundary inputs

diff --git a/NEWS b/NEWS
index d0f8c33e2..ac043babb 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ These are only changes since 3.7.0beta1.
 
  - GT-504, Report extension script/library version mismatches before loading
           functions unavailable in an older library (Darafei Praliaskouski)
+ - GT-515, Reject invalid ST_LargestEmptyCircle boundaries before GEOS can
+          spend unbounded time on them (Darafei Praliaskouski)
 
 * Enhancements *
 
diff --git a/doc/reference_processing.xml b/doc/reference_processing.xml
index 450b22060..8b756ce0b 100644
--- a/doc/reference_processing.xml
+++ b/doc/reference_processing.xml
@@ -1438,6 +1438,7 @@ radius_line | LINESTRING(94 110,63 85)</screen>
       <refsection>
         <title>Description</title>
         <para>Finds the largest circle which does not overlap a set of point and line obstacles. (Polygonal geometries may be included as obstacles, but only their boundary lines are used.) The center of the circle is constrained to lie inside a polygonal boundary, which by default is the convex hull of the input geometry. The circle center is the point in the interior of the boundary which has the farthest distance from the obstacles. The circle itself is provided by the center point and a nearest point lying on an obstacle determining the circle radius.</para>
+        <para>If a boundary is supplied it must be a valid polygonal geometry with positive area.</para>
         <para>The circle center is determined to a given  accuracy specified by a distance tolerance, using an iterative algorithm. If the accuracy distance is not specified a reasonable default is used.</para>
         <para>Returns a record with fields:</para>
 
diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c
index 4358c0664..25688680b 100644
--- a/postgis/lwgeom_geos.c
+++ b/postgis/lwgeom_geos.c
@@ -418,8 +418,18 @@ Datum ST_LargestEmptyCircle(PG_FUNCTION_ARGS)
 		GEOSGeometry *ginput, *gcircle, *gcenter, *gnearest;
 		GEOSGeometry *gboundary = NULL;
 		double width, height, size;
-		GBOX gbox;
-		LWGEOM *lwg;
+		double boundary_area;
+		GBOX gbox, boundary_gbox;
+		LWGEOM *lwg, *lwboundary;
+
+		if (hasBoundary &&
+		    (!gserialized_get_gbox_p(boundary, &boundary_gbox) ||
+		     !(boundary_gbox.xmax > boundary_gbox.xmin && boundary_gbox.ymax > boundary_gbox.ymin)))
+		{
+			lwpgerror("Boundary geometry must have positive area");
+			PG_RETURN_NULL();
+		}
+
 		lwg = lwgeom_from_gserialized(geom);
 		if (!lwgeom_isfinite(lwg))
 		{
@@ -440,6 +450,24 @@ Datum ST_LargestEmptyCircle(PG_FUNCTION_ARGS)
 			tolerance = size / 1000.0;
 		}
 
+		if (hasBoundary)
+		{
+			lwboundary = lwgeom_from_gserialized(boundary);
+			if (!lwgeom_isfinite(lwboundary))
+			{
+				lwgeom_free(lwboundary);
+				lwpgerror("Boundary geometry contains invalid coordinates");
+				PG_RETURN_NULL();
+			}
+			boundary_area = lwgeom_area(lwboundary);
+			lwgeom_free(lwboundary);
+			if (!(boundary_area > 0.0))
+			{
+				lwpgerror("Boundary geometry must have positive area");
+				PG_RETURN_NULL();
+			}
+		}
+
 		initGEOS(lwpgnotice, lwgeom_geos_error);
 
 		ginput = POSTGIS2GEOS(geom);
@@ -448,9 +476,24 @@ Datum ST_LargestEmptyCircle(PG_FUNCTION_ARGS)
 
 		if (hasBoundary)
 		{
+			char boundary_valid;
 			gboundary = POSTGIS2GEOS(boundary);
 			if (!gboundary)
 				HANDLE_GEOS_ERROR("Boundary could not be converted to GEOS");
+			boundary_valid = GEOSisValid(gboundary);
+			if (boundary_valid == 2)
+			{
+				GEOSGeom_destroy(ginput);
+				GEOSGeom_destroy(gboundary);
+				HANDLE_GEOS_ERROR("GEOSisValid");
+			}
+			if (!boundary_valid)
+			{
+				GEOSGeom_destroy(ginput);
+				GEOSGeom_destroy(gboundary);
+				lwpgerror("Boundary geometry is invalid");
+				PG_RETURN_NULL();
+			}
 		}
 
 		gcircle = GEOSLargestEmptyCircle(ginput, gboundary, tolerance);
diff --git a/regress/core/geos39.sql b/regress/core/geos39.sql
index 41e8e2d11..1dcf6c801 100644
--- a/regress/core/geos39.sql
+++ b/regress/core/geos39.sql
@@ -61,3 +61,9 @@ SELECT 'lec-1', round(radius::numeric,3),
   ST_AsText(nearest,3) AS nearest
 FROM ST_LargestEmptyCircle(
   'MULTIPOINT ((4 3), (7 6), (4 6))');
+
+SELECT 'lec-invalid-boundary', radius
+FROM ST_LargestEmptyCircle(
+  'POINT(0 0)'::geometry,
+  20.1,
+  'POLYGON((1 2,1 2,1 2,1 2,3 2,1 2))'::geometry);
diff --git a/regress/core/geos39_expected b/regress/core/geos39_expected
index 9584a74b6..757ea5231 100644
--- a/regress/core/geos39_expected
+++ b/regress/core/geos39_expected
@@ -10,3 +10,4 @@ rp-2|POINT(1 19)
 rp-3|POINT(0 20)
 ERROR:  Geometry contains invalid coordinates
 lec-1|2.121|POINT(5.5 4.5)|POINT(4 3)
+ERROR:  Boundary geometry must have positive area

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

Summary of changes:
 NEWS                         |  2 ++
 doc/reference_processing.xml |  1 +
 postgis/lwgeom_geos.c        | 47 ++++++++++++++++++++++++++++++++++++++++++--
 regress/core/geos39.sql      |  6 ++++++
 regress/core/geos39_expected |  1 +
 5 files changed, 55 insertions(+), 2 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list