You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This change fixes unsafe Player ID usage in classes ConnectionManager, DisconnectManager.
This problem surfaced as an actual remote client crash event when an invalid Player ID was send in a packet to a remote client. It then tried to use that value as an index to arrays (in function ConnectionManager::sendRemoteCommand).
This change now guards all relevant Player ID usages with an appropriate MAX_SLOTS bound check.
Additionally, NUM_CONNECTIONS was removed because it is a duplicate of MAX_SLOTS. And all playerID >= 0 tests were removed because Player ID is an unsigned integer.
xezon
added
Major
Severity: Minor < Major < Critical < Blocker
Network
Anything related to network, servers
Gen
Relates to Generals
ZH
Relates to Zero Hour
Security
Is security related
Fix
Is fixing something, but is not user facing
Stability
Concerns stability of the runtime
labels
Feb 14, 2026
This PR adds runtime bounds checking (playerID >= MAX_SLOTS) before using Player IDs from network packets as array indices in ConnectionManager and DisconnectManager. This fixes a real crash caused by invalid Player IDs in network packets leading to out-of-bounds array accesses. The PR also removes the redundant NUM_CONNECTIONS enum (which was identical to MAX_SLOTS), removes always-true playerID >= 0 checks on unsigned types, and uses const and consistent UnsignedInt types for local player ID variables.
Adds MAX_SLOTS bounds checks in 8+ functions that process network messages with player IDs (processNetCommand, processRunAheadMetrics, processChat, processDisconnectChat, processFileProgress, processFrameResendRequest, processDisconnectFrame, sendRemoteCommand)
Removes duplicate NUM_CONNECTIONS enum from NetworkDefs.h and replaces all its usages with MAX_SLOTS
isPlayerConnected only gets a debug assert, not a runtime guard — it could still be accessed out-of-bounds in release builds if called with an invalid ID
Confidence Score: 4/5
This PR is a targeted safety improvement that correctly guards most network-facing player ID usages; safe to merge with one minor concern about isPlayerConnected.
The changes consistently add bounds validation before using player IDs as array indices across ConnectionManager and DisconnectManager. The NUM_CONNECTIONS removal is verified correct (was equal to MAX_SLOTS). The only concern is that isPlayerConnected uses a debug-only assert rather than a runtime guard, though all callers from the changed code validate before calling it.
Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp — the isPlayerConnected function at line 303 uses a debug-only assert without a runtime bounds check.
Important Files Changed
Filename
Overview
Core/GameEngine/Include/GameNetwork/NetworkDefs.h
Removes duplicate NUM_CONNECTIONS enum value (was equal to MAX_SLOTS). Correct and safe change.
Adds MAX_SLOTS bounds checks for player IDs from network packets, replaces NUM_CONNECTIONS with MAX_SLOTS, removes redundant >= 0 checks on unsigned types. One concern: isPlayerConnected has only a debug assert, not a runtime guard against out-of-bounds access.
Adds MAX_SLOTS bounds check in processDisconnectFrame and removes redundant playerID < 0 check in processDisconnectScreenOff. Both changes are correct.
Flowchart
flowchart TD
A[Network Packet Received] --> B[processNetCommand]
B --> C{ACK Command?}
C -->|Yes| D[processAck / processAckStage1 / processAckStage2]
D --> D1{playerID < MAX_SLOTS?}
D1 -->|Yes| D2[Process ACK on connection]
D1 -->|No| D3[DEBUG_CRASH]
C -->|No| E{playerID >= MAX_SLOTS?}
E -->|Yes| F[Discard - Return TRUE]
E -->|No| G{Connection exists?}
G -->|No & not local| F
G -->|Yes| H{Command Type}
H -->|FRAMEINFO| I[processFrameInfo]
H -->|RUNAHEADMETRICS| J[processRunAheadMetrics]
H -->|CHAT| K[processChat]
H -->|DISCONNECT*| L[DisconnectManager]
H -->|FILEPROGRESS| M[processFileProgress]
H -->|Other| N[sendRemoteCommand]
I --> I1{playerID < MAX_SLOTS?}
I1 -->|Yes| I2[Update frame data]
I1 -->|No| I3[Skip]
J --> J1{playerID < MAX_SLOTS?}
J1 -->|Yes| J2[Update metrics]
J1 -->|No| J3[Return]
L --> L1[processDisconnectFrame]
L1 --> L2{playerID >= MAX_SLOTS?}
L2 -->|Yes| L3[Return]
L2 -->|No| L4[Process disconnect]
N --> N1{playerID < MAX_SLOTS?}
N1 -->|Yes| N2[Use frameData manager]
N1 -->|No| N3[Set frameDataMgr = nullptr]
Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp isPlayerConnected() lacks bounds check before using playerID as array index in m_connections[playerID]
This is a comment left during a code review.
Path: Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp
Line: 303:306
Comment:
`isPlayerConnected()` lacks bounds check before using `playerID` as array index in `m_connections[playerID]````suggestionBool ConnectionManager::isPlayerConnected( Int playerID ){ return ( playerID == m_localSlot || ((playerID >= 0 && playerID < MAX_SLOTS) && m_connections[playerID] && !m_connections[playerID]->isQuitting()) );}```
How can I resolve this? If you propose a fix, please make it concise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FixIs fixing something, but is not user facingGenRelates to GeneralsMajorSeverity: Minor < Major < Critical < BlockerNetworkAnything related to network, serversSecurityIs security relatedStabilityConcerns stability of the runtimeZHRelates to Zero Hour
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change fixes unsafe Player ID usage in classes
ConnectionManager,DisconnectManager.This problem surfaced as an actual remote client crash event when an invalid Player ID was send in a packet to a remote client. It then tried to use that value as an index to arrays (in function
ConnectionManager::sendRemoteCommand).This change now guards all relevant Player ID usages with an appropriate
MAX_SLOTSbound check.Additionally,
NUM_CONNECTIONSwas removed because it is a duplicate ofMAX_SLOTS. And allplayerID >= 0tests were removed because Player ID is an unsigned integer.