From f8183521ffe24c43cd6ca45f1163f6ee90f19625 Mon Sep 17 00:00:00 2001 From: Stefan Altmayer Date: Tue, 13 Aug 2024 22:09:01 +0200 Subject: [PATCH] Fix: Calling any `locate` method with any `NAN` coordinates would return arbitrary results. It is better to systematically crash instead. --- src/delaunay_core/triangulation_ext.rs | 21 +++++++++++++++++++++ src/triangulation.rs | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/delaunay_core/triangulation_ext.rs b/src/delaunay_core/triangulation_ext.rs index 8119283..2186535 100644 --- a/src/delaunay_core/triangulation_ext.rs +++ b/src/delaunay_core/triangulation_ext.rs @@ -448,6 +448,10 @@ pub trait TriangulationExt: Triangulation { target_position: Point2<::Scalar>, start: FixedVertexHandle, ) -> PositionInTriangulation { + let pos = target_position.to_f64(); + assert!(!f64::is_nan(pos.x)); + assert!(!f64::is_nan(pos.y)); + if self.num_vertices() < 2 { return match self.vertices().next() { Some(single_vertex) if single_vertex.position() == target_position => { @@ -953,6 +957,23 @@ mod test { Ok(()) } + #[test] + #[should_panic] + fn test_locate_nan_empty() { + let d = DelaunayTriangulation::>::default(); + d.locate(Point2::new(0.0, f64::NAN)); + } + + #[test] + #[should_panic] + fn test_locate_nan() { + let points = random_points_with_seed(20, SEED); + let d = DelaunayTriangulation::>::bulk_load(points); + if let Ok(d) = d { + d.locate(Point2::new(0.0, f64::NAN)); + } + } + #[test] fn test_iterate_faces() -> Result<(), InsertionError> { const SIZE: usize = 1000; diff --git a/src/triangulation.rs b/src/triangulation.rs index 4602341..be7096d 100644 --- a/src/triangulation.rs +++ b/src/triangulation.rs @@ -395,6 +395,10 @@ pub trait Triangulation: Default { } /// Returns information about the location of a point in a triangulation. + /// + /// # Panics + /// + /// Panics if the target point has any `NAN` coordinate. fn locate( &self, point: Point2<::Scalar>, @@ -406,6 +410,10 @@ pub trait Triangulation: Default { /// Locates a vertex at a given position. /// /// Returns `None` if the point could not be found. + /// + /// # Panics + /// + /// Panics if the target point has any `NAN` coordinate. #[allow(clippy::type_complexity)] fn locate_vertex( &self, @@ -440,6 +448,10 @@ pub trait Triangulation: Default { /// The hint should be a vertex close to the position that /// is being looked up. /// + /// # Panics + /// + /// Panics if the target vertex has any `NAN` coordinate. + /// /// *See also [locate](Triangulation::locate), [locate_vertex](Triangulation::locate_vertex)* fn locate_with_hint( &self, @@ -474,6 +486,10 @@ pub trait Triangulation: Default { /// This method will invalidate all vertex, edge and face handles /// upon successful removal. /// + /// # Panics + /// + /// Panics if the target position has any `NAN` coordinate. + /// /// *See also [remove](Triangulation::remove)* fn locate_and_remove( &mut self,