Repository navigation
BUG: Validate the GIPL header byte count in a single read - #6628
Merged
hjmjohnson merged 1 commit intoJul 14, 2026
Merged
Conversation
ReadImageInformation consumed the 256-byte header as 15 unchecked gzread/istream::read calls, and CanReadFile did 2 more; a truncated or non-GIPL file silently left pixdim/origin locals uninitialized and populated spacing and origin from stack garbage instead of failing. Read the header in one call and check the byte count once, then parse dims/image_type/pixdim/origin from that buffer. The other fields (line1, matrix, flags, min/max, pixval, user_def, magic_number) were dead: unread by any member, and magic_number was never compared; only CanReadFile validates it. CanReadFile's own probe now checks its read count instead of trusting zero-init. Addresses item B86 of InsightSoftwareConsortium#6575.
Contributor
|
| Filename | Overview |
|---|---|
| Modules/IO/GIPL/src/itkGiplImageIO.cxx | Reads the fixed GIPL header in one checked operation and keeps the consumed stream position aligned with later pixel reads. |
| Modules/IO/GIPL/test/itkGiplImageIOGTest.cxx | Adds tests that call ReadImageInformation() directly on truncated plain and compressed GIPL files. |
Reviews (2): Last reviewed commit: "BUG: Validate GIPL header byte count in ..." | Re-trigger Greptile
hjmjohnson
marked this pull request as draft
July 14, 2026 14:58
hjmjohnson
approved these changes
Jul 14, 2026
hjmjohnson
marked this pull request as ready for review
July 14, 2026 20:04
hjmjohnson
merged commit Jul 14, 2026
e357b46
into
InsightSoftwareConsortium:main
19 of 22 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GiplImageIOconsumed the 256-byte header as 17 separategzread/istream::readcalls without ever checking a byte count, so a truncated or non-GIPL file populated dimensions, spacing and origin from uninitialized stack memory. Addresses B86 of #6575.Root cause and fix
Once one read on a broken stream fails, every later read silently no-ops.
float pixdim[4]anddouble origin[4]are never zero-initialized, so their indeterminate values went straight intom_Spacing/m_Origin— undefined behavior, not merely wrong metadata.The fix is structural rather than 17 guards:
ReadImageInformation()now reads the whole 256-byte header in one call, checks the byte count once, andmemcpys the four field groups it actually uses out of that buffer at their documented offsets. The ten other fields the old code read were never assigned to any member and existed only to advance the cursor, which the one-shot read now does; the trailingmagic_numberre-read was likewise never compared against anything (CanReadFile()does the magic-number check, in its own function).CanReadFile()'s own two reads now check their byte count and return false on a short read.Local validation
Two cases added to
itkGiplImageIOGTest.cxx, callingReadImageInformation()directly on a bareGiplImageIO— going throughImageFileReader::Update()masks the bug, because the already-fixed pixel-data check throws first once it inherits the broken stream.ReadImageInformationOfHeaderTruncatedUncompressedFileThrows/...CompressedFileThrows— fail-before: throws nothing. Pass-after: throws.ctest -R Gipl: no existing test's result changed.AI assistance