Skip to content

resample: integer/bool nodata sentinels silently wrap and mask valid data #2660

@brendancol

Description

@brendancol

Describe the bug
resample() accepts a nodata sentinel and masks input pixels equal to it before resampling. For integer and boolean inputs, _resolve_nodata in xrspatial/resample.py casts the sentinel into the input dtype with np.asarray(nodata).astype(agg.dtype).item() without checking that the value is representable. Out-of-range integers wrap silently, so a sentinel can collapse onto a real value and mask valid data.

For a uint8 raster, nodata=999 becomes 231 after the cast, so any real pixel equal to 231 is treated as missing. For boolean inputs, any nonzero sentinel collapses to True, masking every True pixel.

Expected behavior
A nodata sentinel that does not round-trip exactly into agg.dtype should raise a clear ValueError instead of silently wrapping and masking the wrong pixels. The check should also reject sentinels that are meaningless for boolean inputs.

Reproduction

import numpy as np, xarray as xr
from xrspatial import resample

arr = xr.DataArray(np.full((4, 4), 231, dtype="uint8"), dims=("y", "x"))
arr["x"] = np.arange(4); arr["y"] = np.arange(4)
out = resample(arr, scale_factor=0.5, nodata=999)
# every cell becomes NaN because 999 wrapped to 231

Additional context
Fractional float sentinels for integer inputs are already rejected. The remaining gap is range/representability for integer and boolean dtypes. Found during a security/robustness sweep of resample.py.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginput-validationInput validation and error messages

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions