From 014f1ef09f2785083a192abeaf334a6b6ff4bea2 Mon Sep 17 00:00:00 2001 From: jrd Date: Sat, 5 Sep 2026 18:54:12 +0000 Subject: [PATCH] Add bounds check iChanID before array access Backport of #3810 to release/3_12 as a piecemeal patch: only the MathUtils::InRange template (half-open interval, as amended in #3812) and the CAudioMixerBoard::ApplyNewConClientList call site. No cherry-picks; the server chat refactor that carried InRange to main is not included. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017veM89EdPrzUbWbb44aKQs --- src/audiomixerboard.cpp | 9 ++++++--- src/util.h | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/audiomixerboard.cpp b/src/audiomixerboard.cpp index 20c823bf2f..08c45b2310 100644 --- a/src/audiomixerboard.cpp +++ b/src/audiomixerboard.cpp @@ -1349,9 +1349,12 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf for ( size_t iFader = 0; iFader < iNumConnectedClients; iFader++ ) { - // ideally "iChanID" in CChannelInfo would be size_t if it can never be INVALID_INDEX - // as assumed here - iFaderNumber[vecChanInfo[iFader].iChanID] = static_cast ( iFader ); + const int iChanID = vecChanInfo[iFader].iChanID; + + if ( MathUtils::InRange ( iChanID, 0, MAX_NUM_CHANNELS ) ) + { + iFaderNumber[iChanID] = static_cast ( iFader ); + } } // Hide all unused faders and initialize used ones diff --git a/src/util.h b/src/util.h index 441c7997ad..b86c409381 100644 --- a/src/util.h +++ b/src/util.h @@ -1223,6 +1223,13 @@ class MathUtils return powf ( 10.0f, ( fInValueRange0_1 - 1.0f ) * AUD_MIX_FADER_RANGE_DB / 20.0f ); } } + + // Returns true if value is in [lower, upper) (inclusive lower, exclusive upper). + template + static inline bool InRange ( T value, T lower /* inclusive */, T upper /* exclusive */ ) + { + return value >= lower && value < upper; + } }; /******************************************************************************\