Skip to content

read_vrt: out-of-bounds window silently clamped instead of raising (drift from local/HTTP) #1697

@brendancol

Description

@brendancol

Summary

read_vrt(path, window=...) silently clamps invalid window coordinates instead of raising ValueError. The local TIFF path (#1634) and HTTP COG path (#1669) both reject the same bad windows. VRT slipped through.

xrspatial/geotiff/_vrt.py:407-414:

if window is not None:
    r0, c0, r1, c1 = window
    r0 = max(0, r0)
    c0 = max(0, c0)
    r1 = min(vrt.height, r1)
    c1 = min(vrt.width, c1)
else:
    r0, c0, r1, c1 = 0, 0, vrt.height, vrt.width

#1634 added a validator on the local path (_reader.py:2013-2020) that raises ValueError for any out-of-bounds, zero-size, or inverted window. The HTTP path got the same validator (_reader.py:1620-1628). VRT was skipped, probably by accident when #1634 landed.

Reproducer

from xrspatial.geotiff._vrt import read_vrt
out, _ = read_vrt(path, window=(-1, 0, 2, 2))
print(out.shape)  # (2, 2) -- r0 clamped to 0, no exception

On a 4x4 VRT:

window actual expected
(-1, 0, 2, 2) (2, 2) array ValueError
(0, 0, 5, 5) (4, 4) array ValueError
(2, 2, 2, 2) (0, 0) array ValueError

Why it matters: open_geotiff builds the y/x coord arrays from the caller-supplied window indices. A clamped read returns a smaller array than the coords, so the user gets a CoordinateValidationError from xarray's internals instead of a clear xrspatial error. This is exactly the failure mode #1634 was filed for.

Fix

Replace the clamp with the validator the other two paths already use:

if window is not None:
    r0, c0, r1, c1 = window
    if (r0 < 0 or c0 < 0
            or r1 > vrt.height or c1 > vrt.width
            or r0 >= r1 or c0 >= c1):
        raise ValueError(
            f"window={window} is outside the VRT extent "
            f"({vrt.height}x{vrt.width}) or has non-positive size.")
else:
    r0, c0, r1, c1 = 0, 0, vrt.height, vrt.width

Message says "VRT extent" instead of "source extent" since the dimensions come from the parsed VRT, not a single source file.

Tests

A new file test_vrt_window_validation_NNNN.py will cover:

  • negative r0 / c0
  • r1 past vrt.height, c1 past vrt.width
  • zero-size windows (r0 == r1)
  • inverted windows (r0 > r1)
  • a valid in-bounds window still works
  • the same bad window passed to read_to_array on a non-VRT TIFF raises the same error class with a message of the same shape

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions