Describe the bug
landforms() in xrspatial/terrain_metrics.py takes an outer_radius parameter (default 15) and passes it straight to _circular_kernel(radius) with no upper bound. The kernel allocates a (2*radius+1)^2 float64 array plus a boolean mask of the same size.
outer_radius=20000 asks for about 12.8 GB. outer_radius=100000 asks for about 320 GB. The current validation only checks inner_radius >= 1 and outer_radius > inner_radius.
Expected behavior
Raise MemoryError before allocation when the kernel won't fit in memory. xrspatial/convolution.py:_check_kernel_memory (lines 165-183) already does this for circle_kernel, and kde, sieve, and balanced_allocation use _available_memory_bytes() the same way.
Reproduction
import numpy as np
import xarray as xr
from xrspatial import landforms
agg = xr.DataArray(np.random.rand(100, 100).astype(np.float64))
landforms(agg, outer_radius=200000) # tries to allocate ~1.3 TB
Additional context
Found during a security audit of terrain_metrics. Recorded in .claude/sweep-security-state.csv as severity HIGH, Cat 1 (unbounded allocation / DoS).
Describe the bug
landforms()inxrspatial/terrain_metrics.pytakes anouter_radiusparameter (default 15) and passes it straight to_circular_kernel(radius)with no upper bound. The kernel allocates a(2*radius+1)^2float64 array plus a boolean mask of the same size.outer_radius=20000asks for about 12.8 GB.outer_radius=100000asks for about 320 GB. The current validation only checksinner_radius >= 1andouter_radius > inner_radius.Expected behavior
Raise
MemoryErrorbefore allocation when the kernel won't fit in memory.xrspatial/convolution.py:_check_kernel_memory(lines 165-183) already does this forcircle_kernel, andkde,sieve, andbalanced_allocationuse_available_memory_bytes()the same way.Reproduction
Additional context
Found during a security audit of
terrain_metrics. Recorded in.claude/sweep-security-state.csvas severity HIGH, Cat 1 (unbounded allocation / DoS).