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
Summary
read_vrt(path, window=...)silently clamps invalid window coordinates instead of raisingValueError. 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:#1634 added a validator on the local path (
_reader.py:2013-2020) that raisesValueErrorfor 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
On a 4x4 VRT:
(-1, 0, 2, 2)(2, 2)arrayValueError(0, 0, 5, 5)(4, 4)arrayValueError(2, 2, 2, 2)(0, 0)arrayValueErrorWhy it matters:
open_geotiffbuilds 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 aCoordinateValidationErrorfrom 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:
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.pywill cover:r0/c0r1pastvrt.height,c1pastvrt.widthr0 == r1)r0 > r1)read_to_arrayon a non-VRT TIFF raises the same error class with a message of the same shape