Skip to content

Fix szip data reading with RDWR access mode and only decoder is available - #897

Open
bmribler wants to merge 2 commits into
HDFGroup:masterfrom
bmribler:fix_gh-870_RDWR
Open

Fix szip data reading with RDWR access mode and only decoder is available#897
bmribler wants to merge 2 commits into
HDFGroup:masterfrom
bmribler:fix_gh-870_RDWR

Conversation

@bmribler

@bmribler bmribler commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Problems:

  • HDF4 routed AID access mode by file open mode rather than by the actual operation being performed: hdf_get_vp_aid() checked handle->hdf_mode == DFACC_RDONLY, so any read on an RDWR-opened file was routed through the write path, which required a szip encoder even when only decoding was needed. This made reading szip-compressed data from RDWR-opened files fail entirely on decoder-only builds.
  • Fixing that routing exposed a second, latent bug: vp->aid is cached and reused across calls, but several call sites only checked whether an AID existed (== FAIL), not whether its cached access mode (read vs write) matched what the current operation needed. A read-only AID left cached by a prior read could be silently reused for a subsequent write -- Hwrite() checks the DFACC_WRITE flag and fails if it isn't set. The reverse is safe: Hread() doesn't check the access flag at all, so a write-mode AID left open by an earlier write can always be reused for a later read.

Changes:

  • hdf_get_vp_aid() now takes an explicit uint32 access (DFACC_READ / DFACC_WRITE) parameter instead of deriving mode from file-open state, and checks/reopens a cached AID whose access doesn't cover what's needed; uses the library's usual ret_value/goto done convention throughout, including proper cleanup (Hendaccess) if Hsetlength() fails after a successful Hstartaccess()
  • Updated the 4 call sites that route through it: NCcoordck, hdf_xdr_NCvdata, SDsetaccesstype, SDwritechunk
  • SDsetchunkcache is read-only by nature and never needs to upgrade a cached AID, so it now opens directly via Hstartread() instead of routing through hdf_get_vp_aid(), matching the existing pattern already used by SDgetchunkinfo/SDreadchunk
  • Removed two dead #ifdef added_by_mistake blocks in SDgetchunkinfo/SDreadchunk: pre-existing code disabled by a fix in 2011 (commit #9702ef6, bug HDFFR-171). That commit solved the same class of wrong-access-mode problem locally for these two functions by hardcoding Hstartread() instead of calling hdf_get_vp_aid(). This commit solves the issue systematically across the rest of the library.

Testing

  • Before: decoder-only + RDWR-opened file: SDreaddata fails
  • After: decoder-only + RDWR-opened file: SDreaddata succeeds.
    Writing without an encoder still correctly fails. Full-szip and no-szip-at-all configurations behave the same before and after -- no regression. SDgetcompinfo (metadata-only, no decoder/encoder needed) succeeds in all configurations throughout, as expected.

Fixes #870

bmribler and others added 2 commits August 16, 2026 23:44
…ailable

HDF4 routed AID access mode by file open mode rather than by the
actual operation being performed: hdf_get_vp_aid() checked
handle->hdf_mode == DFACC_RDONLY, so any read on an RDWR-opened
file was routed through the write path, which required a szip
encoder even when only decoding was needed. This made reading
szip-compressed data from RDWR-opened files fail entirely on
decoder-only builds.

Fixing that routing exposed a second, latent bug: vp->aid is
cached and reused across calls, but several call sites only
checked whether an AID existed (== FAIL), not whether its cached
access mode (read vs write) matched what the current operation
needed. A read-only AID left cached by a prior read could be
silently reused for a subsequent write -- Hwrite() checks the
DFACC_WRITE flag and fails if it isn't set.  The reverse is
safe: Hread() doesn't check the access flag at all, so a
write-mode AID left open by an earlier write can always be reused
for a later read.

- hdf_get_vp_aid() now takes an explicit `uint32 access`
  (DFACC_READ / DFACC_WRITE) parameter instead of deriving mode
  from file-open state, and checks/reopens a cached AID whose
  access doesn't cover what's needed; uses the library's usual
  ret_value/goto done convention throughout, including proper
  cleanup (Hendaccess) if Hsetlength() fails after a successful
  Hstartaccess()
- Updated the 4 call sites that route through it: NCcoordck,
  hdf_xdr_NCvdata, SDsetaccesstype, SDwritechunk
- SDsetchunkcache is read-only by nature and never needs to
  upgrade a cached AID, so it now opens directly via Hstartread()
  instead of routing through hdf_get_vp_aid(), matching the
  existing pattern already used by SDgetchunkinfo/SDreadchunk
- Removed two dead #ifdef added_by_mistake blocks in
  SDgetchunkinfo/SDreadchunk: pre-existing code disabled by a fix in
  2011 (commit #9702ef6, bug HDFFR-171). That commit solved the same
  class of wrong-access-mode problem locally for these two functions
  by hardcoding Hstartread() instead of calling hdf_get_vp_aid(). This
  commit solves the issue systematically across the rest of the
  library.
Comment thread mfhdf/src/putget.c
Ensure vp->aid is open and has (at least) the requested access, opening
it fresh if necessary.

vp->aid is cached and reused across calls, so an AID opened DFACC_READ

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reword to make it clearer what the function does and when it does and does not need to be called

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component - C Library Core C library issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SDreaddata fails with DFACC_RDWR/no encoder combo

2 participants