Describe the bug
curvature() divides by cellsize * cellsize in every backend kernel with no zero guard. cellsize comes from get_dataarray_resolution(agg), which reads agg.attrs["res"]. If a caller passes a raster whose res attribute is (0, 0) (or one component is 0), the output is inf for every interior pixel instead of a clean error.
Cat 3 (NaN/Inf as logic error) finding from the recent security sweep, MEDIUM severity.
Steps to reproduce
import numpy as np
import xarray as xr
from xrspatial import curvature
data = np.zeros((5, 5), dtype=np.float32)
agg = xr.DataArray(data, attrs={'res': (0, 0)})
result = curvature(agg)
print(result.data) # all inf instead of an error
Expected behavior
curvature() should raise ValueError when either cellsize component is zero or non-finite. The check needs to run before backend dispatch so all four backends (numpy, cupy, dask+numpy, dask+cupy) inherit it.
Fix
Validate the resolution returned by get_dataarray_resolution(agg) in the public curvature() API and raise ValueError if either component is zero or non-finite. Do not change the inner numba/cupy kernels. Do not substitute a fallback cellsize.
Describe the bug
curvature()divides bycellsize * cellsizein every backend kernel with no zero guard.cellsizecomes fromget_dataarray_resolution(agg), which readsagg.attrs["res"]. If a caller passes a raster whoseresattribute is(0, 0)(or one component is 0), the output isinffor every interior pixel instead of a clean error.Cat 3 (NaN/Inf as logic error) finding from the recent security sweep, MEDIUM severity.
Steps to reproduce
Expected behavior
curvature()should raiseValueErrorwhen either cellsize component is zero or non-finite. The check needs to run before backend dispatch so all four backends (numpy, cupy, dask+numpy, dask+cupy) inherit it.Fix
Validate the resolution returned by
get_dataarray_resolution(agg)in the publiccurvature()API and raiseValueErrorif either component is zero or non-finite. Do not change the inner numba/cupy kernels. Do not substitute a fallback cellsize.