Skip to content

geotiff: to_geotiff(crs=True) writes EPSG=1 silently; bool slips through int check #1971

@brendancol

Description

@brendancol

Describe the bug

xrspatial.geotiff.to_geotiff(da, path, crs=True) writes a file with the projected/geographic CRS key set to 1 and produces a DataArray on read-back with attrs['crs'] == 1. Two gaps in the validation chain cause this:

  • xrspatial/geotiff/_writers/eager.py:501 resolves the crs argument with isinstance(crs, int). bool is a subclass of int in Python, so crs=True is accepted and epsg=1. crs=False would similarly map to epsg=0.
  • xrspatial/geotiff/_geotags.py:1077 writes the EPSG code without checking that it resolves with pyproj.
  • On read, xrspatial/geotiff/_geotags.py:557 accepts any numeric projected/geographic CRS key as attrs['crs'], even when _epsg_to_wkt() later emits a GeoTIFFFallbackWarning because pyproj cannot resolve it.

Reproduction

import numpy as np, xarray as xr, tempfile
from xrspatial.geotiff import to_geotiff, open_geotiff

da = xr.DataArray(np.zeros((4,4), dtype=np.float32),
                  coords={'y': np.arange(4), 'x': np.arange(4)},
                  dims=('y','x'))
with tempfile.NamedTemporaryFile(suffix='.tif') as f:
    to_geotiff(da, f.name, crs=True)
    print(open_geotiff(f.name).attrs.get('crs'))  # prints 1

Expected behavior

to_geotiff should reject bool for crs and any integer that does not resolve with pyproj, raising a clear ValueError at the entry point. Bad CRS metadata cannot reach the file and cannot silently poison reprojection or merge code paths.

Additional context

Caught in a code review of the geotiff module. Sibling validators (e.g. _validate_chunks_arg, _validate_tile_size) already reject bools explicitly because True/False sneak through int checks; the CRS path needs the same treatment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginput-validationInput validation and error messages

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions