Skip to content

convolve_2d / convolution_2d skip input validation and silently accept even-sided kernels #3623

Description

@brendancol

Description

The two public convolution entry points in xrspatial/convolution.py do not validate their inputs, so bad arguments either raise an error the caller cannot map back to what they passed, or produce a wrong result with no error at all.

convolve_2d validates the raster but never the kernel:

  • A non-array kernel (list), None, or a 1D/3D array reaches the numba kernel and raises a TypingError naming a "reflected list" or "type none", internals the caller has no handle on.
  • An even-sided kernel (for example np.ones((2, 2))) is accepted silently and returns an off-center result with no error, even though custom_kernel already rejects even kernels as "improper dimensions". Same module, two different contracts.

convolution_2d never checks that agg is a DataArray. Passing a numpy array fails at agg.data with AttributeError: 'memoryview' object has no attribute 'astype', which points at an attribute the caller never touched.

Reproduction

import numpy as np
from xrspatial.convolution import convolve_2d, convolution_2d

data = np.arange(64, dtype=float).reshape(8, 8)

convolve_2d(data, [[0, 1, 0], [1, 1, 1], [0, 1, 0]])  # list -> numba TypingError
convolve_2d(data, None)                                # -> numba TypingError
convolve_2d(data, np.ones((2, 2)))                     # even sided -> silently off-center, no error
convolution_2d(data, np.ones((3, 3)))                  # numpy agg -> AttributeError on .astype

Fix

Add a _validate_kernel helper (2D, odd side lengths, duck-typed on ndim/shape so numpy and cupy kernels both pass) and call it from convolve_2d; add a _validate_raster call in convolution_2d. Even-sided kernels now raise, matching custom_kernel's long-standing odd-shape contract. Internal callers (focal, edge_detection, emerging_hotspots) all pass odd 2D arrays, so they are unaffected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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