Describe the bug
to_geotiff gates writes carrying attrs['gdal_metadata_xml'] or attrs['extra_tags'] behind allow_experimental_codecs=True. Both tags sit in the experimental tier of SUPPORTED_FEATURES (writer.gdal_metadata_xml, writer.extra_tags). But attrs['gdal_metadata'] is not gated, even though _extract_rich_tags converts it to XML via _build_gdal_metadata_xml and writes it to the on-disk TIFF when it's a dict and gdal_metadata_xml is None.
So a fresh DataArray (no _xrspatial_geotiff_contract marker) can write arbitrary GDAL metadata to the output file without opting in. That's a hole in the experimental rich-tag write gate.
The gate lives in _validate_write_rich_tag_optin (xrspatial/geotiff/_attrs.py, ~lines 531-539). The write trigger is in _extract_rich_tags (~lines 1469-1474).
Expected behavior
A fresh DataArray with attrs['gdal_metadata'] set to a dict should raise ValueError on to_geotiff unless allow_experimental_codecs=True is passed, matching how gdal_metadata_xml and extra_tags behave. A round-tripped array (carrying the contract marker) should keep writing without the flag.
Fix direction
Add a gdal_metadata check to _validate_write_rich_tag_optin, triggering only when attrs['gdal_metadata'] is a dict (a non-dict value is ignored by the writer, so it needs no gate). Name attrs['gdal_metadata'] in the rejection message when it's the trigger. Keep the round-trip exemption intact and don't touch _extract_rich_tags.
Additional context
Part of the GeoTIFF experimental-tier contract work (epic #2340).
Describe the bug
to_geotiffgates writes carryingattrs['gdal_metadata_xml']orattrs['extra_tags']behindallow_experimental_codecs=True. Both tags sit in theexperimentaltier ofSUPPORTED_FEATURES(writer.gdal_metadata_xml,writer.extra_tags). Butattrs['gdal_metadata']is not gated, even though_extract_rich_tagsconverts it to XML via_build_gdal_metadata_xmland writes it to the on-disk TIFF when it's a dict andgdal_metadata_xmlis None.So a fresh DataArray (no
_xrspatial_geotiff_contractmarker) can write arbitrary GDAL metadata to the output file without opting in. That's a hole in the experimental rich-tag write gate.The gate lives in
_validate_write_rich_tag_optin(xrspatial/geotiff/_attrs.py, ~lines 531-539). The write trigger is in_extract_rich_tags(~lines 1469-1474).Expected behavior
A fresh DataArray with
attrs['gdal_metadata']set to a dict should raiseValueErroronto_geotiffunlessallow_experimental_codecs=Trueis passed, matching howgdal_metadata_xmlandextra_tagsbehave. A round-tripped array (carrying the contract marker) should keep writing without the flag.Fix direction
Add a
gdal_metadatacheck to_validate_write_rich_tag_optin, triggering only whenattrs['gdal_metadata']is a dict (a non-dict value is ignored by the writer, so it needs no gate). Nameattrs['gdal_metadata']in the rejection message when it's the trigger. Keep the round-trip exemption intact and don't touch_extract_rich_tags.Additional context
Part of the GeoTIFF experimental-tier contract work (epic #2340).