lib/raster3d/tilewrite: Use >= for tile index bounds check#7723
Conversation
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…/lib-raster3d-tilewrite.c
Add a pytest test covering the tileIndex bounds check in Rast3d_write_tile: an index equal to nTiles must be rejected as out of range, and the last valid index must be accepted. The invalid call runs in a subprocess using the grass.lib.raster3d ctypes bindings because the rejection is a fatal error which exits the calling process. The out-of-range test fails without the bounds check change in this branch and passes with it. The test was written by Claude Code using the Claude Fable 5 model.
|
Here is the Claude Code with Fable 5 review you asked for (I'm also adding a test): Review of PR #7723 — lib/raster3d/tilewrite: Use
|
| WRITE_TILE_SCRIPT = """\ | ||
| import sys | ||
| from ctypes import POINTER, byref, c_float, cast | ||
|
|
||
| from grass.lib.gis import G_gisinit | ||
| from grass.lib.raster import FCELL_TYPE | ||
| from grass.lib.raster3d import ( | ||
| RASTER3D_NO_CACHE, | ||
| RASTER3D_Map, | ||
| RASTER3D_Region, | ||
| Rast3d_adjust_region, | ||
| Rast3d_init_defaults, | ||
| Rast3d_open_cell_new, | ||
| Rast3d_write_tile, | ||
| ) | ||
|
|
||
| index_offset = int(sys.argv[1]) | ||
|
|
||
| G_gisinit("test") | ||
| Rast3d_init_defaults() | ||
|
|
||
| region = RASTER3D_Region() | ||
| region.north = 100 | ||
| region.south = 0 | ||
| region.east = 100 | ||
| region.west = 0 | ||
| region.top = 100 | ||
| region.bottom = 0 | ||
| region.rows = 10 | ||
| region.cols = 10 | ||
| region.depths = 10 | ||
| Rast3d_adjust_region(byref(region)) | ||
|
|
||
| handle = Rast3d_open_cell_new( | ||
| "bounds_check_3d", FCELL_TYPE, RASTER3D_NO_CACHE, byref(region) | ||
| ) | ||
| if not handle: | ||
| sys.exit("Rast3d_open_cell_new failed") | ||
| map_ptr = cast(handle, POINTER(RASTER3D_Map)) | ||
| tile = (c_float * map_ptr.contents.tileSize)() | ||
| Rast3d_write_tile(map_ptr, map_ptr.contents.nTiles + index_offset, tile, FCELL_TYPE) | ||
| print("tile write accepted") | ||
| """ |
There was a problem hiding this comment.
That's a weird way to create a test, but it does run a subprocess for it
The bounds check uses
>instead of>=for the upper bound. AtileIndexequal tomap->nTilesis out of range (valid indices are0tomap->nTiles - 1), so this condition should use>= map->nTilesto correctly reject that value.