fix(data): Sanitize GlobalData values after reading INI data#2519
fix(data): Sanitize GlobalData values after reading INI data#2519Cellcote wants to merge 1 commit intoTheSuperHackers:mainfrom
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/Common/GlobalData.cpp | Adds complete sanitization block after INI parsing; all three network history lengths (FPS, latency, cushion) are guarded to ≥1, and road/track fields are clamped with named constants and a static_assert. |
| GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp | Mirror of the Generals sanitization block; includes the m_networkCushionHistoryLength fix that was flagged in prior review threads. |
| Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h | Replaces local #define MAX_TRACK_EDGE_COUNT (100) with the shared constexpr MAX_TANK_TRACK_EDGES from GlobalData.h; array declaration is unchanged in size. |
| Generals/Code/GameEngine/Include/Common/GlobalData.h | Adds MAX_TANK_TRACK_EDGES = 100 and ROAD_BUFFER_PADDING = 4 as constexpr constants alongside MAX_GLOBAL_LIGHTS. |
| GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h | Identical constant additions to the GeneralsMD header; consistent with the Generals variant. |
| Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp | Replaces magic number 4 with ROAD_BUFFER_PADDING in DX8 vertex/index buffer allocations; no logic change. |
| GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp | Same ROAD_BUFFER_PADDING substitution as the Generals counterpart; consistent. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp | Cosmetic blank-line reorder only; no functional change. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[INI File Loaded] --> B[initFromINI fills GlobalData fields]
B --> C{parseGameDataDefinition sanitization}
C --> D["m_numGlobalLights → clamp(0, MAX_GLOBAL_LIGHTS)"]
C --> E["m_maxRoadVertex/Index → clamp(0, 65531)"]
C --> F["m_maxTankTrackEdges → clamp(1, MAX_TANK_TRACK_EDGES=100)"]
C --> G["allocation-size fields → max(value, 0)"]
C --> H["network history lengths → max(value, 1)"]
D --> I[W3DTerrainTracks\nm_edges MAX_TANK_TRACK_EDGES array\nsafe index access]
E --> J[W3DRoadBuffer\nDX8 16-bit index buffers\nsafe allocation]
F --> I
H --> K[FrameMetrics\nmodulo / division\nno divide-by-zero]
Greploops — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.
Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.
Reviews (4): Last reviewed commit: "fix(data): Sanitize GlobalData values af..." | Re-trigger Greptile
93b4a9c to
2729baa
Compare
| TheWritableGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects = std::max(TheWritableGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects, 0); | ||
| TheWritableGlobalData->m_maxLineBuildObjects = std::max(TheWritableGlobalData->m_maxLineBuildObjects, 0); | ||
| TheWritableGlobalData->m_maxRoadSegments = std::max(TheWritableGlobalData->m_maxRoadSegments, 0); | ||
| // Capped to 65531 because DX8 vertex/index buffers use 16-bit indices and allocate size + 4. |
There was a problem hiding this comment.
Had to create a constant for the padding but added.
| TheWritableGlobalData->m_maxRoadVertex = std::clamp(TheWritableGlobalData->m_maxRoadVertex, 0, 65531); | ||
| TheWritableGlobalData->m_maxRoadIndex = std::clamp(TheWritableGlobalData->m_maxRoadIndex, 0, 65531); | ||
| TheWritableGlobalData->m_maxRoadTypes = std::max(TheWritableGlobalData->m_maxRoadTypes, 0); | ||
| // Capped to 100 (MAX_TRACK_EDGE_COUNT) because TerrainTracksRenderObjClass has a fixed-size m_edges array. |
Clamp m_numGlobalLights to [0, MAX_GLOBAL_LIGHTS] and floor allocation-size fields to prevent out-of-bounds array access and undefined behavior from bad INI values. Cap m_maxRoadVertex and m_maxRoadIndex to 16-bit DX8 buffer limit minus ROAD_BUFFER_PADDING, and m_maxTankTrackEdges to MAX_TANK_TRACK_EDGES. Move MAX_TRACK_EDGE_COUNT to GlobalData.h as MAX_TANK_TRACK_EDGES and replace magic +4 in W3DRoadBuffer with ROAD_BUFFER_PADDING constant.
2729baa to
a401e81
Compare
xezon
left a comment
There was a problem hiding this comment.
It is a bit odd that GlobalData needs to be aware about limits of implementations. Maybe the clamping should be done where these globals are used? Not sure.
| #include "Lib/BaseType.h" | ||
|
|
||
| #define MAX_TRACK_EDGE_COUNT 100 //maximum number of edges or divisions in track mark | ||
| #include "Common/GlobalData.h" |
There was a problem hiding this comment.
Tough to include GlobalData.h for just one define.
| TheWritableGlobalData->m_maxLineBuildObjects = std::max(TheWritableGlobalData->m_maxLineBuildObjects, 0); | ||
| TheWritableGlobalData->m_maxRoadSegments = std::max(TheWritableGlobalData->m_maxRoadSegments, 0); | ||
| // Capped because DX8 vertex/index buffers use 16-bit indices and allocate size + ROAD_BUFFER_PADDING. | ||
| static constexpr Int MAX_ROAD_BUFFER_SIZE = 65535 - ROAD_BUFFER_PADDING; |
There was a problem hiding this comment.
constexpr const, because of VC6. No static.
| TheWritableGlobalData->m_maxRoadSegments = std::max(TheWritableGlobalData->m_maxRoadSegments, 0); | ||
| // Capped because DX8 vertex/index buffers use 16-bit indices and allocate size + ROAD_BUFFER_PADDING. | ||
| static constexpr Int MAX_ROAD_BUFFER_SIZE = 65535 - ROAD_BUFFER_PADDING; | ||
| static_assert(MAX_ROAD_BUFFER_SIZE > 0, "ROAD_BUFFER_PADDING must be less than 65535"); |
There was a problem hiding this comment.
The assert condition does not match the message.
| TheWritableGlobalData->m_maxRoadVertex = std::clamp(TheWritableGlobalData->m_maxRoadVertex, 0, MAX_ROAD_BUFFER_SIZE); | ||
| TheWritableGlobalData->m_maxRoadIndex = std::clamp(TheWritableGlobalData->m_maxRoadIndex, 0, MAX_ROAD_BUFFER_SIZE); | ||
| TheWritableGlobalData->m_maxRoadTypes = std::max(TheWritableGlobalData->m_maxRoadTypes, 0); | ||
| // Capped because TerrainTracksRenderObjClass has a fixed-size m_edges[MAX_TANK_TRACK_EDGES] array. |
There was a problem hiding this comment.
Better write m_edges[MAX_TANK_TRACK_EDGES] a different way, to not establish named code references in comments.
| #include "WW3D2/dx8wrapper.h" | ||
| #include "WW3D2/scene.h" | ||
| #include "GameLogic/TerrainLogic.h" | ||
|
|
Summary
m_numGlobalLightsto[0, MAX_GLOBAL_LIGHTS]to prevent out-of-bounds access on fixed-size terrain lighting arraysm_maxRoadSegments,m_maxVisibleTranslucentObjects, etc.) to 0 to prevent undefined behavior from negative INI valuesm_maxTankTrackEdgesand network history lengths to 1 since they are used in subtraction and modulo arithmeticCloses #2517