Skip to content

geotiff: malformed SCALE/OFFSET silently ignored under mask_and_scale #2987

@brendancol

Description

@brendancol

Describe the bug

_extract_scale_offset in xrspatial/geotiff/_attrs.py reads the SCALE and OFFSET items from a GeoTIFF's GDAL_METADATA when a caller passes mask_and_scale=True. Its inner _num helper does:

try:
    return float(gdal_metadata[k])
except (TypeError, ValueError):
    return default

So when a SCALE or OFFSET key is present but its value won't parse as a float (say SCALE="abc"), the function quietly returns the default 1.0 / 0.0.

The caller passed mask_and_scale=True to ask the reader to honor the scale/offset metadata. A malformed value gets treated as if no scale/offset existed at all, so the raw unscaled pixels flow downstream and the file looks clean. That's the same silent-coercion trap the project already closed for integer nodata sentinels with InvalidIntegerNodataError.

Expected behavior

An absent key should stay silent: defaulting to 1.0 / 0.0 is correct, because the source genuinely carries no scale/offset. But a key that is present and unparseable under mask_and_scale=True should fail closed with a typed error from the existing GeoTIFFAmbiguousMetadataError family. The message should name the offending key and value.

Additional context

Both call sites (_finalize_eager_read in _attrs.py and the dask backend in _backends/dask.py) gate this on mask_and_scale=True. The fix needs to tell "key absent" apart from "key present but malformed" inside _extract_scale_offset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggeotiffGeoTIFF moduleinput-validationInput validation and error messages

    Type

    No type
    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