Repository navigation
lib/raster3d: allocate no-cache block tile in the map's internal type - #7952
Merged
Merged
Conversation
Rast3d_get_block_nocache() allocated its scratch tile in the requested cell type but filled it with Rast3d_read_tile() in the map's internal type. Reading a DCELL map as FCELL without a tile cache therefore overflowed the heap buffer (glibc aborts with "double free or corruption" or "malloc(): corrupted top size"). Allocate the tile in map->typeIntern; the conversion to the requested type already happens in Rast3d_copy_values(). Add unit tests reading a DCELL map as FCELL and an FCELL map as DCELL through the no-cache path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nilason
approved these changes
Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Rast3d_get_block_nocache()(used byRast3d_get_block()whenever a map is opened withRASTER3D_NO_CACHE) allocates its scratch tile in the requested cell type:but fills it with
Rast3d_read_tile(map, tileIndex, tile, map->typeIntern), i.e. in the map's internal type, andRast3d_copy_values()then reads it asmap->typeInterntoo. Reading a DCELL 3D raster as FCELL through the fast no-cache path therefore writes a double-sized tile into a float-sized buffer: a heap overflow. glibc aborts withdouble free or corruption (!prev)ormalloc(): corrupted top size.This was found while streaming hyperspectral cubes band-block by band-block with
Rast3d_get_block(..., FCELL_TYPE)on a map produced byr.to.rast3from DCELL rasters.Fix
Allocate the scratch tile in
map->typeIntern. The conversion to the requested type already happens inRast3d_copy_values(), so nothing else changes.Tests
Two cases added to the existing put/get unit (
test.raster3d.lib unit=putget), whichlib/raster3d/testsuite/raster3d_lib_test.py::test_putgetalready runs:Rast3d_get_block()without cache;Each checks every cell value.
Result of
lib/raster3d/testsuite/raster3d_lib_test.py:libgrass_g3dmainFAIL: test_putget, process aborts withdouble free or corruption (!prev)Ran 3 tests ... OKclang-format22.1.5 (the pre-commit pin) reports no changes.AI disclosure
The bug was diagnosed and this patch and its tests were written with the help of an AI coding assistant (Claude Code); they were reviewed, run and verified as described above.
🤖 Generated with Claude Code