Skip to content

fix(exr): use rectangle row stride for partial edge tile reads - #5295

Merged
lgritz merged 1 commit into
AcademySoftwareFoundation:mainfrom
lgritz:lg-exredge
Jul 16, 2026
Merged

fix(exr): use rectangle row stride for partial edge tile reads#5295
lgritz merged 1 commit into
AcademySoftwareFoundation:mainfrom
lgritz:lg-exredge

Conversation

@lgritz

@lgritz lgritz commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

read_native_tiles() on a tiled EXR whose dimensions aren't a multiple of the tile size wrote past the caller's buffer when reading an edge tile range: both readers used a row stride padded up to a whole number of tiles (nxtiles*tile_width) instead of the caller's actual rectangle width, overrunning the buffer whenever the last tile column is partial.

Fixed in both exrinput_c.cpp (Core reader) and exrinput.cpp (classic reader) to use the requested rectangle width as the destination row stride instead. exrinput.cpp additionally needs the pre-clamp width specifically, since read_native_tile() forwards a tile-aligned xend past the image edge for ordinary full-tile reads.

Adds testsuite/openexr-partialtile, a compiled regression test that calls read_native_tiles() directly for both readers -- the only path that exercises this code -- and checks pixels and buffer bounds.

Assisted-by: Claude Code / Claude Opus 4.8

read_native_tiles() on a tiled EXR whose dimensions aren't a multiple of
the tile size wrote past the caller's buffer when reading an edge tile
range: both readers used a row stride padded up to a whole number of
tiles (nxtiles*tile_width) instead of the caller's actual rectangle
width, overrunning the buffer whenever the last tile column is partial.

Fixed in both exrinput_c.cpp (Core reader) and exrinput.cpp (classic
reader) to use the requested rectangle width as the destination row
stride instead. exrinput.cpp additionally needs the pre-clamp width
specifically, since read_native_tile() forwards a tile-aligned xend past
the image edge for ordinary full-tile reads.

Adds testsuite/openexr-partialtile, a compiled regression test that
calls read_native_tiles() directly for both readers -- the only path
that exercises this code -- and checks pixels and buffer bounds.

Assisted-by: Claude Code / Claude Opus 4.8

Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz

lgritz commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Any comments or concerns about this one?

@lgritz

lgritz commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Nearly two weeks old, no objections -> merging.

@lgritz
lgritz merged commit 7303134 into AcademySoftwareFoundation:main Jul 16, 2026
60 checks passed
@lgritz
lgritz deleted the lg-exredge branch July 16, 2026 01:11
@lgritz

lgritz commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

CVE-2026-63422

lgritz added a commit to lgritz/OpenImageIO that referenced this pull request Jul 22, 2026
…mySoftwareFoundation#5295)

read_native_tiles() on a tiled EXR whose dimensions aren't a multiple of
the tile size wrote past the caller's buffer when reading an edge tile
range: both readers used a row stride padded up to a whole number of
tiles (nxtiles*tile_width) instead of the caller's actual rectangle
width, overrunning the buffer whenever the last tile column is partial.

Fixed in both exrinput_c.cpp (Core reader) and exrinput.cpp (classic
reader) to use the requested rectangle width as the destination row
stride instead. exrinput.cpp additionally needs the pre-clamp width
specifically, since read_native_tile() forwards a tile-aligned xend past
the image edge for ordinary full-tile reads.

Adds testsuite/openexr-partialtile, a compiled regression test that
calls read_native_tiles() directly for both readers -- the only path
that exercises this code -- and checks pixels and buffer bounds.

Assisted-by: Claude Code / Claude Opus 4.8

Signed-off-by: Larry Gritz <lg@larrygritz.com>
lgritz added a commit to lgritz/OpenImageIO that referenced this pull request Jul 22, 2026
…mySoftwareFoundation#5295)

read_native_tiles() on a tiled EXR whose dimensions aren't a multiple of
the tile size wrote past the caller's buffer when reading an edge tile
range: both readers used a row stride padded up to a whole number of
tiles (nxtiles*tile_width) instead of the caller's actual rectangle
width, overrunning the buffer whenever the last tile column is partial.

Fixed in both exrinput_c.cpp (Core reader) and exrinput.cpp (classic
reader) to use the requested rectangle width as the destination row
stride instead. exrinput.cpp additionally needs the pre-clamp width
specifically, since read_native_tile() forwards a tile-aligned xend past
the image edge for ordinary full-tile reads.

Adds testsuite/openexr-partialtile, a compiled regression test that
calls read_native_tiles() directly for both readers -- the only path
that exercises this code -- and checks pixels and buffer bounds.

Assisted-by: Claude Code / Claude Opus 4.8

Signed-off-by: Larry Gritz <lg@larrygritz.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant