mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
imgcodecs: fix UBSan load-invalid-value in SunRasterDecoder::readHeader (#29150)
Casting the raw integer fields ras_type and maptype directly to their respective enum types (SunRasType / SunRasMapType) without a prior range check is undefined behavior under C++11 §7.2/8 when the stored value falls outside the enum's valid range. UBSan reports: grfmt_sunras.cpp:72: runtime error: load of value 34077, which is not a valid value for type 'SunRasMapType' Fix: read both fields into plain ints first, validate them against the declared enumerator bounds, and return false (reject the image) on any out-of-range value before performing the enum cast. This is the cheapest correct approach — two integer comparisons added to a path that was already doing I/O — and ensures no downstream code ever sees an ill-formed enum value. Add test_sunraster.cpp with regression tests covering: - The exact crash_001 payload (invalid maptype 34077 / 0x851d) - Invalid ras_type values - maptype = 2 and UINT_MAX (outside [0,1]) - Truncated header - A valid 8-bpp grayscale image that must still decode correctly Signed-off-by: FuzzAnything fuzzanything@gmail.com
This commit is contained in:
@@ -61,10 +61,22 @@ bool SunRasterDecoder::readHeader()
|
||||
int palSize = (m_bpp > 0 && m_bpp <= 8) ? (3*(1 << m_bpp)) : 0;
|
||||
|
||||
m_strm.skip( 4 );
|
||||
m_encoding = (SunRasType)m_strm.getDWord();
|
||||
m_maptype = (SunRasMapType)m_strm.getDWord();
|
||||
// Read as plain integers first; validate before casting to enum types.
|
||||
// Casting an out-of-range integer directly to an enum with no fixed
|
||||
// underlying type is undefined behavior (C++11 §7.2/8). Reject invalid
|
||||
// values early so no downstream code ever touches an ill-formed enum.
|
||||
const int raw_encoding = (int)m_strm.getDWord();
|
||||
const int raw_maptype = (int)m_strm.getDWord();
|
||||
m_maplength = m_strm.getDWord();
|
||||
|
||||
if (raw_encoding < RAS_OLD || raw_encoding > RAS_FORMAT_RGB)
|
||||
return false;
|
||||
if (raw_maptype < RMT_NONE || raw_maptype > RMT_EQUAL_RGB)
|
||||
return false;
|
||||
|
||||
m_encoding = (SunRasType)raw_encoding;
|
||||
m_maptype = (SunRasMapType)raw_maptype;
|
||||
|
||||
if( m_width > 0 && m_height > 0 &&
|
||||
(m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) &&
|
||||
(m_encoding == RAS_OLD || m_encoding == RAS_STANDARD ||
|
||||
|
||||
Reference in New Issue
Block a user