Skip to content

Commit a83a55a

Browse files
committed
Multiple fixes: safety casts, formatting, and OpenAL
Apply a collection of safety, correctness and build fixes across the codebase. Key changes include: add explicit bounds checks and static_casts to avoid signed/unsigned and overflow issues (botlib, client, audio, json, etc.); replace unsafe sprintf usage with Com_sprintf for bounded formatting; refactor the VM DROP macro into a VM_Drop helper for safer variadic error reporting; add pkg-config fallback for OpenAL in CI and include OpenAL compatibility defines; enable conditional depth-fade handling in Vulkan fragment shader template; minor API cleanups in the OpenAL audio world/backend and small binary updates to SPIR-V shader data. Also include a few behavioral fixes (input run flag comparison, snapshot/areamask size checks, makefile command markers). These changes improve robustness and cross-platform build reliability.
1 parent fe1ad1d commit a83a55a

41 files changed

Lines changed: 4761 additions & 6352 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,11 @@ jobs:
306306
run: |
307307
BREW_PREFIX="$(brew --prefix)"
308308
export PKG_CONFIG_PATH="${BREW_PREFIX}/lib/pkgconfig:${BREW_PREFIX}/share/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
309-
OPENAL_CFLAGS="$(pkg-config --cflags openal)" \
309+
OPENAL_CFLAGS="$(pkg-config --cflags openal || true)"
310+
if [ -z "${OPENAL_CFLAGS}" ]; then
311+
OPENAL_CFLAGS="-I$(brew --prefix openal-soft)/include"
312+
fi
313+
OPENAL_CFLAGS="${OPENAL_CFLAGS}" \
310314
SDL_INCLUDE="$(pkg-config --cflags-only-I sdl3)" \
311315
SDL_LIBS="$(pkg-config --libs sdl3)" \
312316
JPEG_CFLAGS="$(pkg-config --cflags libjpeg)" \

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -860,10 +860,10 @@ default: release
860860
all: debug release
861861

862862
debug:
863-
@B="$(BD)" CFLAGS="$(CFLAGS) $(DEBUG_CFLAGS)" CXXFLAGS="$(CXXFLAGS) $(DEBUG_CXXFLAGS)" LDFLAGS="$(LDFLAGS) $(DEBUG_LDFLAGS)" $(RECURSIVE_MAKE) targets V=$(V)
863+
+@B="$(BD)" CFLAGS="$(CFLAGS) $(DEBUG_CFLAGS)" CXXFLAGS="$(CXXFLAGS) $(DEBUG_CXXFLAGS)" LDFLAGS="$(LDFLAGS) $(DEBUG_LDFLAGS)" $(RECURSIVE_MAKE) targets V=$(V)
864864

865865
release:
866-
@B="$(BR)" CFLAGS="$(CFLAGS) $(RELEASE_CFLAGS)" CXXFLAGS="$(CXXFLAGS) $(RELEASE_CXXFLAGS)" $(RECURSIVE_MAKE) targets V=$(V)
866+
+@B="$(BR)" CFLAGS="$(CFLAGS) $(RELEASE_CFLAGS)" CXXFLAGS="$(CXXFLAGS) $(RELEASE_CXXFLAGS)" $(RECURSIVE_MAKE) targets V=$(V)
867867

868868
define ADD_COPY_TARGET
869869
TARGETS += $2
@@ -923,7 +923,7 @@ endif
923923
done
924924
@echo ""
925925
ifneq ($(TARGETS),)
926-
@$(RECURSIVE_MAKE) $(TARGETS) V=$(V)
926+
+@$(RECURSIVE_MAKE) $(TARGETS) V=$(V)
927927
endif
928928

929929
makedirs:

code/botlib/be_ai_chat.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,7 +2386,7 @@ static int BotExpandChatMessage(char *outmessage, int size, const char *message,
23862386
if ( *msgptr != '\0' )
23872387
msgptr++;
23882388

2389-
if ( num >= ARRAY_LEN( match->variables ) )
2389+
if ( num < 0 || num >= static_cast<int>( ARRAY_LEN( match->variables ) ) )
23902390
{
23912391
botimport.Print( PRT_ERROR, "%s(): message \"%s\" variable %d out of range\n", __func__, message, num );
23922392
return qfalse;
@@ -2412,7 +2412,7 @@ static int BotExpandChatMessage(char *outmessage, int size, const char *message,
24122412
BotReplaceSynonyms( temp, sizeof( temp ), vcontext );
24132413
}
24142414

2415-
if ( len + strlen( temp ) >= size )
2415+
if ( size <= 0 || static_cast<size_t>( len ) + strlen( temp ) >= static_cast<size_t>( size ) )
24162416
{
24172417
botimport.Print( PRT_ERROR, "%s(): message \"%s\" too long\n", __func__, message );
24182418
return qfalse;
@@ -2443,7 +2443,7 @@ static int BotExpandChatMessage(char *outmessage, int size, const char *message,
24432443
return qfalse;
24442444
}
24452445

2446-
if ( len + strlen(ptr) >= size )
2446+
if ( size <= 0 || static_cast<size_t>( len ) + strlen( ptr ) >= static_cast<size_t>( size ) )
24472447
{
24482448
botimport.Print( PRT_ERROR, "%s(): message \"%s\" too long\n", __func__, message );
24492449
return qfalse;
@@ -2626,7 +2626,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26262626
if ( var0 ) {
26272627
len = (int)strlen( var0 );
26282628
match.variables[0].offset = index;
2629-
if ( len + index < sizeof( match.string ) ) {
2629+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26302630
match.variables[0].length = len;
26312631
strcat( match.string, var0 );
26322632
index += strlen( var0 );
@@ -2635,7 +2635,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26352635
if ( var1 ) {
26362636
len = (int) strlen( var1 );
26372637
match.variables[1].offset = index;
2638-
if ( len + index < sizeof( match.string ) ) {
2638+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26392639
match.variables[1].length = len;
26402640
strcat( match.string, var1 );
26412641
index += len;
@@ -2644,7 +2644,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26442644
if ( var2 ) {
26452645
len = (int) strlen( var2 );
26462646
match.variables[2].offset = index;
2647-
if ( len + index < sizeof( match.string ) ) {
2647+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26482648
match.variables[2].length = len;
26492649
strcat( match.string, var2 );
26502650
index += len;
@@ -2653,7 +2653,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26532653
if ( var3 ) {
26542654
len = (int) strlen( var3 );
26552655
match.variables[3].offset = index;
2656-
if ( len + index < sizeof( match.string ) ) {
2656+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26572657
match.variables[3].length = len;
26582658
strcat( match.string, var3 );
26592659
index += len;
@@ -2662,7 +2662,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26622662
if ( var4 ) {
26632663
len = (int) strlen( var4 );
26642664
match.variables[4].offset = index;
2665-
if ( len + index < sizeof( match.string ) ) {
2665+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26662666
match.variables[4].length = len;
26672667
strcat( match.string, var4 );
26682668
index += len;
@@ -2671,7 +2671,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26712671
if ( var5 ) {
26722672
len = (int) strlen( var5 );
26732673
match.variables[5].offset = index;
2674-
if ( len + index < sizeof( match.string ) ) {
2674+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26752675
match.variables[5].length = len;
26762676
strcat( match.string, var5 );
26772677
index += len;
@@ -2680,7 +2680,7 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26802680
if ( var6 ) {
26812681
len = (int) strlen( var6 );
26822682
match.variables[6].offset = index;
2683-
if ( len + index < sizeof( match.string ) ) {
2683+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
26842684
match.variables[6].length = len;
26852685
strcat( match.string, var6 );
26862686
index += len;
@@ -2689,8 +2689,8 @@ void BotInitialChat(int chatstate, const char *type, int mcontext, const char *v
26892689
if ( var7 ) {
26902690
len = (int) strlen( var7 );
26912691
match.variables[7].offset = index;
2692-
if ( len + index < sizeof( match.string ) ) {
2693-
match.variables[7].length = strlen(var7);
2692+
if ( len + index < static_cast<int>( sizeof( match.string ) ) ) {
2693+
match.variables[7].length = len;
26942694
strcat( match.string, var7 );
26952695
//index += len;
26962696
}
@@ -2836,7 +2836,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28362836
if ( var0 ) {
28372837
len = (int) strlen( var0 );
28382838
bestmatch.variables[0].offset = index;
2839-
if ( len + index < sizeof( bestmatch.string ) ) {
2839+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28402840
bestmatch.variables[0].length = len;
28412841
strcat( bestmatch.string, var0 );
28422842
index += len;
@@ -2845,7 +2845,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28452845
if ( var1 ) {
28462846
len = (int) strlen( var1 );
28472847
bestmatch.variables[1].offset = index;
2848-
if ( len + index < sizeof( bestmatch.string ) ) {
2848+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28492849
bestmatch.variables[1].length = len;
28502850
strcat( bestmatch.string, var1 );
28512851
index += len;
@@ -2854,7 +2854,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28542854
if ( var2 ) {
28552855
len = (int) strlen( var2 );
28562856
bestmatch.variables[2].offset = index;
2857-
if ( len + index < sizeof( bestmatch.string ) ) {
2857+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28582858
bestmatch.variables[2].length = len;
28592859
strcat( bestmatch.string, var2 );
28602860
index += len;
@@ -2863,7 +2863,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28632863
if ( var3 ) {
28642864
len = (int) strlen( var3 );
28652865
bestmatch.variables[3].offset = index;
2866-
if ( len + index < sizeof( bestmatch.string ) ) {
2866+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28672867
bestmatch.variables[3].length = len;
28682868
strcat( bestmatch.string, var3 );
28692869
index += len;
@@ -2872,7 +2872,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28722872
if ( var4 ) {
28732873
len = (int) strlen( var4 );
28742874
bestmatch.variables[4].offset = index;
2875-
if ( len + index < sizeof( bestmatch.string ) ) {
2875+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28762876
bestmatch.variables[4].length = len;
28772877
strcat( bestmatch.string, var4 );
28782878
index += len;
@@ -2881,7 +2881,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28812881
if ( var5 ) {
28822882
len = (int) strlen( var5 );
28832883
bestmatch.variables[5].offset = index;
2884-
if ( len + index < sizeof( bestmatch.string ) ) {
2884+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28852885
bestmatch.variables[5].length = len;
28862886
strcat( bestmatch.string, var5 );
28872887
index += len;
@@ -2890,7 +2890,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28902890
if ( var6 ) {
28912891
len = (int) strlen( var6 );
28922892
bestmatch.variables[6].offset = index;
2893-
if ( len + index < sizeof( bestmatch.string ) ) {
2893+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
28942894
bestmatch.variables[6].length = len;
28952895
strcat( bestmatch.string, var6 );
28962896
index += len;
@@ -2899,7 +2899,7 @@ int BotReplyChat(int chatstate, const char *message, int mcontext, int vcontext,
28992899
if ( var7 ) {
29002900
len = (int) strlen( var7 );
29012901
bestmatch.variables[7].offset = index;
2902-
if ( len + index < sizeof( bestmatch.string ) ) {
2902+
if ( len + index < static_cast<int>( sizeof( bestmatch.string ) ) ) {
29032903
bestmatch.variables[7].length = len;
29042904
strcat( bestmatch.string, var7 );
29052905
//index += len;

code/botlib/be_interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ int Sys_MilliSeconds(void)
8686
//===========================================================================
8787
static qboolean ValidEntityNumber(int num, const char *str)
8888
{
89-
if ( /*num < 0 || */ (unsigned)num > botlibglobals.maxentities )
89+
if ( num < 0 || num > botlibglobals.maxentities )
9090
{
9191
botimport.Print(PRT_ERROR, "%s: invalid entity number %d, [0, %d]\n",
9292
str, num, botlibglobals.maxentities);

code/botlib/l_precomp.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ static int PC_StringizeTokens( const token_t *tokens, token_t *token )
470470
for (t = tokens; t; t = t->next)
471471
{
472472
len = (int)strlen( t->string );
473-
if ( len + total >= sizeof( token->string ) - 1 ) // reserve space for '"' and '\0'
473+
if ( len + total >= static_cast<int>( sizeof( token->string ) ) - 1 ) // reserve space for '"' and '\0'
474474
return qfalse;
475475
strcpy( token->string + total, t->string );
476476
total += len;
@@ -730,7 +730,7 @@ static int PC_ExpandBuiltinDefine(source_t *source, token_t *deftoken, define_t
730730
{
731731
case BUILTIN_LINE:
732732
{
733-
sprintf(token->string, "%d", deftoken->line);
733+
Com_sprintf(token->string, sizeof(token->string), "%d", deftoken->line);
734734
#ifdef NUMBERVALUE
735735
token->intvalue = deftoken->line;
736736
token->floatvalue = deftoken->line;
@@ -2459,7 +2459,7 @@ static int PC_Directive_eval(source_t *source)
24592459
token.whitespace_p = source->scriptstack->script_p;
24602460
token.endwhitespace_p = source->scriptstack->script_p;
24612461
token.linescrossed = 0;
2462-
sprintf(token.string, "%d", abs(value));
2462+
Com_sprintf(token.string, sizeof(token.string), "%d", abs(value));
24632463
token.type = TT_NUMBER;
24642464
token.subtype = TT_INTEGER|TT_LONG|TT_DECIMAL;
24652465
PC_UnreadSourceToken(source, &token);
@@ -2482,7 +2482,7 @@ static int PC_Directive_evalfloat(source_t *source)
24822482
token.whitespace_p = source->scriptstack->script_p;
24832483
token.endwhitespace_p = source->scriptstack->script_p;
24842484
token.linescrossed = 0;
2485-
sprintf(token.string, "%1.2f", fabs(value));
2485+
Com_sprintf(token.string, sizeof(token.string), "%1.2f", fabs(value));
24862486
token.type = TT_NUMBER;
24872487
token.subtype = TT_FLOAT|TT_LONG|TT_DECIMAL;
24882488
PC_UnreadSourceToken(source, &token);
@@ -2564,7 +2564,7 @@ static int PC_DollarDirective_evalint(source_t *source)
25642564
token.whitespace_p = source->scriptstack->script_p;
25652565
token.endwhitespace_p = source->scriptstack->script_p;
25662566
token.linescrossed = 0;
2567-
sprintf(token.string, "%d", abs(value));
2567+
Com_sprintf(token.string, sizeof(token.string), "%d", abs(value));
25682568
token.type = TT_NUMBER;
25692569
token.subtype = TT_INTEGER|TT_LONG|TT_DECIMAL;
25702570

@@ -2595,7 +2595,7 @@ static int PC_DollarDirective_evalfloat(source_t *source)
25952595
token.whitespace_p = source->scriptstack->script_p;
25962596
token.endwhitespace_p = source->scriptstack->script_p;
25972597
token.linescrossed = 0;
2598-
sprintf(token.string, "%1.2f", fabs(value));
2598+
Com_sprintf(token.string, sizeof(token.string), "%1.2f", fabs(value));
25992599
token.type = TT_NUMBER;
26002600
token.subtype = TT_FLOAT|TT_LONG|TT_DECIMAL;
26012601

code/client/audio/legacy/snd_dma.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ static void S_Update_( int msec ) {
12801280
& ~(dma.submission_chunk-1);
12811281

12821282
// never mix more than the complete buffer
1283-
if ( endtime - s_paintedtime > dma.fullsamples ) {
1283+
if ( endtime - s_paintedtime > static_cast<unsigned>( dma.fullsamples ) ) {
12841284
endtime = s_paintedtime + dma.fullsamples;
12851285
}
12861286

code/client/audio/legacy/snd_mix.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,12 @@ static void S_TransferPaintBuffer( int endtime, byte *buffer )
406406
count = (clc.aviFrameEndTime - s_paintedtime) * dma.channels;
407407
out_idx = ( s_paintedtime * dma.channels ) % dma.samples;
408408
while ( count > 0 ) {
409+
const int dmaSamples = static_cast<int>( dma.samples );
409410
int n = count;
410-
if ( n + out_idx > dma.samples )
411-
n = dma.samples - out_idx;
411+
if ( n + out_idx > dmaSamples )
412+
n = dmaSamples - out_idx;
412413
CL_WriteAVIAudioFrame( buffer + out_idx * dma.samplebits / 8, n * dma.samplebits / 8 );
413-
out_idx = (out_idx + n) % dma.samples;
414+
out_idx = (out_idx + n) % dmaSamples;
414415
count -= n;
415416
}
416417
}

code/client/audio/openal/AudioSystemBackend.inl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ private:
4242
bool UpdateDeviceState( int msec );
4343
void CloseBackgroundStream();
4444
SoundSample *GetSample( sfxHandle_t handle );
45-
const SoundSample *GetSample( sfxHandle_t handle ) const;
4645
qboolean IsSoftMuted() const;
4746

4847
OpenALDevice device_;
@@ -390,13 +389,6 @@ SoundSample *AudioSystem::GetSample( sfxHandle_t handle ) {
390389
return &samples_[static_cast<size_t>( handle )];
391390
}
392391

393-
const SoundSample *AudioSystem::GetSample( sfxHandle_t handle ) const {
394-
if ( handle < 0 || handle >= static_cast<sfxHandle_t>( samples_.size() ) ) {
395-
return nullptr;
396-
}
397-
return &samples_[static_cast<size_t>( handle )];
398-
}
399-
400392
void AudioSystem::BeginRegistration() {
401393
hardMuted_ = false;
402394

code/client/audio/openal/AudioSystemWorld.inl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,6 @@ public:
666666
void StopLoopingSound( int entityNum );
667667
void AddLoopingSound( int entityNum, const float *origin, const float *velocity, sfxHandle_t handle, SoundSample *sample, qboolean realLoop );
668668
void StartSound( int entityNum, int entchannel, sfxHandle_t handle, SoundSample *sample, const float *origin );
669-
void StartLocalSound( sfxHandle_t handle, SoundSample *sample, int channelNum );
670669
void UpdateEntityPosition( int entityNum, const float *origin );
671670
void Respatialize( int entityNum, const float *origin, float axis[3][3] );
672671
void Update( qboolean softMuted );
@@ -952,10 +951,6 @@ void Q3SoundWorld::StartSound( int entityNum, int entchannel, sfxHandle_t handle
952951
device_->AL().alSourcePlay( voice->source );
953952
}
954953

955-
void Q3SoundWorld::StartLocalSound( sfxHandle_t handle, SoundSample *sample, int channelNum ) {
956-
StartSound( listenerNumber_, channelNum, handle, sample, nullptr );
957-
}
958-
959954
void Q3SoundWorld::UpdateEntityPosition( int entityNum, const float *origin ) {
960955
if ( entityNum < 0 || entityNum >= MAX_GENTITIES ) {
961956
Com_Error( ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum );

code/client/audio/openal/OpenALCompat.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ typedef void ( AL_APIENTRY *LPALEVENTCALLBACKSOFT )( ALEVENTPROCSOFT callback, v
4949
typedef ALCboolean ( ALC_APIENTRY *LPALCREOPENDEVICESOFT )( ALCdevice *device, const ALCchar *deviceName, const ALCint *attribs );
5050
#endif
5151

52+
#ifndef AL_SOFT_direct_channels
53+
#define AL_SOFT_direct_channels
54+
#define AL_DIRECT_CHANNELS_SOFT 0x1033
55+
#endif
56+
57+
#ifndef AL_SOFT_direct_channels_remix
58+
#define AL_SOFT_direct_channels_remix
59+
#define AL_REMIX_UNMATCHED_SOFT 0x0002
60+
#endif
61+
5262
#ifndef AL_SOFT_UHJ
5363
#define AL_SOFT_UHJ
5464
#define AL_FORMAT_UHJ2CHN8_SOFT 0x19A2

0 commit comments

Comments
 (0)