Skip to content

geotiff: parse_all_ifds raises on IFD chain cycle (#1913)#1920

Merged
brendancol merged 1 commit into
mainfrom
fix-ifd-cycle-error-2026-05-15
May 15, 2026
Merged

geotiff: parse_all_ifds raises on IFD chain cycle (#1913)#1920
brendancol merged 1 commit into
mainfrom
fix-ifd-cycle-error-2026-05-15

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Fixes #1913. parse_all_ifds in xrspatial/geotiff/_header.py silently truncated the IFD list on a cyclic chain. The loop condition was while offset != 0 and offset not in seen, so a repeat offset exited the loop and returned whatever had been parsed before the cycle. The other two malformed-chain branches in the same function (offset past EOF, chain over MAX_IFDS) raise ValueError, so the cycle case was the odd one out.

The fix restructures the loop to raise ValueError on a repeat offset with the same file is malformed wording. Callers now get a clear error rather than a half-parsed file that looks plausible.

Changes

  • xrspatial/geotiff/_header.py: cycle branch now raises ValueError. Comment explains why (consistency with the sibling errors).
  • xrspatial/geotiff/tests/test_header.py: existing TestIFDChainLoop asserted the old silent-truncation behaviour; updated to assert the new raise (two-IFD cycle and self-loop).
  • xrspatial/geotiff/tests/test_ifd_cycle_1913.py: new test file covering cycle rejection on little-endian and big-endian, error message content, and regression guards for the two sibling malformed-chain branches and the normal multi-IFD chain.

Test plan

  • New cycle tests pass: pytest xrspatial/geotiff/tests/test_ifd_cycle_1913.py -q (8 passed)
  • Updated TestIFDChainLoop tests pass: pytest xrspatial/geotiff/tests/test_header.py -q
  • Existing IFD chain cap tests still pass: pytest xrspatial/geotiff/tests/test_ifd_chain_cap.py -q
  • Full geotiff suite green except for two pre-existing failures unrelated to this change (test_predictor2_big_endian_gpu_1517.py::test_gpu_predictor2_big_endian_int32_tiled_reproducer monkeypatch target missing, test_size_param_validation_gpu_vrt_1776.py::test_tile_size_positive_works tile_size mismatch). Both reproduce on main at b4f0eee.

Cyclic IFD chains used to be silently truncated. The loop condition
`while offset != 0 and offset not in seen` exited cleanly when a
repeat offset showed up and returned whatever had been parsed so far.
The other two malformed-chain branches in the same function
(past-EOF and MAX_IFDS) both raise ValueError, so the cycle case was
the odd one out.

The loop now raises ValueError on a repeat offset with the same
"file is malformed" wording as the sibling errors. Callers get a
clear error instead of a half-parsed file that looks plausible.

test_header.py's existing TestIFDChainLoop asserted the old
silent-truncation behaviour; updated to assert the new raise.
Copilot AI review requested due to automatic review settings May 15, 2026 13:29
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the GeoTIFF IFD-chain parser by treating cyclic IFD chains as malformed input and raising a ValueError, aligning cycle handling with existing malformed-chain error branches (past-EOF and MAX_IFDS cap) and preventing callers from receiving a plausible-looking but truncated parse result.

Changes:

  • Update parse_all_ifds to explicitly detect repeated IFD offsets and raise ValueError with “file is malformed” wording.
  • Update existing cycle-related tests to assert the new raising behavior (including self-loop).
  • Add a new targeted regression test module covering cycle detection (LE/BE), message content, and guarding the sibling malformed-chain branches plus normal chains.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
xrspatial/geotiff/_header.py Makes IFD-chain cycles raise ValueError for consistent malformed-file handling.
xrspatial/geotiff/tests/test_header.py Updates existing cycle-loop tests to expect the new exception-based contract.
xrspatial/geotiff/tests/test_ifd_cycle_1913.py Adds regression coverage for cycle detection across endianness and for existing malformed-chain branches.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@brendancol brendancol merged commit 2ef162c into main May 15, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

geotiff: parse_all_ifds silently truncates on IFD chain cycle

2 participants