From 47d346fbfe57d3f07223fea8f31e1ff8891593ad Mon Sep 17 00:00:00 2001 From: Walid Chtioui Date: Mon, 13 Jul 2026 22:37:10 +0200 Subject: [PATCH 1/2] Fix left shift on signed int channel setting sign bit and causing UB * When the signed integer (type: int) is 192, the following undefined behavior occurs: 11000000 << 24 => is undefined behavior because setting sign bit of an integer via a left shift operation is UB. Simply cast channel to uint32_t before shifting. * To replicate: build with -fsanitize="undefined" and navigate to KTX-Software/tests/cts/clitests then: ktx transcode --testrun input/ktx2/valid_R16G16_SFLOAT_CUBE_ARRAY.ktx2 / output/transcode/transcode_error_not_transcodable/output_R16G16_SFLOAT_CUBE_ARRAY.ktx2 You will get the following: KTX-Software/external/dfdutils/createdfd.c:123:18: runtime error: left shift of 192 by 24 places cannot be represented in type 'int' Signed-off-by: Walid Chtioui --- createdfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/createdfd.c b/createdfd.c index bb79ebd..daa9b7e 100644 --- a/createdfd.c +++ b/createdfd.c @@ -120,7 +120,7 @@ static void writeSample(uint32_t *DFD, int sampleNo, int channel, sample[KHR_DF_SAMPLEWORD_BITOFFSET] = (offset << KHR_DF_SAMPLESHIFT_BITOFFSET) | ((bits - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) | - (channel << KHR_DF_SAMPLESHIFT_CHANNELID); + ((uint32_t)channel << KHR_DF_SAMPLESHIFT_CHANNELID); sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0; From 01b51a80c3e9aec38ca66f07f7af050e43453a1f Mon Sep 17 00:00:00 2001 From: Walid Chtioui Date: Tue, 14 Jul 2026 19:30:48 +0200 Subject: [PATCH 2/2] Add comment on why `channel` is cast into uint32_t Signed-off-by: Walid Chtioui --- createdfd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/createdfd.c b/createdfd.c index daa9b7e..2438e47 100644 --- a/createdfd.c +++ b/createdfd.c @@ -117,6 +117,12 @@ static void writeSample(uint32_t *DFD, int sampleNo, int channel, if (channel == 3) channel = KHR_DF_CHANNEL_RGBSDA_ALPHA; channel = setChannelFlags(channel, suffix); + // `channel` is cast into an uint32_t to avoid the following issue: + // When `channel` is 192, the following UB occurs: 11000000 << 24 + // Setting sign bit of an integer via a left shift operation is UB. + // + // TODO: This is the least intrusive solution for the moment. Ideally, + // writeSample should take uint32_t params. sample[KHR_DF_SAMPLEWORD_BITOFFSET] = (offset << KHR_DF_SAMPLESHIFT_BITOFFSET) | ((bits - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |