From b856781eccd6ff1582bd14a6d3508c8aa8c75a2b Mon Sep 17 00:00:00 2001 From: Oliver Tan Date: Tue, 19 Apr 2022 22:35:12 +0000 Subject: [PATCH] builtins: fix panic for ST_MinimumBoundingCircle with num_segments Release note (bug fix): Fix a bug where ST_MinimumBoundingCircle would panic with infinite coordinates and a num_segments argument. --- pkg/geo/geomfn/linestring.go | 3 +++ pkg/geo/geomfn/topology_operations.go | 6 ++++++ pkg/sql/logictest/testdata/logic_test/geospatial | 3 +++ pkg/sql/sem/builtins/geo_builtins.go | 6 ------ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/geo/geomfn/linestring.go b/pkg/geo/geomfn/linestring.go index 96b27c01b89a..dd8aa77987f3 100644 --- a/pkg/geo/geomfn/linestring.go +++ b/pkg/geo/geomfn/linestring.go @@ -60,6 +60,9 @@ func LineMerge(g geo.Geometry) (geo.Geometry, error) { if g.Empty() { return g, nil } + if BoundingBoxHasInfiniteCoordinates(g) { + return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow") + } ret, err := geos.LineMerge(g.EWKB()) if err != nil { return geo.Geometry{}, err diff --git a/pkg/geo/geomfn/topology_operations.go b/pkg/geo/geomfn/topology_operations.go index fb61162bc4b8..5a481f65c6dd 100644 --- a/pkg/geo/geomfn/topology_operations.go +++ b/pkg/geo/geomfn/topology_operations.go @@ -16,6 +16,8 @@ import ( "github.com/cockroachdb/cockroach/pkg/geo" "github.com/cockroachdb/cockroach/pkg/geo/geopb" "github.com/cockroachdb/cockroach/pkg/geo/geos" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" ) // Boundary returns the boundary of a given Geometry. @@ -42,6 +44,10 @@ func Centroid(g geo.Geometry) (geo.Geometry, error) { // MinimumBoundingCircle returns minimum bounding circle of an EWKB func MinimumBoundingCircle(g geo.Geometry) (geo.Geometry, geo.Geometry, float64, error) { + if BoundingBoxHasInfiniteCoordinates(g) { + return geo.Geometry{}, geo.Geometry{}, 0, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow") + } + polygonEWKB, centroidEWKB, radius, err := geos.MinimumBoundingCircle(g.EWKB()) if err != nil { return geo.Geometry{}, geo.Geometry{}, 0, err diff --git a/pkg/sql/logictest/testdata/logic_test/geospatial b/pkg/sql/logictest/testdata/logic_test/geospatial index 8214dcfb71fc..2c9733d9114f 100644 --- a/pkg/sql/logictest/testdata/logic_test/geospatial +++ b/pkg/sql/logictest/testdata/logic_test/geospatial @@ -5670,6 +5670,9 @@ true statement error st_minimumboundingcircle\(\): value out of range: overflow select st_minimumboundingcircle(st_makepoint(((-0.27013513189303495):::FLOAT8::FLOAT8 // 5e-324:::FLOAT8::FLOAT8)::FLOAT8::FLOAT8, (-0.4968052087960828):::FLOAT8::FLOAT8)::GEOMETRY::GEOMETRY)::GEOMETRY +statement error st_minimumboundingcircle\(\): value out of range: overflow +select st_minimumboundingcircle(st_makepoint(((-0.27013513189303495):::FLOAT8::FLOAT8 // 5e-324:::FLOAT8::FLOAT8)::FLOAT8::FLOAT8, (-0.4968052087960828):::FLOAT8::FLOAT8)::GEOMETRY::GEOMETRY, 10)::GEOMETRY + subtest st_unaryunion query T diff --git a/pkg/sql/sem/builtins/geo_builtins.go b/pkg/sql/sem/builtins/geo_builtins.go index 1f962e8a456a..196a3bbb7806 100644 --- a/pkg/sql/sem/builtins/geo_builtins.go +++ b/pkg/sql/sem/builtins/geo_builtins.go @@ -3181,9 +3181,6 @@ Note If the result has zero or one points, it will be returned as a POINT. If it defProps(), geometryOverload1( func(ctx *tree.EvalContext, g *tree.DGeometry) (tree.Datum, error) { - if geomfn.BoundingBoxHasInfiniteCoordinates(g.Geometry) { - return nil, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow") - } line, err := geomfn.LineMerge(g.Geometry) if err != nil { return nil, err @@ -6471,9 +6468,6 @@ The parent_only boolean is always ignored.`, "st_minimumboundingcircle": makeBuiltin(defProps(), geometryOverload1( func(evalContext *tree.EvalContext, g *tree.DGeometry) (tree.Datum, error) { - if geomfn.BoundingBoxHasInfiniteCoordinates(g.Geometry) { - return nil, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow") - } polygon, _, _, err := geomfn.MinimumBoundingCircle(g.Geometry) if err != nil { return nil, err