From 4d6bdcc8530b1da3221e51a631e3e428faa88978 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sat, 8 Oct 2022 16:33:41 +0200 Subject: [PATCH] If CM_LeafCluster() returned -1, don't use that as array index, fix #894 It seems to return -1 if the leaf is in the void; sometimes it also seems to happen when you're just close to a wall, maybe due to (mis)prediction. ASan complains about this, but in practice it probably can't cause issues, as the byte left to the mask array (from CM_ClusterPVS() or CM_ClusterPHS()) will either belong to another global variable or padding between them. Fixed it anyway. --- src/server/sv_game.c | 10 ++++++++-- src/server/sv_send.c | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/server/sv_game.c b/src/server/sv_game.c index 973d56f3..702f4ec5 100644 --- a/src/server/sv_game.c +++ b/src/server/sv_game.c @@ -293,7 +293,10 @@ PF_inPVS(vec3_t p1, vec3_t p2) cluster = CM_LeafCluster(leafnum); area2 = CM_LeafArea(leafnum); - if (mask && (!(mask[cluster >> 3] & (1 << (cluster & 7))))) + // cluster -1 means "not in a visible leaf" or something like that (void?) + // so p1 and p2 probably don't "see" each other. + // either way, we must avoid using a negative index into mask[]! + if (cluster < 0 || (!(mask[cluster >> 3] & (1 << (cluster & 7))))) { return false; } @@ -326,7 +329,10 @@ PF_inPHS(vec3_t p1, vec3_t p2) cluster = CM_LeafCluster(leafnum); area2 = CM_LeafArea(leafnum); - if (mask && (!(mask[cluster >> 3] & (1 << (cluster & 7))))) + // cluster -1 means "not in a visible leaf" or something like that (void?) + // so p1 and p2 probably don't "hear" each other. + // either way, we must avoid using a negative index into mask[]! + if (cluster < 0 || (!(mask[cluster >> 3] & (1 << (cluster & 7))))) { return false; /* more than one bounce away */ } diff --git a/src/server/sv_send.c b/src/server/sv_send.c index da375077..8b934dd0 100644 --- a/src/server/sv_send.c +++ b/src/server/sv_send.c @@ -227,7 +227,9 @@ SV_Multicast(vec3_t origin, multicast_t to) continue; } - if (!(mask[cluster >> 3] & (1 << (cluster & 7)))) + // cluster can be -1 if we're in the void (or sometime just at a wall) + // and using a negative index into mask[] would be invalid + if (cluster < 0 || !(mask[cluster >> 3] & (1 << (cluster & 7)))) { continue; }