78 lines
2.2 KiB
Diff
78 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000001010
|
|
--- a/engine/server/sv_custom.c
|
|
+++ b/engine/server/sv_custom.c
|
|
@@ -61,6 +61,36 @@ static void SV_CreateCustomizationList( sv_client_t *cl )
|
|
}
|
|
}
|
|
|
|
+// CWE-407: SV_FileInConsistencyList performs O(C) linear scan per call.
|
|
+// SV_TransferConsistencyInfo calls it for each of sv.num_resources (up to
|
|
+// MAX_RESOURCES=8192), producing O(R*C) string comparisons per map load.
|
|
+// FIX: Pre-build a hash set of consistency filenames so each lookup is O(1).
|
|
+
|
|
+#define CONSISTENCY_HASH_SIZE 256
|
|
+
|
|
+typedef struct consistency_hash_entry_s
|
|
+{
|
|
+ consistency_t *pc;
|
|
+ struct consistency_hash_entry_s *next;
|
|
+} consistency_hash_entry_t;
|
|
+
|
|
+static consistency_hash_entry_t *consistency_hash[CONSISTENCY_HASH_SIZE];
|
|
+static consistency_hash_entry_t consistency_hash_pool[MAX_MODELS];
|
|
+static int consistency_hash_pool_used;
|
|
+
|
|
+static void SV_BuildConsistencyHash( void )
|
|
+{
|
|
+ int i;
|
|
+ memset( consistency_hash, 0, sizeof( consistency_hash ));
|
|
+ consistency_hash_pool_used = 0;
|
|
+
|
|
+ for( i = 0; i < MAX_MODELS && sv.consistency_list[i].filename; i++ )
|
|
+ {
|
|
+ uint h = COM_HashKey( sv.consistency_list[i].filename, CONSISTENCY_HASH_SIZE );
|
|
+ consistency_hash_entry_t *e = &consistency_hash_pool[consistency_hash_pool_used++];
|
|
+ e->pc = &sv.consistency_list[i];
|
|
+ e->next = consistency_hash[h];
|
|
+ consistency_hash[h] = e;
|
|
+ }
|
|
+}
|
|
+
|
|
static qboolean SV_FileInConsistencyList( const char *filename, consistency_t **ppout )
|
|
{
|
|
- int i;
|
|
+ consistency_hash_entry_t *e;
|
|
+ uint h;
|
|
|
|
if( ppout != NULL )
|
|
*ppout = NULL;
|
|
|
|
- for( i = 0; i < MAX_MODELS; i++ )
|
|
+ h = COM_HashKey( filename, CONSISTENCY_HASH_SIZE );
|
|
+
|
|
+ for( e = consistency_hash[h]; e != NULL; e = e->next )
|
|
{
|
|
- consistency_t *pc = &sv.consistency_list[i];
|
|
-
|
|
- if( !pc->filename )
|
|
- break;
|
|
-
|
|
- if( !Q_stricmp( pc->filename, filename ))
|
|
+ if( !Q_stricmp( e->pc->filename, filename ))
|
|
{
|
|
if( ppout != NULL )
|
|
- *ppout = pc;
|
|
+ *ppout = e->pc;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -196,6 +226,9 @@ void SV_TransferConsistencyInfo( void )
|
|
resource_t *pResource;
|
|
string filepath;
|
|
consistency_t *pc;
|
|
+
|
|
+ // Build hash table once, then O(1) lookups below
|
|
+ SV_BuildConsistencyHash();
|
|
|
|
for( i = 0; i < sv.num_resources; i++ )
|
|
{
|