Summary
_read_cog_http in xrspatial/geotiff/_reader.py doesn't validate the band argument. band=-1 silently returns the last channel, band >= samples_per_pixel leaks a raw numpy IndexError, and band=N (N != 0) on a single-band file is dropped on the floor. The local, dask, GPU, and VRT paths all reject the same inputs after PR #1673.
The in-file comment at _reader.py:2031-2034 already flags the gap:
# NOTE: the HTTP branch (``_read_cog_http`` above) currently
# accepts ``band`` but never slices on it; issue #1669 will
# add the slice. When that lands, mirror this same check
# there so HTTP rejects the same inputs.
PR #1669 / #1680 added the slice on L1638. The mirror-the-check follow-up was never done.
Reproduction
Multi-band HTTP COG read with band=-1 returns the last channel:
arr = open_geotiff(http_url, band=-1) # returns last band, no error
The same call on a local path raises:
IndexError: band=-1 out of range for 3-band file.
Single-band HTTP COG read with band=1 (or any nonzero index) is silently dropped, because the slice guard at L1638 is gated on arr.ndim == 3 and ifd.samples_per_pixel > 1. The local path raises:
IndexError: band=1 requested on a single-band file.
Fix plan
Insert a band validator in _read_cog_http after the orientation and window validators (around _reader.py:1606-1628), before the tile fetch on L1630. Mirror the check at L2035-2043 of read_to_array. Call source.close() before raising since the HTTP source holds a network handle. Update the NOTE comment at L2031-2034 so it no longer points at unfinished work. Add regression tests covering band=-1, band >= samples_per_pixel, single-band nonzero band, single-band band=0, band=None, and cross-path parity with the local-path eager read.
Summary
_read_cog_httpinxrspatial/geotiff/_reader.pydoesn't validate thebandargument.band=-1silently returns the last channel,band >= samples_per_pixelleaks a raw numpyIndexError, andband=N(N != 0) on a single-band file is dropped on the floor. The local, dask, GPU, and VRT paths all reject the same inputs after PR #1673.The in-file comment at
_reader.py:2031-2034already flags the gap:PR #1669 / #1680 added the slice on L1638. The mirror-the-check follow-up was never done.
Reproduction
Multi-band HTTP COG read with
band=-1returns the last channel:The same call on a local path raises:
Single-band HTTP COG read with
band=1(or any nonzero index) is silently dropped, because the slice guard at L1638 is gated onarr.ndim == 3 and ifd.samples_per_pixel > 1. The local path raises:Fix plan
Insert a
bandvalidator in_read_cog_httpafter the orientation and window validators (around_reader.py:1606-1628), before the tile fetch on L1630. Mirror the check at L2035-2043 ofread_to_array. Callsource.close()before raising since the HTTP source holds a network handle. Update the NOTE comment at L2031-2034 so it no longer points at unfinished work. Add regression tests coveringband=-1,band >= samples_per_pixel, single-band nonzero band, single-bandband=0,band=None, and cross-path parity with the local-path eager read.