From 54544c9a90ff1095ba2f4822534931a5ce2bb4ac Mon Sep 17 00:00:00 2001 From: armatti Date: Fri, 16 Oct 2026 16:26:00 +0300 Subject: [PATCH] Avoid shifting by 32 or more in interpretDFD The BITLENGTH field holds the bit length minus 1, so 1U << BITLENGTH is undefined for samples of 32 bits or more, such as those of the R64 integer formats and block-compressed formats. Clamp the bit length to 32. The spec's extension of sampleUpper for longer samples gives the same result as comparing at 32 bits. Found by fuzzing KTX-Software with libFuzzer. Fixes #31. --- interpretdfd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interpretdfd.c b/interpretdfd.c index b58a79f..bfbb176 100644 --- a/interpretdfd.c +++ b/interpretdfd.c @@ -138,7 +138,11 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD, isFixed = false; } else { uint32_t sampleUpper = KHR_DFDSVAL(BDFDB, i, SAMPLEUPPER); - uint32_t maxVal = 1U << KHR_DFDSVAL(BDFDB, i, BITLENGTH); + // sampleUpper of a longer sample is extended per the spec, which + // gives the same comparison result as 32 bits. + uint32_t bitLength = KHR_DFDSVAL(BDFDB, i, BITLENGTH) + 1; + if (bitLength > 32) bitLength = 32; + uint32_t maxVal = 1U << (bitLength - 1); if (!isSigned) maxVal <<= 1; maxVal--; isFixed = 1U < sampleUpper && sampleUpper < maxVal;