From 693c7e7e2e7afb67bbdbe5ef551345a3e8f47c43 Mon Sep 17 00:00:00 2001 From: Ady0333 Date: Sat, 5 Sep 2026 20:53:11 +0000 Subject: [PATCH 1/2] r.lake: Reject seed coordinates north or west of the region The conversion to a cell index truncated towards zero, so a coordinate less than one cell north or west of the region gave index 0 instead of a negative value and passed the check below zero. Such a seed was silently moved to the first row or column instead of being rejected. --- raster/r.lake/main.c | 5 ++-- raster/r.lake/tests/r_lake_test.py | 43 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/raster/r.lake/main.c b/raster/r.lake/main.c index a1abbf5e27b..3a413cacf76 100644 --- a/raster/r.lake/main.c +++ b/raster/r.lake/main.c @@ -28,6 +28,7 @@ * Kaarliit, shii programma ir veltiita Tev. * */ +#include #include #include @@ -232,8 +233,8 @@ int main(int argc, char *argv[]) G_scan_easting(sdxy_opt->answers[0], &east, G_projection()); G_scan_northing(sdxy_opt->answers[1], &north, G_projection()); - start_col = (int)Rast_easting_to_col(east, &window); - start_row = (int)Rast_northing_to_row(north, &window); + start_col = (int)floor(Rast_easting_to_col(east, &window)); + start_row = (int)floor(Rast_northing_to_row(north, &window)); if (start_row < 0 || start_row >= rows || start_col < 0 || start_col >= cols) diff --git a/raster/r.lake/tests/r_lake_test.py b/raster/r.lake/tests/r_lake_test.py index e1a3ff905fd..78317c6b9a0 100644 --- a/raster/r.lake/tests/r_lake_test.py +++ b/raster/r.lake/tests/r_lake_test.py @@ -110,6 +110,34 @@ def test_seed_coordinates_on_region_edge_are_rejected( assert "Seed point outside the current region" in error.value.errors +@pytest.mark.parametrize( + "coordinates", + [(25.5, 50.5), (25.5, 50.9), (-0.5, 25.5), (-0.9, 25.5)], + ids=["north", "north-almost-one-cell", "west", "west-almost-one-cell"], +) +def test_seed_coordinates_less_than_a_cell_outside_are_rejected( + session_with_flat_terrain, coordinates +): + """Coordinates north or west of the region are outside it. + + Truncating the converted index towards zero turns the whole interval + between -1 and 0 into row or column 0, which hides these coordinates from + the check below zero. + """ + tools = Tools(session=session_with_flat_terrain) + + with pytest.raises(ToolError) as error: + tools.r_lake( + elevation="terrain", + water_level=10, + lake="lake_out", + coordinates=coordinates, + ) + + assert error.value.returncode == 1 + assert "Seed point outside the current region" in error.value.errors + + def test_seed_coordinates_in_last_row_are_accepted(session_with_flat_terrain): """Coordinates in the last row are inside the region and fill it.""" tools = Tools(session=session_with_flat_terrain) @@ -120,3 +148,18 @@ def test_seed_coordinates_in_last_row_are_accepted(session_with_flat_terrain): stats = tools.r_univar(map="lake_out", format="json").json assert stats["n"] == 2500 + + +@pytest.mark.parametrize("coordinates", [(25.5, 50), (0, 25.5)], ids=["north", "west"]) +def test_seed_coordinates_on_north_and_west_edge_are_accepted( + session_with_flat_terrain, coordinates +): + """The northern and western edges belong to the first row and column.""" + tools = Tools(session=session_with_flat_terrain) + + tools.r_lake( + elevation="terrain", water_level=10, lake="lake_out", coordinates=coordinates + ) + + stats = tools.r_univar(map="lake_out", format="json").json + assert stats["n"] == 2500 From 309c44fa85b6db25416514b66d00388f0e6d52f7 Mon Sep 17 00:00:00 2001 From: Ady0333 Date: Sun, 6 Sep 2026 05:20:12 +0000 Subject: [PATCH 2/2] r.lake: Link libm for floor() Commit 6f95cc1cac added a call to floor() but r.lake was not linked against libm, so the CMake build failed with an undefined reference. Add the math library to both build systems, as other raster modules do. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VaNhLMPgugrZq8EBLRdno5 --- raster/CMakeLists.txt | 2 +- raster/r.lake/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/raster/CMakeLists.txt b/raster/CMakeLists.txt index ad7bdeb8611..8a08f6b4f8e 100644 --- a/raster/CMakeLists.txt +++ b/raster/CMakeLists.txt @@ -318,7 +318,7 @@ build_program_in_subdir( build_program_in_subdir(r.latlong DEPENDS grass_gis grass_raster grass_gproj) -build_program_in_subdir(r.lake DEPENDS grass_gis grass_raster) +build_program_in_subdir(r.lake DEPENDS grass_gis grass_raster ${LIBM}) build_program_in_subdir( r.mask.status diff --git a/raster/r.lake/Makefile b/raster/r.lake/Makefile index 1aa155f2baa..2b1df47131a 100644 --- a/raster/r.lake/Makefile +++ b/raster/r.lake/Makefile @@ -4,7 +4,7 @@ MODULE_TOPDIR = ../.. PGM = r.lake -LIBES = $(RASTERLIB) $(GISLIB) +LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB) DEPENDENCIES = $(RASTERDEP) $(GISDEP) include $(MODULE_TOPDIR)/include/Make/Module.make