Skip to content

geotiff: planar stripped TIFF returns uninitialized bands when strip table is truncated #1782

@brendancol

Description

@brendancol

Describe the bug

_read_strips in xrspatial/geotiff/_reader.py validates StripOffsets / StripByteCounts against n_strips_expected = (height + rps - 1) // rps at line 1410. For PlanarConfiguration=2 (planar/separate bands) the strip tables must hold strips_per_band * samples_per_pixel entries, not just strips_per_band. The pre-flight check is too lenient for planar files.

The planar loop at lines 1436-1441 then handles the missing tail with:

for band_idx in range(samples):
    band_offset = band_idx * strips_per_band
    for strip_idx in range(first_strip, last_strip + 1):
        global_idx = band_offset + strip_idx
        if global_idx >= len(offsets):
            continue

continue skips strips that should have existed for bands 1..N-1, leaving the corresponding region of the pre-allocated np.empty output untouched. The caller sees garbage uninitialised memory for those bands.

The tiled path already does the right thing through validate_tile_layout() (which knows about planar layout); the strip path should mirror that.

Expected behavior

When PlanarConfiguration == 2 and samples_per_pixel > 1, the pre-flight check should require len(offsets) >= strips_per_band * samples_per_pixel (and the same for byte_counts), and raise a typed ValueError if not. The silent if global_idx >= len(offsets): continue skip inside the loop can then be removed.

Categories

  • Cat 1 (memory safety): uninitialised np.empty exposed to callers
  • Cat 5 (backend inconsistency): tile path validates via validate_tile_layout(); strip path does not

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions